以下で存在を知り購入。

成分的には「数学女子」といった趣で、正直もう少し数学成分が欲しかったところではある。しかしその抑えめの数学成分がかなりきちんとしている点で好感が持てる。これなら本物の数学男女も納得いくのではないか。

以下、断片的な感想。

  • ガチな数学が好きな人には「数学ガール」があるし。漫画化もされてるよ!
  • 数字は得意で数式とコンピューターが苦手という主人公の設定は、いける。
  • 一番気に入ったネタ: y = \sqrt{|x|}+\sqrt{6-x^2}; y = \sqrt{|x|}-\sqrt{6-x^2}; このグラフを書け
  • でも私が数学少年だった頃、ワシはバレンタインデーにチョコレートを渡す習慣がない国にいたので、いまいちピンと来ないところはある。その代わりカードはもらったしあげたけれども。 Linear Algebra を手ほどきしてくれた数学女子なTAにも。
  • 主人公の用意したチョコ、私だったら黄金比とかけあわせていたなあ。まず黄金比の板チョコを用意して、正方形を一個切り出して本名。残ったのも黄金比なのでまた正方形を切り出して…以下同文という具合
  • 「Make 10」またの名を「テンパズル」にはまる主人公を見て、思わず強引に解くプログラムを書いてしまった。どう考えても主人公が答えを見つけるよりプログラムを書く時間の方が短かったというのはおいておいて、主人公のことを念頭において豪快に書きました:-)
    4桁の数字
    答え
  • Make 10 といえば、このページがすごい。 ここにある拡張版 Make 10 の回答集を主人公に教えたら、一生はまっちゃうかも。

ぜひ(娯|誤|御)一読あれ。

Dan the Mathphilia


Make 10 する JavaScript

/* 1st f is for fake, not file */
var fsprintf = (function(){
  var rx = new RegExp(/%[a-z]/g);
  return function(){ 
    var args = [].slice.apply(arguments);
    var fmt  = args.shift();
    return fmt.replace(rx, function(m0){
      return args.shift();
    });
  };
})();

var pats = [
    "%d %s %d %s %d %s %d",
    "(%d %s %d) %s %d %s %d",
    "%d %s (%d %s %d) %s %d",
    "%d %s %d %s (%d %s %d)",
    "(%d %s %d %s %d) %s %d",
    "%d %s (%d %s %d %s %d)",
    "((%d %s %d) %s %d) %s %d",
    "(%d %s (%d %s %d)) %s %d",
    "%d %s ((%d %s %d) %s %d)",
    "%d %s (%d %s (%d %s %d))",
    "(%d %s %d) %s (%d %s %d)",
];

var opts = ['+','-','*','/'];

var solve = function(digits){
  var a = digits[0], b = digits[1], c = digits[2], d = digits[3];
  var result = [];
  for (var i = 0, o = opts[0]; o = opts[i]; i++){
    for (var j = 0, p = opts[0]; p = opts[j]; j++){
      for (var k = 0, q = opts[0]; q = opts[k]; k++){
        for (var l = 0, r = pats[0]; r = pats[l]; l++){
          var e = fsprintf(r, a, o, b, p, c, q, d);
          try{
            var v = eval(e);
            if (v === 10) result.push(e + ' = ' + v);
          }catch(e){
          }
        }
      }
    }
  }
  return result;
};

var permute = function(ary, cb, ret){
    if (!ret) ret = [];
    if (ary.length){
        var nary, ntmp, i;
        for (i = 0; i < ary.length; i++){
            nary = ary.slice();
            nret = ret.slice();
            nret.push(nary.splice(i, 1)[0]);
            arguments.callee(nary, cb, nret);
        }
    }else{
        cb(ret);
    }
}

var permuted = function(ary){
  var ret = [];
  permute(ary, function(a){ ret.push(a) });
  return ret;
}

var uniq = function(ary){
  var ret = [], seen = {};
  for (var i = 0, l = ary.length; i < l; i++){
    var v = ary[i];
    if (!seen[v]) seen[v] = 1, ret.push(v);
  }
  return ret;
};

make10 = function(digits){
  var perms = uniq(permuted(digits));
  var answers = [];
  for (var i = 0, l = perms.length; i < l; i++) {
    answers = answers.concat(solve(perms[i]));
  }
  return answers;
}

元となった Perl Script

全ての場合をしらみつぶし。これでもCore i7なiMacで二分足らずで終了します。しかもスレッド一つで。

% wc make10.out 
84454  760086 1829102 make10.out

これで正しいのかな…

#!/usr/bin/env perl
use strict;
use warnings;

my @pats = (
    "%d %s %d %s %d %s %d",
    "(%d %s %d) %s %d %s %d",
    "%d %s (%d %s %d) %s %d",
    "%d %s %d %s (%d %s %d)",
    "(%d %s %d %s %d) %s %d",
    "%d %s (%d %s %d %s %d)",
    "((%d %s %d) %s %d) %s %d",
    "(%d %s (%d %s %d)) %s %d",
    "%d %s ((%d %s %d) %s %d)",
    "%d %s (%d %s (%d %s %d))",
    "(%d %s %d) %s (%d %s %d)",
);

my @opts = qw{+ - * /};

sub solve{
    my ($a, $b, $c, $d) = @_;
    for my $o (@opts){
	for my $p (@opts){
	    for my $q (@opts){
		for my $t (@pats){
		    my $e = sprintf $t, $a, $o, $b, $p, $c, $q, $d;
		    my $v = eval $e;
		    next if $@; # zero division
		    next unless $v == 10;
		    print "$e = $v\n";
		}
	    }
	}
    }
}

for my $a (0..9){
    for my $b (0..9){
	for my $c (0..9){
	    for my $d (0..9){
		solve $a, $b, $c, $d;
	    }
	}
    }
}