遅ればせながら、みなさま、あけましておめでとうございます。

2010 年になりましたが、この 2010 という数字について、最近ある事実を発見しました。この 2010 は、1 から 9 までを順番に並べた 1+2÷3×45×67+8−9 という式で計算できるんです。

1+2÷3×45×67+8−9=2010

...って、大仰に書き出してはみましたが、これは、日本では小町算という名前で知られる有名な算数パズルですね。今回はこれを Mathematica でやってみます。

(あれ?なぜか今回は「ですます」調になっちゃってますね。まぁ、気にしないで下さい)

ここでは、単純にすべての場合を試して、その中から 2010 になるものを探すことにします。となると、すべての組み合わせをどうやって作るかがポイントになります。
これ、最初は一人で考えてうんうん言っていたのですが、かつて僕に Mathematica を仕込んだ知人(僕の外部脳とも言う)に相談してみたら、「+−×÷の他に〈前後の数字を接合する〉という5番目の演算子を考えて、それぞれの演算子に 0〜4 の数字を割り当てたら、5進数の数え上げでいけるんじゃない?」とのこと。おぉ、なるほど、そうすれば良いのか。

つまりこうです。
1〜9 までの数字の列の、それぞれの数字の間(8カ所)に+−×÷○の5種類の演算子を入れることにします。○は前後の数字を接合する演算子。つまり 4○5 は、2桁の数字 45 になります。そうして、各演算子に下図のように 0〜4 の数字を対応づけます。

こうすることで、「演算子のすべての組み合わせ」が、「5進数の 00000000 から 44444444 までの数値」に対応することになります。

Mathematica で、上の図にある5進数の 24303021 を、演算子の列に変換するのは次のように書けます(Mathematica では n 進数を n^^xxxxx の形で書きます)。

In[1]:=
{"","-","+","*","/"}[[#+1]]& /@ IntegerDigits[5^^24303021, 5, 9]

Out[1]=
{, +, /, *, , *, , +, -}

接合演算子○は、空文字列 "" で表しています。8桁じゃなく9桁で IntegerDigits しているのは、次に演算子を 1〜9 の並びの間に挟み込んで数式に戻すときに数が揃っているとすっきり書けるからです。

In[2]:=
StringJoin@Transpose[
  {{"","+","/","*","","*","","+","-"}, ToString /@ Range[9]}]

Out[2]=
1+2/3*45*67+8-9

最後に ToExpression を使って、文字列を数式として評価すればオーケー。

In[3]:=
ToExpression["1+2/3*45*67+8-9"]

Out[3]=
2010

これと同じことを、5進数の 00000000 から 44444444 まですべて行なって、ToExpression の結果が 2010 になったときにそれを書き出せば良いので、今回やりたいすべての組み合わせの確認は、次のように実現できます。

Do[
  expr = StringJoin@Transpose[
    {{"","-","+","*","/"}[[#+1]]& /@ IntegerDigits[n, 5, 9],
      ToString /@ Range[9]}];
  If[ToExpression[expr] == 2010, Print[expr]]
 , {n, 5^^00000000, 5^^44444444}]

コードはなんとたったの6行ぽっち。効率の良いコードではないので実行はトロトロですが、1分も待てば結果が得られるので今回はこれで十分。
結果は4つ。これで全部。探索範囲を、5進数の 144444444 まで延長すれば、先頭に−(マイナス)が付いた場合も探せます。

以上、遅ればせながらのお正月ネタでした。
今年が皆様にとって良い1年でありますように...。

※この記事の内容は執筆者の個人的見解で、ヒューリンクスによる公式情報ではありません。[免責事項]

トラックバック

この記事へのトラックバックURL
http://blog.hulinks.co.jp/cgi/mt/mt-tb.cgi/401
内容に対しての関連性がみられないものは削除する場合があります

コメント一覧

面白い話題をありがとうございます。
Knuthの誕生日にあわせてケーキを作った方がいて、Knuthのホームページに別のパターンで2010が作られています。
http://www-cs-faculty.stanford.edu/~uno/news.html

おー、Knuth だー。藤村さん、楽しい記事のご紹介、大変ありがとうございます。
僕もいろいろ見てみたのですが、どうも、欧米では、このタイプの「数字の結合は使わないで括弧は OK」という小町算の方がメジャーのようですね。下記ページにすごいリストがありました。
http://www.thesamet.com/2010.txt

自己レス(?)です。
記事中のコードで Transpose 関数を使っている部分の処理は、Riffle 関数に置き換えるとほんの少し自然に書けますね。Riffle って ver.6 で追加されたらしい関数なのですが、恥ずかしながら今日まで知りませんでした。
http://reference.wolfram.com/mathematica/ref/Riffle.html

コメントの投稿

Emailアドレスは表示されません。は必須項目です。
ヒューリンクス取り扱い製品の内容や購入に関するお問い合わせはヒューリンクスサイト連絡先へお願いいたします。投稿前にその他の注意事項もご覧ください。

HULINKS サイトの新着情報