児童100人がキャンプに行った.夕食の時間になったが,食事をする場所が狭く100人が一緒に食事できない.そこで,この100人を1列に並べ,先頭から数えて10人目ごとに児童を選び,食事をさせることにした.最後まで食事にありつけない児童は元の列の何番目にいた人だろうか.ただし,列は並び替えず,いなくなった人の分は前に詰めることとする.
(頭の体操 四谷大塚ベストセレクション (カッパブックス), p.127)
あ,これは最後の一人クイズですね.大学院生のときの輪講で(英文で)見かけました.輪を作って何人かおきに撃ち殺し,最後に残るのは何番でしょうってやつ.
※「閲覧注意」のフレーズは,背景と同じ色にしました.
答えは…
最初に並んだときに1番目から9番目にいた人たちが最後まで食事にありつけない
(p.128)
しまった,「先頭から数えて」は毎回適用するんですか.
輪を作るほうの問題は,答えのページの下半分に「チャレンジ」として書かれていました.
■150人が円のように並んだ場合,(略)1人おきに食事をしていくと最後に残る1人は何番目の人だろうか.
(p.128)
答えは暗算では出せませんので,巻末の解答を頼ると…『45番目』(p.200)とのこと.
さてこれを答えるワンライナーを作りますか.
ruby -e 'def f(num,step); a=(1..num).to_a; pos=0; z=[]; until a.empty?; pos=(pos-1+step)%a.size; z<<a.delete_at(pos); end; z; end; puts f(150,2)'
出力の最初は偶数ばかり.150までいったところで,輪の残りは1, 3, 5, 7, ...と並びますから次は3,そして7を選びます.要は4で割って3余る数です.3巡目は1から始まり,8で割って1余る数,その後は混沌としています.とりあえず,最後は45になっています.最後だけ出したければ,
ruby -e 'def f(num,step); a=(1..num).to_a; pos=0; z=[]; until a.empty?; pos=(pos-1+step)%a.size; z<<a.delete_at(pos); end; z; end; puts f(150,2).last'
とします.