なんかすげー面白そうな番組が始まったんですね。テレビは来週から見始めるとして、Danさんのエントリに問題が載ってたので解いてみよう。ついでに最近Javaと共に勉強しているPythonの修行にも丁度良さそうなので、プログラムはPythonで書いてみる。
自分で解いてみたい方は以下はネタバレになりますのでご注意を。
問題
15段の階段があります。階段を一段づつ上ってもOK、一段飛ばしで上ってもOKとして、この階段の上り方が何通りあるか答えなさい。
要するに、一回に1段か2段進めるという訳ですね。そして上るまでの歩数に注目すると、「最多で15歩、最小で8歩」ということになる。
15歩のときの昇るときの様子は以下のように表せる。
1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 15
8歩で昇るときの様子の一例は以下のように表せる。
2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 = 15
この8歩の方に注目してみれば、「8歩で昇るパターン」には8通りあることはすぐ分かると思います。つまり1段昇るのを1歩目〜8歩目のどこにもってきても良いからです。15のパターンは上に上げた1つのパターンしかありません。
さて8歩や15歩と同じように、9歩〜14歩でもこのように「1と2の組み合わせ」で15になるパターンがいくつあるのかを考えれば、この問題の答えが見つかりそうです。
とりあえず、プログラムを使って超強引に解いてみます。超強引とは15歩〜8歩、つまり1と2の数が15個〜8個の足し算に対して答えが15になるパターンを数えていきます。
def ListSum(L): t = 0 for i in L: t += i return t def PlusOne(L): L[0] = L[0] + 1 for i in range(len(L)): if L[i] == 3: L[i] = 1 L[i + 1] = L[i + 1] + 1 def Kaidan(Dan): hit = 0 for j in range(Dan,int(Dan - 0.5) / 2,-1): L = [1] * j flg = 1 while flg: sum = ListSum(L) if sum == Dan: hit += 1 if sum == j * 2: flg = 0 if flg == 1: PlusOne(L) print hit if __name__ == '__main__': Kaidan(15)
解法、プログラム共に全然エレガントじゃない(笑)。しかも実行してみると分かると思うけど、20段くらいで使い物にならない速度です。
速度が遅い原因は「ありえないパターン」についても調べまくっているからであると思う。ありえないパターンとは、例えば8歩で昇るパターンの場合、1が2つ入ることはありえない。1が1つじゃないと15まで届きませんからね。
この辺を考慮して、次回改善策を披露します。
他の人は数学的に解いてるなあ…
番組のホームページは以下。「99.9%は仮説」の著者、竹内薫氏も出演している模様。
http://www.fujitv.co.jp/b_hp/komanechi/index.html