算額(その1541)
埼玉県本庄市都島 正観寺 戸塚盛政の算額 享保11年(1726)
山口正義:やまぶき 第 26 号
https://yamabukiwasan.sakura.ne.jp/ymbk26.pdf
山口正義:やまぶき 第 40 号
https://yamabukiwasan.sakura.ne.jp/ymbk40.pdf
甲,乙,丙,丁,戊の立方体がある。甲と乙の体積の和が 189,丙と丁と戊の体積の和が 36 である。辺の長さの差は一定である。それぞれの一辺の長さはいかほどか。
立方体:甲の一辺の長さを「甲」,辺の差を「差」とおき,以下の連立方程式を解く。
問題文に出てくる 2 つの定数を記号のままとして解こうとすると,"RecursionError('maximum recursion depth exceeded')" が発生するので解けない。それほど複雑だということであろう。
using SymPy
@syms 甲::positive, 差::positive
eq1 = 甲^3 + (甲 - 差)^3 - 189
eq2 = (甲 -2差)^3 + (甲 -3差)^3 + (甲 -4差)^3 - 36
res = solve([eq1, eq2], (甲, 差))[1]
(5, 1)
甲の一辺の長さは 5,差が 1 なので,順次 4, 3, 2, 1 となる。
山口の解説は「(まともにやれば)9 次方程式が得られるが,これをとくのはやっかいである」と書いているが,SymPy では何の苦も無く解ける(当たり前だが)。
丙,丁,戊の体積の和が 36 なので,丙^3 + 丁^3 + 戊^3 = 36, 丙 > 丁 > 戊, 各辺は整数なので,3, 2, 1 が解であることはすぐにわかり,5^3 + 4^3 = 189 となるのを確認すれば解を得るのは簡単である。直感で解いていはいけないのかな?
直感で解かれるのを避けるなら,以下のようなテストデータを作ればよい。
甲^3 + 乙^3 = 3699397765
丙^3 + 丁^3 + 戊^3 = 5120681355
using SymPy
@syms 甲::positive, 差::positive
eq1 = 甲^3 + (甲 - 差)^3 - 3699397765
eq2 = (甲 -2差)^3 + (甲 -3差)^3 + (甲 -4差)^3 - 5120681355
res = solve([eq1, eq2], (甲, 差))[1]
(1234, 13)
甲の一辺の長さは 1234,差は 13 である。
1. ブルートフォースで解く
甲の一辺の長さと差が未知なので,探索範囲を誤ると答えが出ないが,実行時間を見ながら範囲を広げていけば解が見つかる可能性は高い。
実行時間を短くするために色々策を弄することもできるが,まずは,単純なプログラムでやってみる。
以下のプログラムは 2 秒以内で正解を出す。
@time begin
K1 = 3699397765
K2 = 5120681355
for 差 = 1:100
for 甲 = 5:999999
乙 = 甲 - 差
丙 = 甲 - 2差
丁 = 甲 - 3差
戊 = 甲 - 4差
戊 > 0 && 甲^3 + 乙^3 == K1 && 丙^3 + 丁^3 + 戊^3 == K2 && (println("甲 = $甲, 差 = $差"); break)
end
end
end
甲 = 1234, 差 = 13
1.396169 seconds (99.00 M allocations: 1.476 GiB, 5.47% gc time, 0.70% compilation time)