いきなりですが問題です.
「8」の数を4つ使って,加減乗除をし,答えを求めます.
例えば,8÷8+8÷8=2です.ここで「8÷8+8÷8」を,「2になる式」と呼びます.
5になる式,6になる式,7になる式を,作ってください.
解答の前に,補足です.数を連接させて,「88」「888」「8888」といった数にするのは禁止とします.カッコはOKとします.「8÷8+8÷8」も「(8÷8)+(8÷8)」も,2になる式ですが,「((8÷8)+8)÷8」は,「1.125(または8分の9)になる式」です.カッコの入れ子も差し支えなく,{}や[]は使用しないこととします.
といったところで解答です.0から10までの各整数について,その値になる式の数と,具体的な式を1つずつ,示します.
0 ... 44通り ((8+8)-8)-8 1 ... 32通り ((8+8)-8)÷8 2 ... 1通り (8÷8)+(8÷8) 3 ... 2通り ((8+8)+8)÷8 4 ... 4通り (8×8)÷(8+8) 5 ... なし 6 ... 1通り 8-((8+8)÷8) 7 ... 1通り ((8×8)-8)÷8 8 ... 9通り ((8-8)×8)+8 9 ... 2通り ((8×8)+8)÷8 10 ... 2通り ((8+8)÷8)+8
5になる式はなく,6になる式,7になる式(と2になる式)は,それぞれ1通りだけでした.なお,2になる式の2組のカッコと,6になる式の外側,7になる式の内側のカッコは,除去しても結果が変わらず,異なる式と見なせます.しかしプログラムを書いてみると,このカッコの除去処理は容易ではなく,今回の出力では,いずれの式にもカッコを2つ入れ,演算子の適用の順序を明確にしました.
総当たりで式を求めて出力するプログラムをRubyで作成し,Gistに置きました.
「総当たり」の方針として,まず「『8』の数を4つ使った,加減乗除の式」として,次の形を考えます.
8 o1 8 o2 8 o3 8
ここでo1, o2, o3は「+-×÷」のいずれかです.
そしてo1, o2, o3の2項演算を,どの順番で適用するかによって,式が決まるというわけです.例えばo1に「÷」,o2に「+」,o3に「÷」を割り当てて,o1, o2, o3の順に演算を行うのなら,式は「((8÷8)+8)÷8」です.o1からo3までの割り当ては同じでも,o1, o3, o2の順にしたら,式は「(8÷8)+(8÷8)」になって答えも異なります.
場合の数は,o1からo3までの割り当ては4の3乗で64通り,そして適用順は,3つの演算子の組み合わせだから3の階乗で6通り…とするわけにいきません.今回の式では,「o1, o3, o2の順」と「o3, o1, o2の順」は,同じ式になります(o1が「÷」,o2が「+」,o3が「÷」で,o3, o1, o2の順のときにも,式は「(8÷8)+(8÷8)」です).それらは「式」として同一なので,別カウントにしないこととし,結局,適用順は5通りとなります.総数は64×5=320通りです.
式によっては分数や負の数のほか,0除算が発生することがあります(例えば「(8+8)÷(8-8)」).プログラムではこれも式として認め,内部で評価結果をnilにし,出力時にはNot a Numberを意味する「NaN」にしています.NaNになるのは15通りです.また最大の値は4096,最小の値は-504,分数になる中で最大と最小はとです*1.
(同日追記)本文およびGistのプログラムコードを更新しました.5通りの適用順を忠実にプログラムコードにすると,以下のようになり,o1, o2, o3の出現順序はさまざまですが,4つの8に対応する,v1, v2, v3, v4はどれもこの順に出現しているのは,面白いところです.
def eval(v1, v2, v3, v4, o1, o2, o3, d = 0) case d when 0 # d == 0: ((8 o1 8) o2 8) o3 8 v = op(o3, op(o2, op(o1, v1, v2), v3), v4) when 1 # d == 1: (8 o1 8) o2 (8 o3 8) v = op(o2, op(o1, v1, v2), op(o3, v3, v4)) when 2 # d == 2: (8 o1 (8 o2 8)) o3 8 v = op(o3, op(o1, v1, op(o2, v2, v3)), v4) when 3 # d == 3: 8 o1 ((8 o2 8) o3 8) v = op(o1, v1, op(o3, op(o2, v2, v3), v4)) when 4 # d == 4: 8 o1 (8 o2 (8 o3 8)) v = op(o1, v1, op(o2, v2, op(o3, v3, v4)))
*1:「8分の1プラスマイナス8」です.