Compare commits
4 Commits
c525fdc3d7
...
a35be7ec92
Author | SHA1 | Date | |
---|---|---|---|
a35be7ec92 | |||
cee23e5034 | |||
679e03217b | |||
402372f802 |
BIN
progress.png
BIN
progress.png
Binary file not shown.
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 119 KiB |
@ -14,3 +14,5 @@
|
||||
stars: 2
|
||||
8:
|
||||
stars: 2
|
||||
9:
|
||||
stars: 2
|
1
res/examples/day9_1.txt
Normal file
1
res/examples/day9_1.txt
Normal file
@ -0,0 +1 @@
|
||||
12345
|
1
res/examples/day9_2.txt
Normal file
1
res/examples/day9_2.txt
Normal file
@ -0,0 +1 @@
|
||||
2333133121414131402
|
152
src/day9/puzzle1.typ
Normal file
152
src/day9/puzzle1.typ
Normal 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
86
src/day9/puzzle2.typ
Normal 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)
|
BIN
src/main.pdf
BIN
src/main.pdf
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user