Last active
March 11, 2019 09:54
-
-
Save takehiko/d5bedb440a0552d021962bfac608979c to your computer and use it in GitHub Desktop.
Make 2-digit numbers that appear on the "kuku" table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# kukuniketa.rb : 「九九2桁」ソルバ | |
# by takehikom | |
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]といった配列を入力にとり, | |
# 2個ずつ組み合わせて2桁の数を作って,いずれも九九の答えに出現する | |
# ものを求める. | |
# see also: https://takehikom.hateblo.jp/entry/2019/03/11/054444 | |
# 解を求めて出力する | |
def kukuniketa_solver(array = nil) | |
# 配列チェック | |
raise "not an array" if !(Array === array) | |
raise "empty" if array.length == 0 | |
raise "odd number of elements" if array.length % 2 == 1 | |
count_all = 0 # すべての解の総数 | |
hash_numseq = {} # 解となる2桁の数の組み合わせを格納するハッシュ | |
array.permutation do |array2| | |
# 十の位に0が来るものは処理しない | |
next if (0...(array2.length)).any? { |i| i % 2 == 0 && array2[i] == 0 } | |
# 2桁の数を作る | |
array3 = (1..(array2.length / 2)).map do |i| | |
array2[i * 2 - 2] * 10 + array2[i * 2 - 1] | |
end | |
# 並べ替えたものがすでに解にあるなら処理しない | |
next if hash_numseq.key?(array3.sort) | |
# 1つでも九九にない数があれば処理しない | |
next if !array3.all? { |n| kuku?(n) } | |
# 解を出力する | |
hash_numseq[array3.sort] = true | |
array4 = array3.map { |n| decomp_all(n) } | |
count_all += print_answers(array4) | |
end | |
# 解の数と,2桁の数の組み合わせを出力する | |
puts "#{count_all} answers." | |
puts "Numbers (#{hash_numseq.keys.length} patterns): #{hash_numseq.keys.map{|a|a.inspect}.join(' ')}" | |
end | |
# nが九九の表(積)に入っていたら真,そうでなければ偽を返す | |
def kuku?(n) | |
1.upto(9) do |i| | |
return true if n / i < 10 && n / i * i == n | |
end | |
false | |
end | |
# nに対し九九の2つの因数の積を文字列の配列で返す | |
def decomp_all(n) | |
(1..9).map { |i| | |
(n / i < 10 && n / i * i == n) ? "%d * %d = %2d" % [i, n / i, n] : nil | |
}.compact | |
end | |
# arrayの各要素の九九分解式を出力する.出力した解の数を返す. | |
# 再帰呼び出しを使用している. | |
def print_answers(array, output_array = []) | |
count = 0 | |
if (array.empty?) | |
puts output_array | |
puts | |
return 1 | |
end | |
array2 = array[1..-1] | |
array[0].each do |s| | |
count += print_answers(array2, output_array + [s]) | |
end | |
count | |
end | |
if __FILE__ == $0 | |
kukuniketa_solver([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) | |
# kukuniketa_solver([0, 1, 2, 3, 5, 6, 7, 8]) | |
# kukuniketa_solver([1, 2, 3, 4, 5, 6]) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment