読者です 読者をやめる 読者になる 読者になる

RubyでMake10やってみた

実家に帰ってTVをつけたらこんなCMが、


Nexus 7 : 10 Puzzle - YouTube

気になったのは、CM中に出てきた「1,1,5,8で10を作る」という問題。

このような問題はMake10とか、10Puzzleと呼ばれているらしい。 (テンパズル@wikipedia)

小さい頃から車のナンバーとかでMake10をやってきたこの道数10年になる私が、この1,1,5,8のパターンはなかなか解けない。。。

→ しかし弟にやらせたら15分程で解きおった。
→ → 弟答え言いたがる。
→ → → 明日まで待ってと頼む。

どうしても自力で解いてスッキリしたかった
このままでは明日、弟がドヤ顔で回答している姿がぁぁぁぁ、、、

という経緯でMake10を解くプログラムを書きました。

gemで公開しているので、簡単に使えます。
https://rubygems.org/gems/make10

$ gem install make10
$ irb
> require 'make10'
=> true
> Make10.solve(9,9,9,9)
=> ["(9+(9*9))/9", "((9*9)+9)/9"]


ソースコード

module Make10

  @ans_format = "%f%c%f%c%f%c%f"
  @ops = ["+", "-", "*", "/"]
  @parentheses_patterns = ["%f%c%f%c%f%c%f", 
                          "(%f%c%f)%c(%f%c%f)", 
                          "((%f%c%f)%c%f)%c%f", 
                          "(%f%c(%f%c%f))%c%f", 
                          "%f%c((%f%c%f)%c%f)", 
                          "%f%c(%f%c(%f%c%f))", ]

  def solve(*inputs)
    nums_list = make_all_pattern(inputs)
    ans = []
    nums_list.each do |nums|
      @ops.each do |o1|
        @ops.each do |o2|
          @ops.each do |o3|
            @parentheses_patterns.each do |pattern|
              exp = sprintf(pattern, nums[0] , o1, nums[1], o2, nums[2], o3, nums[3])
              ans << exp.gsub(/0|\./, "") if eval(exp) == 10.0
            end
          end
        end
      end
    end

    return ans.uniq

  end

  def make_all_pattern(nums)
    nums_list = []
    nums.permutation.each {|d| nums_list << d}
    nums_list
  end

  module_function :solve, :make_all_pattern

end

© karahiyo