advent_of_code/2024_4.rb
Code:
# Advent of Code 2024, Day 4: Ceres Search
# https://adventofcode.com/2024/day/4
require_relative './helpers.rb'
def part_one(d)
c = 0
d.size.times { |y|
d[0].size.times { |x|
next unless d[y][x] == 'X'
# Bounds
t, b, l, r = y - 3 >= 0, y + 3 < d.size, x - 3 >= 0, x + 3 < d[0].size
# Horizontal
c += ((0..3).map { |m| d[y][x - m] }.join == 'XMAS' ? 1 : 0) if l
c += ((0..3).map { |m| d[y][x + m] }.join == 'XMAS' ? 1 : 0) if r
# Vertical
c += ((0..3).map { |m| d[y - m][x] }.join == 'XMAS' ? 1 : 0) if t
c += ((0..3).map { |m| d[y + m][x] }.join == 'XMAS' ? 1 : 0) if b
# Diagonal
c += ((0..3).map { |m| d[y + m][x + m] }.join == 'XMAS' ? 1 : 0) if b & r
c += ((0..3).map { |m| d[y + m][x - m] }.join == 'XMAS' ? 1 : 0) if b & l
c += ((0..3).map { |m| d[y - m][x + m] }.join == 'XMAS' ? 1 : 0) if t & r
c += ((0..3).map { |m| d[y - m][x - m] }.join == 'XMAS' ? 1 : 0) if t & l
}
}
return c
end
def part_two(d)
c = 0
d.size.times { |y|
d[0].size.times { |x|
# Skip edges
next if (y == 0) | (x == 0) | (y == d.size - 1) | (x == d[0].size - 1)
# Skip words without A in center
next unless d[y][x] == 'A'
# Get vertices
v = [d[y - 1][x - 1], d[y - 1][x + 1], d[y + 1][x - 1], d[y + 1][x + 1]]
# Skip matching vertices like 'MAM' and 'SAS'
next if (v[0] == v[3]) | (v[1] == v[2])
# Increment
c += 1 if v.sort.join == 'MMSS'
}
}
return c
end
def solve(data)
data.map!(&:chars)
[part_one(data), part_two(data)]
end
puts solve(get_dataset(year: 2024, day: 4, type: 'example'))
puts solve(get_dataset(year: 2024, day: 4, type: 'example_2'))
puts solve(get_dataset(year: 2024, day: 4, type: 'input'))
Output:
18
9
0
0
2397
1824