68 lines
1.3 KiB
Typst
68 lines
1.3 KiB
Typst
#import "/src/utils.typ": *
|
|
|
|
#let offsets = (
|
|
(-1, 0),
|
|
(0, -1),
|
|
(1, 0),
|
|
(0, 1)
|
|
)
|
|
|
|
#let in-grid(w, h, x, y) = {
|
|
return 0 <= x and x < w and 0 <= y and y < h
|
|
}
|
|
|
|
#let solve(input) = {
|
|
let grid = input.split("\n").map(l => l.clusters())
|
|
let w = grid.first().len()
|
|
let h = grid.len()
|
|
let in-grid = in-grid.with(w, h)
|
|
|
|
let visited = ((false,) * w,) * h
|
|
let total = 0
|
|
|
|
for y in range(h) {
|
|
for x in range(w) {
|
|
if visited.at(y).at(x) {
|
|
continue
|
|
}
|
|
let char = grid.at(y).at(x)
|
|
let cells = ()
|
|
let borders = 0
|
|
let next-cells = ((x, y),)
|
|
while next-cells.len() != 0 {
|
|
let (cx, cy) = next-cells.remove(0)
|
|
cells.push((cx, cy))
|
|
visited.at(cy).at(cx) = true
|
|
for (dx, dy) in offsets {
|
|
let (x2, y2) = (cx + dx, cy + dy)
|
|
if (x2, y2) in cells or (x2, y2) in next-cells {
|
|
continue
|
|
}
|
|
if in-grid(x2, y2) {
|
|
let char2 = grid.at(y2).at(x2)
|
|
if char2 == char {
|
|
next-cells.push((x2, y2))
|
|
} else {
|
|
borders += 1
|
|
}
|
|
} else {
|
|
borders += 1
|
|
}
|
|
}
|
|
}
|
|
total += borders * cells.len()
|
|
}
|
|
}
|
|
|
|
return total
|
|
}
|
|
|
|
#show-puzzle(
|
|
12, 1,
|
|
solve,
|
|
example: (
|
|
"1": 140,
|
|
"2": 772,
|
|
"3": 1930
|
|
)
|
|
) |