Created
December 11, 2021 05:46
-
-
Save sarahzrf/1ac2bac7104d1ae4521c77cbf9860f52 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
require 'set' | |
class Octopus | |
def initialize(cave, x, y) | |
@cave = cave | |
@x = x | |
@y = y | |
end | |
attr_reader :x, :y | |
def energy | |
@cave.energy_at(x, y) | |
end | |
def energy=(n) | |
@cave.set_energy_at(x, y, n) | |
end | |
def flashed? | |
@cave.flashed_at?(x, y) | |
end | |
def flashed=(b) | |
@cave.set_flashed_at(x, y, b) | |
end | |
def neighbors | |
@cave.neighbors_at(x, y) | |
end | |
end | |
class Cave | |
def initialize(energies) | |
@energies = energies | |
@flashed = energies.map {|row| row.map {false}} | |
@height = energies.length | |
@width = energies[0].length | |
@to_flash = Set.new | |
@total_flashes = 0 | |
end | |
attr_reader :width, :height, :total_flashes | |
def in_bounds?(x, y) | |
x >= 0 && y >= 0 && x < width && y < height | |
end | |
def [](x, y) | |
Octopus.new(self, x, y) if in_bounds?(x, y) | |
end | |
def energy_at(x, y) | |
@energies[y][x] | |
end | |
def set_energy_at(x, y, n) | |
@energies[y][x] = n | |
@to_flash << [x, y] if n > 9 and not flashed_at?(x, y) | |
end | |
def flashed_at?(x, y) | |
@flashed[y][x] | |
end | |
def set_flashed_at(x, y, b) | |
@flashed[y][x] = b | |
end | |
Offsets = [ | |
[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1] | |
] | |
def neighbors_at(x, y) | |
Offsets.map {|dx, dy| self[x + dx, y + dy]}.compact | |
end | |
def start_step | |
(0...height).each do |y| | |
(0...width).each do |x| | |
self[x, y].energy += 1 | |
end | |
end | |
end | |
def step_done? | |
@to_flash.empty? | |
end | |
def do_flashes | |
old = @to_flash | |
old.each do |x, y| | |
self[x, y].flashed = true | |
@total_flashes += 1 | |
end | |
@to_flash = Set.new | |
old.each do |x, y| | |
self[x, y].neighbors.each do |n| | |
n.energy += 1 | |
end | |
end | |
end | |
def reset_flashes | |
@flashed.each {|row| row.map! {false}} | |
end | |
def finish_step | |
@flashed.each_with_index do |row, y| | |
row.each_with_index do |fl, x| | |
self[x, y].energy = 0 if fl | |
end | |
end | |
reset_flashes | |
end | |
def step | |
start_step | |
do_flashes until step_done? | |
finish_step | |
end | |
end | |
cave = Cave.new($<.map {|l| l.chomp.chars.map(&:to_i)}) | |
100.times {cave.step} | |
print cave.total_flashes | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment