Created
July 6, 2014 20:56
-
-
Save takehiko/03c66680606c48344539 to your computer and use it in GitHub Desktop.
This file contains 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 | |
# ruby magicsquare.rb | |
# ruby magicsquare.rb -c | |
# ruby magicsquare.rb 2 | |
# ruby magicsquare.rb 3 | |
module MagicSquare | |
class Table | |
def initialize(t = nil) | |
@numbers = t || [nil, nil, 6, 3, nil, nil, 0, nil, nil] | |
end | |
attr_accessor :numbers | |
def to_s | |
s = "" | |
3.times do |row| | |
3.times do |col| | |
s += "[#{@numbers[3 * row + col] || ' '}]" | |
end | |
s += "\n" | |
end | |
s.strip | |
end | |
def print | |
puts to_s | |
end | |
def fill(ary) | |
i = 0 | |
ary.each do |item| | |
until @numbers[i].nil? | |
i += 1 | |
if i == @numbers.length | |
return self | |
end | |
end | |
@numbers[i] = item | |
end | |
self | |
end | |
def answer?(opt_msg = false) | |
if @numbers.compact.length != @numbers.length | |
return opt_msg ? "not filled" : false | |
end | |
if @numbers.uniq.length != @numbers.length | |
return opt_msg ? "same numbers found" : false | |
end | |
if @numbers[2] != 6 || @numbers[3] != 3 || @numbers[6] != 0 | |
return opt_msg ? "initial state changed" : false | |
end | |
[@numbers[1], @numbers[3], @numbers[5], @numbers[7]].each do |num| | |
if num.even? | |
return opt_msg ? "odd number condition violated" : false | |
end | |
end | |
sums = [] | |
sums << @numbers[0] + @numbers[1] + @numbers[2] | |
sums << @numbers[3] + @numbers[4] + @numbers[5] | |
sums << @numbers[6] + @numbers[7] + @numbers[8] | |
sums << @numbers[0] + @numbers[3] + @numbers[6] | |
sums << @numbers[1] + @numbers[4] + @numbers[7] | |
sums << @numbers[2] + @numbers[5] + @numbers[8] | |
sums << @numbers[0] + @numbers[4] + @numbers[8] | |
sums << @numbers[2] + @numbers[4] + @numbers[6] | |
if sums.uniq.length != sums.length | |
return opt_msg ? "same sums found" : false | |
end | |
opt_msg ? "OK" : true | |
end | |
end | |
class Solver | |
def initialize(opt_c = false) | |
@table_init = Table.new | |
@opt_correct_answer_only = opt_c | |
@trial_count = 0 | |
end | |
def fill_table(t, ary) | |
t.fill(ary) | |
end | |
def valid_table(t = @table_init, opt_msg = false) | |
t.answer?(opt_msg) | |
end | |
def check_and_print_result(t) | |
@trial_count += 1 | |
if @opt_correct_answer_only | |
if t.answer? | |
t.print | |
puts | |
end | |
else | |
puts "Trial \##{@trial_count} / Result: #{valid_table(t, true)}" | |
t.print | |
puts | |
end | |
end | |
def solve(param = nil) | |
case param | |
when "2" | |
solve_evenodd | |
when "3" | |
solve_perm9 | |
else | |
solve_perm6 | |
end | |
end | |
def solve_evenodd | |
if !@opt_correct_answer_only | |
Table.new.print | |
puts | |
end | |
ary_odd = "157".split(//).map {|item| item.to_i} | |
ary_even = "248".split(//).map {|item| item.to_i} | |
ary_odd.permutation do |perm_odd| | |
ary_even.permutation do |perm_even| | |
t = Table.new | |
t.numbers[1], t.numbers[5], t.numbers[7] = perm_odd | |
t.numbers[0], t.numbers[4], t.numbers[8] = perm_even | |
check_and_print_result(t) | |
end | |
end | |
end | |
def solve_perm9 | |
ary = (0..8).to_a | |
ary.permutation do |perm| | |
check_and_print_result(Table.new(perm)) | |
end | |
end | |
def solve_perm6 | |
if !@opt_correct_answer_only | |
Table.new.print | |
puts | |
end | |
ary = "124578".split(//).map {|item| item.to_i} | |
ary.permutation do |perm| | |
check_and_print_result(Table.new.fill(perm)) | |
end | |
end | |
end | |
end | |
if __FILE__ == $0 | |
opt_c = false | |
if /^-c/ =~ ARGV.first | |
ARGV.shift | |
opt_c = true | |
end | |
MagicSquare::Solver.new(opt_c).solve(ARGV.first) | |
end | |
=begin | |
http://www.juen.ac.jp/math/journal/files/vol29/29-tsukada.pdf | |
【問題1】 | |
[ ][_][6] | |
[3][ ][_] | |
[0][_][ ] | |
たて,横,ななめの3つのマス内の数字の和がすべてことなるように0~8を各1個ずつ入れます.灰色の4つのマスには奇数の数字を入れます.いま,0,3,6が図上のように入っています.このとき,残りの1,2,4,5,7,8を入れなさい. | |
(灰色:[_]および[3]) | |
=end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment