問題概略
4 枚のカードに 1 から 9 までのいずれかの整数を記入します。同じ数を複数回記入しても構いません。
できた 4 枚のカードをすべて使って掛け算と割り算だけの計算式を作り,答えが 10 になるようにします。
たとえばカードに書かれた数字が「2,2,5,2」のとき とすれば答えが 10 の計算式を作れます。このような数の記入の仕方は何通りあるでしょうか。
解説の pdf も作りました。きれいなレイアウトで読みたい方はこちらをどうぞ。
題意を正確にとらえる
は左から順に計算して とするらしいです。
また,「2,2,5,2」から が作れることから 4 枚のカードは並べ替え可能です。
求めるのは 4 つの数の組 の個数ではなく,集合 の個数だとわかります。
数を並べ替えていい以上,掛け算と割り算の順番を考える必要はありません。
5 と 2 を作る
5 と 2 を作って掛け算すれば 10 になります。5 が 2 個か 4 個の場合が不適なのはすぐわかるので,5 は 1 個か 3 個です。
ア)5 が 3 個のとき
で 5 を作ります。これと 2 の積は 10 なので は条件をみたします。
イ)5 が 1 個のとき
まず の形のものが 8 通りあります。
2 は , , でも作れます。
\begin{align*}
2 &=4\div (2\div 1)=4\div (4\div 2)=4\div (6\div 3)\\
&=6\div (3\times 1)=6\div (6\div 2)= 6\div (9\times 3)\\
&=8\div (4\div 1)=8\div (8\div 2)
\end{align*}
このうち は で使った と同じなので除きます。
まとめると答えは 個です。
mathematica で解く
手計算で解けましたが,モレやダブリが生じそうなのでプログラムを組んで解いてみました。
のような関数を手で 個作るのは嫌なので
を 3 回合成します。リストの累積利用の結果を返す関数 Fold を使いました。
こうして作った 8 個の関数に を代入して,その値の集合が 10 を含むものを探します。
In[]:= AbsoluteTiming[ lst = Tuples[Range@9, 4]; f[x_, y_] := Flatten[{x*y, x/y}]; g[{a_, b_, c_, d_}] := MemberQ[Fold[f, a, {b, c, d}], 10]; ans = Length@DeleteDuplicates[Sort /@ Select[lst, g]]] Out[]= {0.0614063, 16}