173 lines
4.1 KiB
Ruby
173 lines
4.1 KiB
Ruby
map = {}
|
|
|
|
input = File.readlines('./input').map.with_index do |line, i|
|
|
line.chomp.chars.each_with_index { |char, pos| map[[pos, i, 0, 0]] = char }
|
|
end
|
|
|
|
def draw_bounds(map)
|
|
x = map.keys.map { |x, _, _, _| x }
|
|
y = map.keys.map { |_, y, _, _| y }
|
|
z = map.keys.map { |_, _, z, _| z }
|
|
w = map.keys.map { |_, _, _, w| w }
|
|
|
|
[x.min - 1, x.max + 1].each do |x|
|
|
(y.min - 1..y.max + 1).each do |y|
|
|
(z.min - 1..z.max + 1).each do |z|
|
|
(w.min - 1..w.max + 1).each do |w|
|
|
map[[x, y, z, w]] = '.'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
[y.min - 1, y.max + 1].each do |y|
|
|
(x.min - 1..x.max + 1).each do |x|
|
|
(z.min - 1..z.max + 1).each do |z|
|
|
(w.min - 1..w.max + 1).each do |w|
|
|
map[[x, y, z, w]] = '.'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
[z.min - 1, z.max + 1].each do |z|
|
|
(y.min - 1..y.max + 1).each do |y|
|
|
(x.min - 1..x.max + 1).each do |x|
|
|
(w.min - 1..w.max + 1).each do |w|
|
|
map[[x, y, z, w]] = '.'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
[w.min - 1, w.max + 1].each do |w|
|
|
(y.min - 1..y.max + 1).each do |y|
|
|
(x.min - 1..x.max + 1).each do |x|
|
|
(z.min - 1..z.max + 1).each do |z|
|
|
map[[x, y, z, w]] = '.'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
map
|
|
end
|
|
|
|
def surrounding_cords(cord)
|
|
x, y, z, w = cord
|
|
cords = [
|
|
[x, y, z, w - 1],
|
|
[x, y, z, w + 1],
|
|
|
|
# boottom
|
|
[x, y, z - 1, w],
|
|
[x - 1, y - 1, z - 1, w],
|
|
[x, y - 1, z - 1, w],
|
|
[x + 1, y - 1, z - 1, w],
|
|
[x - 1, y, z - 1, w],
|
|
[x + 1, y, z - 1, w],
|
|
[x - 1, y + 1, z - 1, w],
|
|
[x, y + 1, z - 1, w],
|
|
[x + 1, y + 1, z - 1, w],
|
|
# top
|
|
[x, y, z + 1, w],
|
|
[x - 1, y - 1, z + 1, w],
|
|
[x, y - 1, z + 1, w],
|
|
[x + 1, y - 1, z + 1, w],
|
|
[x - 1, y, z + 1, w],
|
|
[x + 1, y, z + 1, w],
|
|
[x - 1, y + 1, z + 1, w],
|
|
[x, y + 1, z + 1, w],
|
|
[x + 1, y + 1, z + 1, w],
|
|
# middle
|
|
[x - 1, y - 1, z, w],
|
|
[x, y - 1, z, w],
|
|
[x + 1, y - 1, z, w],
|
|
[x - 1, y, z, w],
|
|
[x + 1, y, z, w],
|
|
[x - 1, y + 1, z, w],
|
|
[x, y + 1, z, w],
|
|
[x + 1, y + 1, z, w],
|
|
|
|
[x, y, z - 1, w - 1],
|
|
[x - 1, y - 1, z - 1, w - 1],
|
|
[x, y - 1, z - 1, w - 1],
|
|
[x + 1, y - 1, z - 1, w - 1],
|
|
[x - 1, y, z - 1, w - 1],
|
|
[x + 1, y, z - 1, w - 1],
|
|
[x - 1, y + 1, z - 1, w - 1],
|
|
[x, y + 1, z - 1, w - 1],
|
|
[x + 1, y + 1, z - 1, w - 1],
|
|
# top
|
|
[x, y, z + 1, w - 1],
|
|
[x - 1, y - 1, z + 1, w - 1],
|
|
[x, y - 1, z + 1, w - 1],
|
|
[x + 1, y - 1, z + 1, w - 1],
|
|
[x - 1, y, z + 1, w - 1],
|
|
[x + 1, y, z + 1, w - 1],
|
|
[x - 1, y + 1, z + 1, w - 1],
|
|
[x, y + 1, z + 1, w - 1],
|
|
[x + 1, y + 1, z + 1, w - 1],
|
|
# middle
|
|
[x - 1, y - 1, z, w - 1],
|
|
[x, y - 1, z, w - 1],
|
|
[x + 1, y - 1, z, w - 1],
|
|
[x - 1, y, z, w - 1],
|
|
[x + 1, y, z, w - 1],
|
|
[x - 1, y + 1, z, w - 1],
|
|
[x, y + 1, z, w - 1],
|
|
[x + 1, y + 1, z, w - 1],
|
|
|
|
[x, y, z - 1, w + 1],
|
|
[x - 1, y - 1, z - 1, w + 1],
|
|
[x, y - 1, z - 1, w + 1],
|
|
[x + 1, y - 1, z - 1, w + 1],
|
|
[x - 1, y, z - 1, w + 1],
|
|
[x + 1, y, z - 1, w + 1],
|
|
[x - 1, y + 1, z - 1, w + 1],
|
|
[x, y + 1, z - 1, w + 1],
|
|
[x + 1, y + 1, z - 1, w + 1],
|
|
# top
|
|
[x, y, z + 1, w + 1],
|
|
[x - 1, y - 1, z + 1, w + 1],
|
|
[x, y - 1, z + 1, w + 1],
|
|
[x + 1, y - 1, z + 1, w + 1],
|
|
[x - 1, y, z + 1, w + 1],
|
|
[x + 1, y, z + 1, w + 1],
|
|
[x - 1, y + 1, z + 1, w + 1],
|
|
[x, y + 1, z + 1, w + 1],
|
|
[x + 1, y + 1, z + 1, w + 1],
|
|
# middle
|
|
[x - 1, y - 1, z, w + 1],
|
|
[x, y - 1, z, w + 1],
|
|
[x + 1, y - 1, z, w + 1],
|
|
[x - 1, y, z, w + 1],
|
|
[x + 1, y, z, w + 1],
|
|
[x - 1, y + 1, z, w + 1],
|
|
[x, y + 1, z, w + 1],
|
|
[x + 1, y + 1, z, w + 1]
|
|
]
|
|
end
|
|
|
|
def cycle(map)
|
|
new_map = {}
|
|
map.each do |cord, _state|
|
|
neighbours_active = surrounding_cords(cord).map { |cord| map[cord] == '#' }.count(true)
|
|
|
|
if map[cord] == '#' && (2..3).include?(neighbours_active) ||
|
|
map[cord] == '.' && neighbours_active == 3
|
|
new_map[cord] = '#'; next
|
|
else
|
|
new_map[cord] = '.'
|
|
end
|
|
end
|
|
new_map
|
|
end
|
|
|
|
6.times do
|
|
map = draw_bounds(map)
|
|
map = cycle(map)
|
|
end
|
|
|
|
puts map.values.count('#')
|