Nim
Overall really simple puzzle, but description is so confusing, that I mostly solved it based on example diagrams.
Edit: much shorter and faster one-pass solution. Runtime: 132 us
type Vec2 = tuple[x,y: int]
func delta(a, b: Vec2): Vec2 = (a.x-b.x, a.y-b.y)
func outOfBounds[T: openarray | string](pos: Vec2, grid: seq[T]): bool =
pos.x < 0 or pos.y < 0 or pos.x > grid[0].high or pos.y > grid.high
proc solve(input: string): AOCSolution[int, int] =
var grid = input.splitLines()
var antennas: Table[char, seq[Vec2]]
for y, line in grid:
for x, c in line:
if c != '.':
discard antennas.hasKeyOrPut(c, newSeq[Vec2]())
antennas[c].add (x, y)
var antinodesP1: HashSet[Vec2]
var antinodesP2: HashSet[Vec2]
for _, list in antennas:
for ind, ant1 in list:
antinodesP2.incl ant1 # each antenna is antinode
for ant2 in list.toOpenArray(ind+1, list.high):
let d = delta(ant1, ant2)
for dir in [-1, 1]:
var i = dir
while true:
let antinode = (x: ant1.x+d.x*i, y: ant1.y+d.y*i)
if antinode.outOfBounds(grid): break
if i in [1, -2]: antinodesP1.incl antinode
antinodesP2.incl antinode
i += dir
result.part1 = antinodesP1.len
result.part2 = antinodesP2.len
Last year the difficulty was fluctuating from 0 to 100 each day.
This year all problems so far are suspiciously easy. Maybe the second half of the month will be extra hard?