Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.46 KB | None | 0 0
  1. module TenPuzzle
  2. class Solver
  3. ALL_NUMBER_COMBINATIONS = [*1..9].combination(4).to_a
  4. OPERATORS = %i(+ - * /)
  5.  
  6. def solve
  7. count = 0
  8. ALL_NUMBER_COMBINATIONS.each do |numbers|
  9. nodes = numbers.map { |n| Node.new(n, n.to_s) }
  10. formulas = two_two_pattern_formulas(nodes) + two_one_one_pattern_formulas(nodes)
  11.  
  12. count += 1 if formulas.any?
  13.  
  14. puts "#{numbers.join(',')} : #{formulas.any? ? 'OK' : 'NO'} : example #{formulas.sample}"
  15. end
  16.  
  17. puts "(10になる組み合わせの数) / (全4桁の組み合わせ数) = #{count} / #{ALL_NUMBER_COMBINATIONS.size}"
  18. end
  19.  
  20. def calculate_result_nodes(node1, node2)
  21. OPERATORS.flat_map { |operator|
  22. if %i(- /).include?(operator)
  23. # 順番で結果が異なる演算子の場合
  24. [
  25. node1.calculate(node2, operator),
  26. node2.calculate(node1, operator)
  27. ]
  28. else
  29. [node1.calculate(node2, operator)]
  30. end
  31. }
  32. end
  33.  
  34. def two_two_pattern_formulas(nodes)
  35. formulas = []
  36. nodes.combination(2).each do |first_pair|
  37. nodes_for_first_pair = calculate_result_nodes(*first_pair)
  38.  
  39. other_pair = nodes - first_pair
  40. nodes_for_other_pair = calculate_result_nodes(*other_pair)
  41.  
  42. nodes_for_first_pair.product(nodes_for_other_pair).each do |last_pair|
  43. whole_nodes = calculate_result_nodes(*last_pair)
  44. formulas += whole_nodes.select(&:ten?).map(&:formula)
  45. end
  46. end
  47. formulas
  48. end
  49.  
  50. def two_one_one_pattern_formulas(nodes)
  51. formulas = []
  52. nodes.combination(2).each do |first_pair|
  53. nodes_for_first_pair = calculate_result_nodes(*first_pair)
  54. second_node, last_node = nodes - first_pair
  55. formulas += formulas_merged_one_and_one_nodes(nodes_for_first_pair, second_node, last_node)
  56. formulas += formulas_merged_one_and_one_nodes(nodes_for_first_pair, last_node, second_node)
  57. end
  58. formulas
  59. end
  60.  
  61. def formulas_merged_one_and_one_nodes(nodes_for_first_pair, second_node, last_node)
  62. second_pair_results = nodes_for_first_pair
  63. .flat_map { |first_pair_result| calculate_result_nodes(first_pair_result, second_node) }
  64.  
  65. second_pair_results.flat_map do |second_pair_result|
  66. whole_nodes = calculate_result_nodes(second_pair_result, last_node)
  67. whole_nodes.compact.select(&:ten?).map(&:formula)
  68. end
  69. end
  70. end
  71.  
  72. class Node
  73. attr_reader :val, :formula
  74.  
  75. def initialize(arg_val, arg_formula)
  76. @val = arg_val
  77. @formula = arg_formula
  78. end
  79.  
  80. def ten?
  81. @val == 10
  82. end
  83.  
  84. def calculate(node, operator)
  85. case operator
  86. when :+
  87. sum(node)
  88. when :-
  89. diff(node)
  90. when :*
  91. product(node)
  92. when :/
  93. quotient(node)
  94. end
  95. end
  96.  
  97. def sum(node)
  98. new_val = @val + node.val
  99. new_formula = "(#{@formula} + #{node.formula})"
  100. Node.new(new_val, new_formula)
  101. end
  102.  
  103. def diff(node)
  104. new_val = @val - node.val
  105. new_formula = "(#{@formula} - #{node.formula})"
  106. Node.new(new_val, new_formula)
  107. end
  108.  
  109. def product(node)
  110. new_val = @val * node.val
  111. new_formula = "(#{@formula} * #{node.formula})"
  112. Node.new(new_val, new_formula)
  113. end
  114.  
  115. def quotient(node)
  116. return nil if node.val.zero?
  117. new_val = Rational(@val, node.val)
  118. new_formula = "(#{@formula} / #{node.formula})"
  119. Node.new(new_val, new_formula)
  120. end
  121. end
  122. end
  123.  
  124. TenPuzzle::Solver.new.solve
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement