Skip to content

Instantly share code, notes, and snippets.

@takehiko
Last active March 11, 2019 09:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takehiko/d5bedb440a0552d021962bfac608979c to your computer and use it in GitHub Desktop.
Save takehiko/d5bedb440a0552d021962bfac608979c to your computer and use it in GitHub Desktop.
Make 2-digit numbers that appear on the "kuku" table
#!/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