map = Array(Array(Array(Int32))).new(301) { |i| Array(Array(Int32)).new(301) { |j| Array(Int32).new(301, 0) } } pairs = (1..300).to_a.product (1..300).to_a (1..300).each do |y| (1..300).each do |x| rack_id = x + 10 level = rack_id * y level += 3463 level *= rack_id digit = (level / 100) % 10 digit -= 5 map[x][y][1] = digit end end def square_score(powers, coord, size) x, y = coord total = 0 half = size / 2 total = powers[x][y][half] + powers[x][y + half][half] + powers[x + half][y][half] + powers[x + half][y + half][half] if size.odd? size.times do |i| total += powers[x + size - 1][y + i][1] total += powers[x + i][y + size - 1][1] end total -= powers[x + size - 1][y + size - 1][1] end powers[x][y][size] = total return total end def max_score(powers, pairs, size = 3) possible_squares = (1..300 - size + 1).to_a possible_pairs = possible_squares.product possible_squares possible_pairs.max_by do |pair| x, y = pair score = square_score(powers, pair, size) end end puts max_score(map, pairs, 2) puts max_score(map, pairs, 3) max = -1000 max_pair = nil 297.times do |i| pair = max_score(map, pairs, i + 4) score = square_score(map, pair, i + 4) if score > max max = score max_pair = { pair, i + 4 } else break end end puts max_pair