1
0
Fork 0
advent-of-code-2024/14/main.rb
2024-12-14 15:17:34 -05:00

109 lines
2.1 KiB
Ruby
Executable file

#!/usr/bin/env ruby
require "debug"
require "ostruct"
MOVES = 100
input = (if ARGV.first.nil?
WIDTH = 11
HEIGHT = 7
DATA
else
WIDTH = 101
HEIGHT = 103
ARGF
end)
def print_grid(grid)
grid.each_with_index do |row, y|
row.each_with_index do |val, x|
if val.size > 0
print grid[y][x].size
elsif x == WIDTH / 2 || y == HEIGHT / 2
print " "
else
print " "
end
end
puts
end
puts
puts
end
def move(grid, ticks = 1)
new_grid = Array.new(HEIGHT) { Array.new(WIDTH) { Array.new } }
grid.each_with_index do |row, y|
row.each_with_index do |val, x|
movements = val.map do |robot|
new_x = (x + robot.first * ticks) % WIDTH
new_y = (y + robot.last * ticks) % HEIGHT
new_grid[new_y][new_x] << robot
end
end
end
new_grid
end
def safety_factor(grid)
[
[[0, 0], [HEIGHT / 2 - 1, WIDTH / 2 - 1]],
[[0, WIDTH / 2 + 1], [HEIGHT / 2 - 1, WIDTH - 1]],
[[HEIGHT / 2 + 1, 0], [HEIGHT - 1, WIDTH / 2 - 1]],
[[HEIGHT / 2 + 1, WIDTH / 2 + 1], [HEIGHT - 1, WIDTH - 1]],
].map do |(top_left, bottom_right)|
(top_left.first..bottom_right.first).map do |y|
(top_left.last..bottom_right.last).map do |x|
grid[y][x].size
end.sum
end.sum
end.inject(:*)
end
def count_top(grid)
(0...HEIGHT / 2).map do |y|
grid[y].select { !_1.empty? }.size
end.sum
end
grid = Array.new(HEIGHT) { Array.new(WIDTH) { Array.new } }
input = input.readlines(chomp: true)
.map do |line|
x, y, vx, vy = line.scan(/(-?\d+)/).flatten.map(&:to_i)
grid[y][x] << [vx, vy]
end
new_grid = move(grid.clone.map(&:clone), MOVES)
part_1 = safety_factor(new_grid)
new_grid = grid.dup.map(&:dup)
candidates = (WIDTH * HEIGHT).times.map.with_index do |moves|
new_grid = move(new_grid)
[moves + 1, safety_factor(new_grid)]
end.sort_by(&:last)
part_2 = candidates.first.first
print_grid(move(grid, candidates.first.first))
p part_1
p part_2
__END__
p=0,4 v=3,-3
p=6,3 v=-1,-3
p=10,3 v=-1,2
p=2,0 v=2,-1
p=0,0 v=1,3
p=3,0 v=-2,-2
p=7,6 v=-1,-3
p=3,0 v=-1,-2
p=9,3 v=2,3
p=7,3 v=-1,2
p=2,4 v=2,-3
p=9,5 v=-3,-3