- 橋本由美子: 塵劫記を算数・数学教育に取り入れる意義と教材化, 数学教育論文発表会論文集, No.40, pp.13-18 (2007). http://ci.nii.ac.jp/naid/110007173815
授業事例の中心にあるのは,「まま子立て」です.Webを調べると,いろいろ出てきました.
- wikipedia:ままこ立て
- wikipedia:ヨセフスの問題
- http://www.edita.jp/masanori432/one/masanori432318.html
- 昔の算数クイズ。継子立て(ままこだて)の大逆転ドラマはどこから始まるの? 町人思案橋・クイズ集/ウェブリブログ
「ヨセフスの問題」を読んで,雑記の中を検索…ありました.最後の一人クイズです.
冒頭の論文で,授業で提示した課題はというと:
問題 円形に並び、2人抜きで1、2・・と数え、2と唱えた人を抜かします。最後に残る人が勝ちです。何番が勝ちでしょう。ルール (1)自分は1にいます。自分から数えます。(2)1、2、1、2・・・で2と唱えた位置の人は抜けます。(3)最後まで残った人が勝ちです。
(p.17)
問題 自分が1の位置にいて、最後まで残るためには、回りの人数を何人にすればいいでしょうか。
(同)
まず過去のスクリプトで,数値だけ変えてみます。
$ ruby -e 'def f(num,step); a=(1..num).to_a; pos=0; z=; until a.empty?; pos=(pos-1+step)%a.size; z<
; until a.empty?; pos=(pos-1+step)%a.size; z<
3人の場合は,1の位置の人が「1」と言い,2の人が「2」と言うので抜けて,3の人が「1」と言い,1の人が「2」と言うので抜ける.なので最後まで残ったのは3の人,という次第です.
n人を縦に並べて出力していると,行数が多くなって,バックスクロールするのも手間です.これについては,ワンライナーの最後,「puts」を「p」に変えれば,すっきりします.
$ ruby -e 'def f(num,step); a=(1..num).to_a; pos=0; z=; until a.empty?; pos=(pos-1+step)%a.size; z<
; until a.empty?; pos=(pos-1+step)%a.size; z<
それと,「最後の一人だけ」を出力したければ,「puts f(なになに)」の直後に「.last」をつければ解決します.初期状態の人数を,1人から17人として,求めてみます.
$ ruby -e 'def f(num,step); a=(1..num).to_a; pos=0; z=[]; until a.empty?; pos=(pos-1+step)%a.size; z<
「最後の一人」に規則性があること,初期人数が人のとき,最後に残るのは番目すなわち円環の中で最後に数を言う人であること,そして,初期人数が人のとき,最後に残るのが1番目すなわち最初の最初に数を言う人であることが,分かります.
論文を離れ,「まま子立て」を確かめるワンライナーを作ることにします.設定は以下のとおり.
ある家に子どもが30人いて、15人は先妻の子(これを継子という)、もう15人は後妻の子です。この30人を輪になるように並べ、ある1人の子どもから時計回りに数え、10番目の子を除きます。続いて、その次の子どもからまた数えなおして10番目の子を除きます。このように10番目、10番目・・・と繰り返し除いていったときに最後に残る1人に家を継がせることにしたそうです。
http://www.edita.jp/masanori432/one/masanori432318.html
後妻は、次の図のように子どもを並べました。
(図省略)
丸1の子どもから数え始めて、繰り返し10番目ごとに子ども除いていくと、15人いた継子(先妻の子)のうち14人までもが連続して除かれてしまいます。そこで1人だけ残った継子(丸14)は、後妻に訴えます。
継子14「これでは、あまりにも一方的過ぎるから、今度は自分(丸)から数え始めてください。」
後妻「自分の子はまだ15人も残っているし、じゃあ、あなた(継子14)から数え始めましょうか。」
結果は、どうなったと思いますか?
1人だけ残った継子(丸14)から数え始めると、今度はどんどん後妻の子どもたちが除かれていってしまい、ついには15人いた後妻の子どもたちが全員除かれてしまうのです。結局、1人だけ残った継子が後継ぎになってしまいました。
継子14を「1の位置の人」とし,後妻サイドの残り15人を並べた16人でスタートするなら,抜ける人の順番は,次のようになります.
$ ruby -e 'def f(num,step); a=(1..num).to_a; pos=0; z=[]; until a.empty?; pos=(pos-1+step)%a.size; z<
最初の30人の配置も,取り入れることにします.
$ ruby -e 'num=30; step=10; a=%w(X1 X2 O3 X4 X5 X6 O7 O8 O9 O10 O11 X12 X13 O14 O15 X16 X17 X18 X19 O20 X21 O22 O23 O24 X25 O26 O27 X28 X29 O30); pos=0; z=[]; until a.empty?; pos=(pos-1+step)%a.size; z<
ポイントは,初期状態の配列を変更したのと,残り16人になったときに"O14"が先頭になるよう,ローテーション*1する処理を入れた点です.
出力は,こうなります.
["O14", "X16", "X17", "X18", "X19", "X21", "X25", "X28", "X29", "X1", "X2", "X4", "X5", "X6", "X12", "X13"]
["O10", "O20", "O30", "O11", "O22", "O3", "O15", "O27", "O9", "O24", "O7", "O23", "O8", "O26", "change", "X1", "X18", "X12", "X2", "X25", "X19", "X17", "X21", "X29", "X6", "X28", "X16", "X5", "X13", "X4", "O14"]
最初のリストは,継子1人と後妻の子15人の配置です.2番目のリストは,最初の30人から,O14が最後の1人になるまでの,取り除かれていく人の順番です.
配置の変化を知ることができるよう,もう少しだけ,スクリプトを変えてみましょう.出力は膨大になるので省略します.
$ ruby -e 'num=30; step=10; a=%w(X1 X2 O3 X4 X5 X6 O7 O8 O9 O10 O11 X12 X13 O14 O15 X16 X17 X18 X19 O20 X21 O22 O23 O24 X25 O26 O27 X28 X29 O30); pos=0; z=[]; until a.empty?; pos=(pos-1+step)%a.size; z<
冒頭の論文,「まま子立て」を教材化する前の「類型」もまた興味深いので,打ち出しておきます.授業のサンプルプログラムづくりや,当雑記でRubyを中心として何か書くときにも,たしかにそういう考え方ができるなあと思ったのでした.
教材化の類型は、数値の変更、文脈・場面の変更の2つの観点から、次の4つのタイプに分けられる。
タイプI型a 原題を生かし、数値もそのまま提示する【例】ねずみ算,入り子算
タイプI型b a型で行った後、原題の図形を変えたりして発展させる。【例】薬師算、俵杉算
タイプII型 数値はそのまま、文脈を現代風に変える【例】絹盗人算
タイプIII型a 原題を生かすが、きまりを見つけやすいように特殊の場合の数値に置き換える。【例】百五減算
タイプIIIb タイプI型bと似ているが数値をいろいろ変えて、発展させる【例】油分け算、薬師算
タイプIV型 原題の構造はそのまま生かし、数値を易しくし、場面を現代風に変える。授業後、原題に立ち戻って、紹介する。【例】まま子立て
(p.16)
(最終更新日時:Thu Jan 26 05:41:09 2012ごろ)
*1:Ruby 1.9ならArray#rotateが使えるのですが,1.8にはないメソッドのため,採用しませんでした.