Compare commits

...

4 Commits

Author SHA1 Message Date
a35be7ec92
added visualization for day 9 puzzle 2 2024-12-09 20:45:58 +01:00
cee23e5034
added visualization for day 9 puzzle 1 2024-12-09 20:35:35 +01:00
679e03217b
day 9 puzzle 2 2024-12-09 18:53:35 +01:00
402372f802
day 9 puzzle 1 2024-12-09 18:42:21 +01:00
7 changed files with 242 additions and 0 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 119 KiB

View File

@ -13,4 +13,6 @@
7: 7:
stars: 2 stars: 2
8: 8:
stars: 2
9:
stars: 2 stars: 2

1
res/examples/day9_1.txt Normal file
View File

@ -0,0 +1 @@
12345

1
res/examples/day9_2.txt Normal file
View File

@ -0,0 +1 @@
2333133121414131402

152
src/day9/puzzle1.typ Normal file
View File

@ -0,0 +1,152 @@
#import "/src/utils.typ": *
#let parse-input(input) = {
let blocks = ()
let holes = ()
let block-i = 0
let is-block = true
let pos = 0
for c in input {
let block = (pos, int(c))
if is-block {
block.push(block-i)
block-i += 1
blocks.push(block)
} else {
holes.push(block)
}
pos += int(c)
is-block = not is-block
}
return (blocks, holes)
}
#let compute-checksum(blocks) = {
let total = 0
for (i0, l, id) in blocks {
total += id * range(i0, i0 + l).sum()
}
return total
}
#let insert(list, elmt) = {
for (i, elmt2) in list.enumerate() {
if elmt.first() < elmt2.first() {
list.insert(i, elmt)
return list
}
}
list.push(elmt)
return list
}
#let solve(input) = {
let (blocks, holes) = parse-input(input)
for (hi, hl) in holes {
while hl > 0 {
if blocks.last().first() < hi + hl {
break
}
let (bi, bl, bid) = blocks.pop()
let len = calc.min(hl, bl)
blocks.insert(0, (hi, len, bid))
if len < bl {
blocks = insert(blocks, (bi, bl - len, bid))
}
hl -= len
hi += len
}
if hl > 0 {
break
}
}
return compute-checksum(blocks)
}
#let col-gradient = gradient.linear(red, orange, yellow, green, aqua, blue, purple)
#let show-fs(size, max-id, blocks) = {
let cells = ()
for (bi, bl, bid) in blocks {
cells.push(
grid.cell(
x: bi,
colspan: bl,
fill: col-gradient.sample(bid * 100% / max-id),
str(bid)
)
)
}
grid(
columns: (1fr,) * size,
align: center + horizon,
stroke: black,
inset: 0.3em,
..cells
)
}
#let visualize(input) = {
let (blocks, holes) = parse-input(input)
let max-id = blocks.last().last()
let last-block = blocks.last()
let last-holes = holes.last()
let show-fs = show-fs.with(
calc.max(
last-block.first() + last-block.at(1),
last-holes.first() + last-holes.last()
),
max-id
)
let steps = ()
steps.push(show-fs(blocks))
for (hi, hl) in holes {
while hl > 0 {
if blocks.last().first() < hi + hl {
break
}
let (bi, bl, bid) = blocks.pop()
let len = calc.min(hl, bl)
blocks.insert(0, (hi, len, bid))
if len < bl {
blocks = insert(blocks, (bi, bl - len, bid))
}
hl -= len
hi += len
}
if hl > 0 {
break
}
steps.push(show-fs(blocks))
}
stack(
spacing: 0.5em,
..steps
)
}
#show-puzzle(
9, 1,
solve,
example: (
"1": 60,
"2": 1928
),
only-example: true,
visualize: visualize
)
// Too long to recompile everytime
#show-result(6390180901651)

86
src/day9/puzzle2.typ Normal file
View File

@ -0,0 +1,86 @@
#import "/src/utils.typ": *
#import "puzzle1.typ": parse-input, compute-checksum, insert, show-fs
#let solve(input) = {
let (blocks, holes) = parse-input(input)
let blocks2 = ()
for (bi, bl, bid) in blocks.rev() {
for (i, (hi, hl)) in holes.enumerate() {
if hi < bi and bl <= hl {
bi = hi
holes.at(i).first() += bl
holes.at(i).last() -= bl
if bl == hl {
holes.remove(i)
}
break
}
}
blocks2.push((bi, bl, bid))
}
return compute-checksum(blocks2)
}
#let visualize(input) = {
let (blocks, holes) = parse-input(input)
let max-id = blocks.last().last()
let last-block = blocks.last()
let last-holes = holes.last()
let show-fs = show-fs.with(
calc.max(
last-block.first() + last-block.at(1),
last-holes.first() + last-holes.last()
),
max-id
)
let steps = ()
steps.push(show-fs(blocks))
let ids = ()
let blocks2 = ()
for (bi, bl, bid) in blocks.rev() {
let moved = false
for (i, (hi, hl)) in holes.enumerate() {
if hi < bi and bl <= hl {
bi = hi
holes.at(i).first() += bl
holes.at(i).last() -= bl
if bl == hl {
_ = holes.remove(i)
}
moved = true
break
}
}
ids.push(bid)
blocks2.push((bi, bl, bid))
if moved {
steps.push(show-fs(
blocks.filter(b => b.last() not in ids) +
blocks2
))
}
}
stack(
spacing: 0.5em,
..steps
)
}
#show-puzzle(
9, 2,
solve,
example: (
"1": 132,
"2": 2858
),
only-example: true,
visualize: visualize
)
// Too long to recompile everytime
#show-result(6412390114238)

Binary file not shown.