advent_of_code/2024_15.rb
Code:
# Advent of Code 2024, Day 15: Warehouse Woes
# https://adventofcode.com/2024/day/15
require_relative './helpers.rb'
class Obstacle
attr_accessor :type, :pos
def initialize(type, pos)
@type, @pos = type, pos
end
def try(g, d)
o = get_grid(g, [@pos.x + d.x, @pos.y + d.y].to_p)
return false if o.type == '#'
return true if o.type == '.'
return o.try(g, d) if o.type == 'O'
if o.type == '[' || o.type == ']'
return o.try(g, d) if d.y == 0
a = get_grid(g, [o.pos.x + (o.type == '[' ? 1 : -1), o.pos.y].to_p)
o.try(g, d) && a.try(g, d)
end
end
def move(g, d)
return unless try(g, d)
o = get_grid(g, [@pos.x + d.x, @pos.y + d.y].to_p)
o.move(g, d) if o.type == 'O'
if o.type == '[' || o.type == ']'
a = get_grid(g, [o.pos.x + (o.type == '[' ? 1 : -1), o.pos.y].to_p)
a.move(g, d) if d.x == 0
o.move(g, d)
end
o.type, @type = @type, '.'
end
end
def simulate(grid, steps)
grid.map!.with_index { |row, y| row.map.with_index { |cell, x| Obstacle.new(cell, [x, y].to_p) } }
r = grid.flatten.filter { |o| o.type == '@' }.compact.first
steps.each { |s| r = get_grid(grid, [r.pos.x + s.x, r.pos.y + s.y].to_p) if r.move(grid, s) }
grid.each { |r| r.each { |o| print o.type }; print "\n" } if grid.size < 20
return grid
end
def part_one(grid, steps)
simulate(grid, steps).flatten.sum { |o| o.type == 'O' ? (o.pos.x + o.pos.y * 100) : 0}
end
def part_two(grid, steps)
grid.map! { |r| r.map { |c| c == '@' ? '@.' : (c == 'O' ? '[]' : c * 2) }.join.chars }
simulate(grid, steps).flatten.sum { |o| o.type == '[' ? (o.pos.x + o.pos.y * 100) : 0}
end
def solve(data)
grid, steps = [], []
data.each { |l| '^>v<'.chars.include?(l[0]) ? (steps += l.chars) : (grid << l.chars) }
steps.map! { |s| { '>' => [1, 0], 'v' => [0, 1], '<' => [-1, 0], '^' => [0, -1] }[s].to_p }
[part_one(copy_grid(grid), steps), part_two(copy_grid(grid), steps)]
end
puts solve(get_dataset(year: 2024, day: 15, type: 'example'))
puts solve(get_dataset(year: 2024, day: 15, type: 'example_2'))
puts solve(get_dataset(year: 2024, day: 15, type: 'example_3'))
puts solve(get_dataset(year: 2024, day: 15, type: 'input'))
Output:
##########
#.O.O.OOO#
#........#
#OO......#
#OO@.....#
#O#.....O#
#O.....OO#
#O.....OO#
#OO....OO#
##########
####################
##[].......[].[][]##
##[]...........[].##
##[]........[][][]##
##[]......[]....[]##
##..##......[]....##
##..[]............##
##..@......[].[][]##
##......[][]..[]..##
####################
10092
9021
########
#....OO#
##.....#
#.....O#
#.#O@..#
#...O..#
#...O..#
########
################
##......[][]..##
####....[]....##
##......[]....##
##..##...[]...##
##....@.......##
##......[]....##
################
2028
1751
#######
#@..#.#
#.O...#
#..O..#
#..O..#
#.....#
#######
##############
##...[].##..##
##...@.[]...##
##....[]....##
##..........##
##..........##
##############
908
618
1318523
1337648