問題
長さn[cm]の1本の棒を1[cm]単位に切り分けることを考えます。
ただし1本の棒を一度に切ることができるのは1人だけです。
切り分けられた棒が3本あれば、同時に3人できることができます。
最大m人の人がいるとき、最短何回で切り分けられるかを求めてください。
例えば、n = 8, m = 3の時は下図のようになり、
4回で切り分けることができます。
1回目 |1|2|3|4||5|6|7|8|
2回目 |1|2||3|4| |5|6||7|8|
3回目 |1||2| |3||4| |5||6| |7|8| <= 3人しかいないので1ヶ所残る
4回目 |1| |2| |3| |4| |5| |6| |7||8|
|1| |2| |3| |4| |5| |6| |7| |8|
問題1
n = 20, m = 3の時の回数を求めてください。
問題2
n = 100, m = 5の時の回数を求めてください。
引用「プログラマ脳を鍛える数学パズル 著者 長井 敏克」
回答
def cutbar(m, n, current, count):
if current >= n:
print("Count:", count)
elif current < m:
count += 1
current = current * 2
cutbar(m, n, current, count)
else:
count += 1
current += m
cutbar(m, n, current, count)
count = 0
cutbar(3, 20, 1, count) # Count: 8
cutbar(5, 100, 1, count) # Count: 22
def cutbar(m, n):
count = 0
current = 1
while n > current:
current += current if current < m else m
count = count + 1
print(count)
cutbar(3, 20) # Count: 8
cutbar(5, 100) # Count: 22
つまづいたところ
ずばりcurrent += m
や
current += current if current < m else m
のような、
なぜcurrent(棒の本数)
にm(人数)
などを足すのかということですね。
最後は無理やりおちつかせた形になりました・・・
原因としては、
問題を読んだはじめの印象が「どんどん棒の本数を倍にしていくんだな」というもので、
それに最後まで引っ張られてしまいました。
確かにanswer_1.py
では、途中まで棒の本数を倍にし続けます。
しかし、棒の本数が人数を超えたあとは、
棒の本数がn(cm)
を超えるまでm(人数)
をひたすら足し続けるような処理内容でした。
answer_2.py
に至っては、棒の本数を倍するなど全くせず、
本数か人数を足していくような処理内容です。
結局、「こういうものなんだな」に近いような感じで自分を納得させました。
再帰
や三項演算子
を使う機会となったのは、いい経験になりました。
今後自然に書けるようになって行きたいです。
以上、ご拝読ありがとうございました。