いきなりですが問題です.以下の2次元配置の中で,「■」の1箇所だけを「□」に変更し,全体がある規則に従うようにしてください.
□□■■□□ ■□□■■□ ■■■■■■ □□■■□□ ■□■■□■ ■■□■■□
さっそくですが解答の前に元ネタです.
- 作者: 細水保宏,ガウスの会
- 出版社/メーカー: 東洋館出版社
- 発売日: 2013/09/13
- メディア: 単行本
- この商品を含むブログ (1件) を見る
□□■■□□ ■□□■□□ ■■■■■■ □□■■□□ ■□■■□■ ■■□■■□
ですので解答は「上から2番目,右から2番目」です.実際,そこの■を□に置き換えることで,どの行もどの列も,■の数が偶数になります.
正解(原文)で,■の数を確認すると:
- 1行目は2個,1列目は4個*2
- 2行目は2個,2列目は2個
- 3行目は6個,3列目は4個
- 4行目は2個,4列目は6個
- 5行目は4個,5列目は2個
- 6行目は2個,6列目は2個
冒頭の問題だと:
- 1行目は2個,1列目は4個
- 2行目は3個(奇数!),2列目は2個
- 3行目は6個,3列目は4個
- 4行目は2個,4列目は6個
- 5行目は4個,5列目は3個(奇数!)
- 6行目は2個,6列目は2個
ということで,奇数になっている行と列がちょうど1箇所ずつあり,左上を基準としたとき「2行目・5列目」を変更すればよいとなります.
書籍では,配置の手順についても書かれています(pp.101-103).最終的に作るのは6×6の2次元配置ですが,このうち5×5の部分を「1人の子どもに適当に並べてもらう」ことにします.「その後,先生が11枚を並べる」のですが,この段階でどの列・どの行も,■が偶数になるようにしているのでした.
子どもが次のように並べたのなら:
□□■■□ ■□□■□ ■■■■■ □□■■□ ■□■■□
まずどの行も,■の数が偶数になるよう,右に追加して:
□□■■□□ ■□□■□□ ■■■■■■ □□■■□□ ■□■■□■
それから列ごとに,■の数が偶数になるよう,下に追加していけば,できあがりというわけです.
小学校の算数なので「偶数」「奇数」となりますが,これは情報通信の分野で「パリティ」と呼ばれているものです.例えば□を0,■を1に対応づけることにすれば,偶パリティです.
思うところあって出題を自動生成するRubyスクリプト"ppg.rb"を書きました.Gistに置いています.
出題としては,どの行・どの列も,すべて偶数または奇数となるよう,反転させるべき箇所を一つ見つけるというものにしました.
偶数か奇数かは,問題ごとにランダムです.また列数は6〜8行,行数は4〜6行としています.
引数なしで実行した場合,問題→Enterを押す→解答→Enterを押す→次の問題…と無限にループし,qとEnterを押せば終了します.引数をつけて実行した場合,その数(整数値)だけ,問題と解答を出力します.
スクリプトについて少しだけ書いておきますと,2次元の配置は,「配列の配列」で保持しています.行ごとのパリティ追加は,配列の「配列」ごとに和を計算*3して,帳尻が合うように0か1かを決めます.列ごとのパリティ追加をするため,Array#transposeを使っています.ruby -d ppg.rb 1を実行すると,ランダム配置,行ごとにパリティをつけた状態,列ごとパリティをつけた状態,と順に出力します.以下はその一例です.
$ ruby -d ppg.rb 1 #### step 1 #### ■□□□■ □■□□□ □□□■□ #### step 2 #### ■□□□■□ □■□□□■ □□□■□■ #### step 3 #### ■□□□■□ □■□□□■ □□□■□■ ■■□■■□ ■□□□■□ → ■□□□■□ → ■□□□■□ □■□□□■ → □■□□□■ → □■□□□■ □□□■□□ → □□□■□* → □□□■□■ ■■□■■□ → ■■□■■□ → ■■□■■□
(最終更新:2013-09-20 晩.ruby -d ppg.rb 1の実行例を追加しました.)
*1:算数の授業としては,「しきしき探偵団」(pp.64-67)が同じくらいに興味深い内容でした.
*2:左上を1行目・1列目としています.
*3:配列の各要素の和は,eachでもinjectでもなく,Enumerable#reduceを用いています.コマンド「ri inject」を実行した際のメッセージに出てくるほか,http://doc.okkez.net/static/2.0.0/class/Enumerable.html#I_INJECTにも式の例が書かれています.