$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()