$n = 11 $towers = {} $idx = {a: 1, b: 2, c: 3} ​ def init $towers = { a: 1.upto($n).to_a.reverse, b: [], c: [] } end ​init() ​def stat() ts = [:a, :b, :c] puts ts.join("\t") ($n - 1).downto(0).each do |i| [:a, :b, :c].each do |t| print "#{$towers[t][i]}\t" end puts end end ​def m(from, to) d = $towers[from].pop dest_d = $towers[to].last if (to == :b && d == 1) || (dest_d && d > dest_d) puts("illegal move") exit(0) end $towers[to].push(d) puts "#{d} #{$idx[from]} #{$idx[to]}" end ​ ​ def move_right m(:a,:c) m(:a,:b) m(:c,:a) m(:b,:c) m(:a,:c) end ​ def move_left m(:c,:a) m(:c,:b) m(:a,:c) m(:b,:a) m(:c,:a) end ​ def swap() da = $towers[:a].last.to_i db = $towers[:b].last.to_i dc = $towers[:c].last.to_i ts = [da, db, dc] idx = [:a, :b, :c] ​ ts.each_with_index do |d, i| next if d == 0 || d == 1 ts.each_with_index do |dd, ii| next if dd == d ​ if dd == 0 || d < dd return [idx[i], idx[ii]] end end end end def done?() $towers[:a].last == nil && $towers[:b].last == nil end ​ def solve while true move_right break if done?() m(*swap()) move_left m(*swap()) end end stat() solve() stat()