advent_of_code/2024_12.rb
Code:
# Advent of Code 2024, Day 12: Garden Groups
# https://adventofcode.com/2024/day/12
require_relative './helpers.rb'
@seen = []
def crawl(grid, point)
@seen.include?(point) ? (return [[], 0]) : (@seen << point)
v, area, perimeter = get_grid(grid, point), [point], 0
[[1, 0], [-1, 0], [0, 1], [0, -1]].each do |x, y|
n_point = [point.x + x, point.y + y].to_p
if get_grid(grid, n_point) == v
crawl(grid, n_point).as { |a, p| area, perimeter = area + a, perimeter + p }
else
perimeter += 1
end
end
return [area, perimeter]
end
def part_one(regions)
regions.map { |area, perimeter| area.size * perimeter }.sum
end
def part_two(grid, regions)
regions.map { |area, _|
area.map { |point| [
[[ 0, -1], [-1, -1], [-1, 0]], [[-1, 0], [-1, 1], [ 0, 1]],
[[ 0, 1], [ 1, 1], [ 1, 0]], [[ 1, 0], [ 1, -1], [ 0, -1]],
].map { |c| c.map { |x, y| [point.x + x, point.y + y].to_p } }.map { |c|
c.map { |n| area.include?(n) }.as { |i, j, k| ((i == k) && (!i || !j)) ? 1 : 0 }
}.sum
}.sum * area.size
}.sum
end
def solve(data)
grid, regions = data.map { |l| l.chomp.chars }, []
draw_grid(grid) if grid.size < 20
grid.size.times do |y|
grid[0].size.times do |x|
regions << crawl(grid, [x, y].to_p) unless @seen.include?([x, y].to_p)
end
end
[part_one(regions), part_two(grid, regions)]
end
# puts solve(get_dataset(year: 2024, day: 12, type: 'example'))
# puts solve(get_dataset(year: 2024, day: 12, type: 'example_2'))
# puts solve(get_dataset(year: 2024, day: 12, type: 'example_3'))
puts solve(get_dataset(year: 2024, day: 12, type: 'example_4'))
# puts solve(get_dataset(year: 2024, day: 12, type: 'input'))
Output:
AAAAAA
AAABBA
AAABBA
ABBAAA
ABBAAA
AAAAAA
1184
368