rohacik = [ [00,10,01], [00,10,11], [10,11,01], [00,01,11] ] stvorcek = [ [00,10,01,11] ] hadik = [ [00,01,11,12], [01,11,10,20], [10,11,01,02], [00,10,11,21] ] tecko = [ [01,11,10,12], [01,11,00,02], [10,11,00,20], [10,11,01,21] ] krizik = [ [10,01,11,21,12] ] ciarka = [ [00,01,02], [00,10,20] ] elko = [ [00,01,11,21], [00,10,20,21], [00,10,01,02], [02,10,11,12], [00,10,11,12], [20,21,11,01], [00,01,02,12], [01,00,10,20] ] $piece_shapes = [ krizik, hadik, tecko, stvorcek, elko, ciarka, rohacik ].reverse $piece_quantities = [ 2, 2, 2, 2, 2, 2, 4 ].reverse def empty_map() map = Array.new(6).map{ Array.new(10) } map[6] = $piece_quantities.dup map end def try_piece(map, ptype, shape, px, py) shape.each do |c| xoff = c/10; yoff = c%10 return if px+xoff >= 10 or py+yoff >= 6 or px+xoff < 0 or py+yoff < 0 return if map[py+yoff][px+xoff] end # past this point, the piece can be placed in there; create new entry in $solutions_to_try mapdup = map.collect{ |row| row.dup } shape.each { |c| mapdup[py+c%10][px+c/10] = ptype } mapdup[6][ptype] -= 1 $solutions_to_try << mapdup end def find_empty_field(map) 6.times { |y| 10.times { |x| return [x,y] if not map[y][x] } } nil end def try_solution(map) $timer = ($timer+1)%300; print(`clear` + dump_solution(map) + "Found: #{$progress}\n") if $timer == 0 next_empty = find_empty_field(map) found_solution(map) if not next_empty $piece_shapes.each_with_index do |dirs,ptype| next if map[6][ptype] == 0 dirs.each_with_index do |shape,pdir| shape.each { |c| try_piece(map, ptype, shape, next_empty[0]-c/10, next_empty[1]-c%10) } end end end def dump_solution(map) dump = [] 6.times{ |rowid| dump << map[rowid].collect{ |f| f ? (65+f).chr : "." }.join + "\n" } dump.join end def found_solution(map) $progress += 1 $stderr.print "---------------\n" + dump_solution(map) # exit end $progress = 0 $timer = 0 $solutions_to_try = [ empty_map ] while $solutions_to_try.length > 0 do try_solution($solutions_to_try.pop) end