Compare commits
5 Commits
dd1e8a81fd
...
953716b95a
Author | SHA1 | Date | |
---|---|---|---|
953716b95a | |||
43c6d9e325 | |||
927feb071e | |||
5107cf7f82 | |||
9a7eef5186 |
BIN
progress.png
BIN
progress.png
Binary file not shown.
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 129 KiB |
@ -27,4 +27,10 @@
|
|||||||
14:
|
14:
|
||||||
stars: 2
|
stars: 2
|
||||||
15:
|
15:
|
||||||
|
stars: 2
|
||||||
|
16:
|
||||||
|
stars: 0
|
||||||
|
17:
|
||||||
|
stars: 1
|
||||||
|
18:
|
||||||
stars: 2
|
stars: 2
|
15
res/examples/day16_1.txt
Normal file
15
res/examples/day16_1.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
###############
|
||||||
|
#.......#....E#
|
||||||
|
#.#.###.#.###.#
|
||||||
|
#.....#.#...#.#
|
||||||
|
#.###.#####.#.#
|
||||||
|
#.#.#.......#.#
|
||||||
|
#.#.#####.###.#
|
||||||
|
#...........#.#
|
||||||
|
###.#.#####.#.#
|
||||||
|
#...#.....#.#.#
|
||||||
|
#.#.#.###.#.#.#
|
||||||
|
#.....#...#.#.#
|
||||||
|
#.###.#.#.#.#.#
|
||||||
|
#S..#.....#...#
|
||||||
|
###############
|
17
res/examples/day16_2.txt
Normal file
17
res/examples/day16_2.txt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#################
|
||||||
|
#...#...#...#..E#
|
||||||
|
#.#.#.#.#.#.#.#.#
|
||||||
|
#.#.#.#...#...#.#
|
||||||
|
#.#.#.#.###.#.#.#
|
||||||
|
#...#.#.#.....#.#
|
||||||
|
#.#.#.#.#.#####.#
|
||||||
|
#.#...#.#.#.....#
|
||||||
|
#.#.#####.#.###.#
|
||||||
|
#.#.#.......#...#
|
||||||
|
#.#.###.#####.###
|
||||||
|
#.#.#...#.....#.#
|
||||||
|
#.#.#.#####.###.#
|
||||||
|
#.#.#.........#.#
|
||||||
|
#.#.#.#########.#
|
||||||
|
#S#.............#
|
||||||
|
#################
|
5
res/examples/day17_1.txt
Normal file
5
res/examples/day17_1.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Register A: 729
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,1,5,4,3,0
|
5
res/examples/day17_2.txt
Normal file
5
res/examples/day17_2.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Register A: 2024
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0
|
25
res/examples/day18.txt
Normal file
25
res/examples/day18.txt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
5,4
|
||||||
|
4,2
|
||||||
|
4,5
|
||||||
|
3,0
|
||||||
|
2,1
|
||||||
|
6,3
|
||||||
|
2,4
|
||||||
|
1,5
|
||||||
|
0,6
|
||||||
|
3,3
|
||||||
|
2,6
|
||||||
|
5,1
|
||||||
|
1,2
|
||||||
|
5,5
|
||||||
|
2,5
|
||||||
|
6,5
|
||||||
|
1,4
|
||||||
|
0,4
|
||||||
|
6,4
|
||||||
|
1,1
|
||||||
|
6,1
|
||||||
|
1,0
|
||||||
|
0,5
|
||||||
|
1,6
|
||||||
|
2,0
|
67
src/day16/puzzle1.typ
Normal file
67
src/day16/puzzle1.typ
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#import "/src/utils.typ": *
|
||||||
|
|
||||||
|
#let START = "S"
|
||||||
|
#let END = "E"
|
||||||
|
#let WALL = "#"
|
||||||
|
#let EMPTY = "."
|
||||||
|
|
||||||
|
#let offsets = (
|
||||||
|
(1, 0),
|
||||||
|
(0, 1),
|
||||||
|
(-1, 0),
|
||||||
|
(0, -1)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let solve(input) = {
|
||||||
|
let grid = input.split("\n").map(l => l.clusters())
|
||||||
|
let w = grid.first().len()
|
||||||
|
let h = grid.len()
|
||||||
|
|
||||||
|
let (sx, sy) = (0, 0)
|
||||||
|
let (ex, ey) = (0, 0)
|
||||||
|
for y in range(h) {
|
||||||
|
for x in range(w) {
|
||||||
|
let c = grid.at(y).at(x)
|
||||||
|
if c == START {
|
||||||
|
(sx, sy) = (x, y)
|
||||||
|
} else if c == END {
|
||||||
|
(ex, ey) = (x, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let choices = ((sx, sy, 0, 0),)
|
||||||
|
let (x, y, dir, score) = (0, 0, 0, 0)
|
||||||
|
while choices.len() != 0 {
|
||||||
|
let min-score = calc.min(..choices.map(c => c.last()))
|
||||||
|
let i = choices.position(c => c.last() == min-score)
|
||||||
|
(x, y, dir, score) = choices.remove(i)
|
||||||
|
for (d, (dx, dy)) in offsets.enumerate() {
|
||||||
|
// Ignore backflips
|
||||||
|
if calc.abs(d - dir) == 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let (x2, y2) = (x + dx, y + dy)
|
||||||
|
let c = grid.at(y2).at(x2)
|
||||||
|
if c == WALL {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let score2 = score + 1 + if d != dir {1000} else {0}
|
||||||
|
if c == END {
|
||||||
|
return score2
|
||||||
|
}
|
||||||
|
choices.push((x2, y2, d, score2))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#show-puzzle(
|
||||||
|
16, 1,
|
||||||
|
solve,
|
||||||
|
example: (
|
||||||
|
"1": 7036,
|
||||||
|
"2": 11048
|
||||||
|
)
|
||||||
|
)
|
0
src/day16/puzzle2.typ
Normal file
0
src/day16/puzzle2.typ
Normal file
87
src/day17/puzzle1.typ
Normal file
87
src/day17/puzzle1.typ
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#import "/src/utils.typ": *
|
||||||
|
|
||||||
|
#let ADV = 0
|
||||||
|
#let BXL = 1
|
||||||
|
#let BST = 2
|
||||||
|
#let JNZ = 3
|
||||||
|
#let BXC = 4
|
||||||
|
#let OUT = 5
|
||||||
|
#let BDV = 6
|
||||||
|
#let CDV = 7
|
||||||
|
|
||||||
|
#let get-combo(regs, value) = {
|
||||||
|
if value >= 7 {
|
||||||
|
panic()
|
||||||
|
}
|
||||||
|
if value <= 3 {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return regs.at(value - 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let solve(input) = {
|
||||||
|
let (registers, program) = input.split("\n\n")
|
||||||
|
|
||||||
|
let regs = ()
|
||||||
|
for line in registers.split("\n") {
|
||||||
|
regs.push(
|
||||||
|
int(
|
||||||
|
line.split(": ")
|
||||||
|
.last()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
program = program.split(": ")
|
||||||
|
.last()
|
||||||
|
.split(",")
|
||||||
|
.map(int)
|
||||||
|
|
||||||
|
let out = ()
|
||||||
|
let pc = 0
|
||||||
|
while pc < program.len() {
|
||||||
|
let op = program.at(pc)
|
||||||
|
let val = program.at(pc + 1)
|
||||||
|
if op == ADV {
|
||||||
|
let num = regs.at(0)
|
||||||
|
let den = get-combo(regs, val)
|
||||||
|
let res = num.bit-rshift(den)
|
||||||
|
regs.at(0) = res
|
||||||
|
} else if op == BXL {
|
||||||
|
regs.at(1) = regs.at(1).bit-xor(val)
|
||||||
|
} else if op == BST {
|
||||||
|
regs.at(1) = get-combo(regs, val).bit-and(0b111)
|
||||||
|
} else if op == JNZ {
|
||||||
|
if regs.at(0) != 0 {
|
||||||
|
pc = val
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if op == BXC {
|
||||||
|
regs.at(1) = regs.at(1).bit-xor(regs.at(2))
|
||||||
|
} else if op == OUT {
|
||||||
|
out.push(get-combo(regs, val).bit-and(0b111))
|
||||||
|
} else if op == BDV {
|
||||||
|
let num = regs.at(0)
|
||||||
|
let den = get-combo(regs, val)
|
||||||
|
let res = num.bit-rshift(den)
|
||||||
|
regs.at(1) = res
|
||||||
|
} else if op == CDV {
|
||||||
|
let num = regs.at(0)
|
||||||
|
let den = get-combo(regs, val)
|
||||||
|
let res = num.bit-rshift(den)
|
||||||
|
regs.at(2) = res
|
||||||
|
} else {
|
||||||
|
panic("Unknown instruction " + str(op))
|
||||||
|
}
|
||||||
|
pc += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.map(str).join(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
#show-puzzle(
|
||||||
|
17, 1,
|
||||||
|
solve,
|
||||||
|
example: (
|
||||||
|
"1": "4,6,3,5,6,3,5,2,1,0"
|
||||||
|
)
|
||||||
|
)
|
108
src/day17/puzzle2.typ
Normal file
108
src/day17/puzzle2.typ
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#import "/src/utils.typ": *
|
||||||
|
|
||||||
|
#let ADV = 0
|
||||||
|
#let BXL = 1
|
||||||
|
#let BST = 2
|
||||||
|
#let JNZ = 3
|
||||||
|
#let BXC = 4
|
||||||
|
#let OUT = 5
|
||||||
|
#let BDV = 6
|
||||||
|
#let CDV = 7
|
||||||
|
|
||||||
|
#let ops = ("ADV", "BXL", "BST", "JNZ", "BXC", "OUT", "BDV", "CDV")
|
||||||
|
|
||||||
|
#let get-combo(regs, value) = {
|
||||||
|
if value >= 7 {
|
||||||
|
panic()
|
||||||
|
}
|
||||||
|
if value <= 3 {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return regs.at(value - 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let describe-combo(value) = {
|
||||||
|
if value == 7 {
|
||||||
|
return "<invalid>"
|
||||||
|
}
|
||||||
|
if value <= 3 {
|
||||||
|
return str(value)
|
||||||
|
}
|
||||||
|
return "ABC".at(value - 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let describe(program) = {
|
||||||
|
let res = ""
|
||||||
|
res += program.map(str).join(",")
|
||||||
|
|
||||||
|
for i in range(0, program.len(), step: 2) {
|
||||||
|
res += "\n"
|
||||||
|
let op = program.at(i)
|
||||||
|
let val = program.at(i + 1)
|
||||||
|
let combo = describe-combo(val)
|
||||||
|
|
||||||
|
res += ops.at(op) + ": "
|
||||||
|
if op == ADV {
|
||||||
|
res += "A >>= " + combo
|
||||||
|
} else if op == BXL {
|
||||||
|
res += "B ^= " + str(val)
|
||||||
|
} else if op == BST {
|
||||||
|
res += "B = " + combo + " & 0b111"
|
||||||
|
} else if op == JNZ {
|
||||||
|
res += "IF A != 0 {PC = " + str(val) + "}"
|
||||||
|
} else if op == BXC {
|
||||||
|
res += "B ^= C"
|
||||||
|
} else if op == OUT {
|
||||||
|
res += "OUT(" + combo + " & 0b111)"
|
||||||
|
} else if op == BDV {
|
||||||
|
res += "B = A >> " + combo
|
||||||
|
} else if op == CDV {
|
||||||
|
res += "C = A >> " + combo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
#let solve(input) = {
|
||||||
|
let (registers, program) = input.split("\n\n")
|
||||||
|
|
||||||
|
let regs = ()
|
||||||
|
for line in registers.split("\n") {
|
||||||
|
regs.push(
|
||||||
|
int(
|
||||||
|
line.split(": ")
|
||||||
|
.last()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
program = program.split(": ")
|
||||||
|
.last()
|
||||||
|
.split(",")
|
||||||
|
.map(int)
|
||||||
|
|
||||||
|
let out = ()
|
||||||
|
let pc = 0
|
||||||
|
|
||||||
|
regs.first() = 0
|
||||||
|
|
||||||
|
for n in program {
|
||||||
|
let b = n
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw(block: true, describe(program))
|
||||||
|
}
|
||||||
|
|
||||||
|
Example:
|
||||||
|
#solve(read(get-example-path(17, suffix: "2")))
|
||||||
|
|
||||||
|
Input:
|
||||||
|
#solve(get-input(17))
|
||||||
|
|
||||||
|
/*
|
||||||
|
#show-puzzle(
|
||||||
|
17, 2,
|
||||||
|
solve,
|
||||||
|
example: (
|
||||||
|
"2": 117440
|
||||||
|
)
|
||||||
|
)*/
|
143
src/day18/puzzle1.typ
Normal file
143
src/day18/puzzle1.typ
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#import "/src/utils.typ": *
|
||||||
|
|
||||||
|
#let offsets = (
|
||||||
|
(1, 0),
|
||||||
|
(0, 1),
|
||||||
|
(-1, 0),
|
||||||
|
(0, -1)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let get-lowest(nodes, scores) = {
|
||||||
|
let lowest-score = none
|
||||||
|
let lowest-i = none
|
||||||
|
for (i, (x, y)) in nodes.enumerate() {
|
||||||
|
let score = scores.at(y).at(x)
|
||||||
|
|
||||||
|
if lowest-i == none or score < lowest-score {
|
||||||
|
lowest-score = score
|
||||||
|
lowest-i = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if lowest-i == none {
|
||||||
|
panic()
|
||||||
|
}
|
||||||
|
return lowest-i
|
||||||
|
}
|
||||||
|
|
||||||
|
#let make-path(parents, end) = {
|
||||||
|
let path = (end,)
|
||||||
|
let (x, y) = end
|
||||||
|
let pos = parents.at(y).at(x)
|
||||||
|
while pos != none {
|
||||||
|
(x, y) = pos
|
||||||
|
path.insert(0, pos)
|
||||||
|
pos = parents.at(y).at(x)
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
#let find-path(w, h, grid) = {
|
||||||
|
let end = (w - 1, h - 1)
|
||||||
|
let (x, y) = (0, 0)
|
||||||
|
let open = ((x, y),)
|
||||||
|
let closed = ()
|
||||||
|
let g-scores = ((0,) * w,) * h
|
||||||
|
let f-scores = ((calc.inf,) * w,) * h
|
||||||
|
let parents = ((none,)*w,)*h
|
||||||
|
while open.len() != 0 {
|
||||||
|
let cur = open.remove(get-lowest(open, f-scores))
|
||||||
|
|
||||||
|
if cur == end {
|
||||||
|
return make-path(parents, cur)
|
||||||
|
}
|
||||||
|
|
||||||
|
let g-score = g-scores.at(y).at(x)
|
||||||
|
let f-score = f-scores.at(y).at(x)
|
||||||
|
|
||||||
|
let (x, y) = cur
|
||||||
|
for (dx, dy) in offsets {
|
||||||
|
let (x2, y2) = (x + dx, y + dy)
|
||||||
|
if x2 < 0 or x2 >= w or y2 < 0 or y2 >= h {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if grid.at(y2).at(x2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (x2, y2) in closed {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let g = x2 + y2
|
||||||
|
let h = calc.abs(end.first() - x2) + calc.abs(end.last() - y2)
|
||||||
|
let f = g + h
|
||||||
|
|
||||||
|
if f < f-scores.at(y2).at(x2) {
|
||||||
|
g-scores.at(y2).at(x2) = g
|
||||||
|
f-scores.at(y2).at(x2) = f
|
||||||
|
parents.at(y2).at(x2) = (x, y)
|
||||||
|
open.push((x2, y2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closed.push(cur)
|
||||||
|
}
|
||||||
|
panic("No path was found")
|
||||||
|
}
|
||||||
|
|
||||||
|
#let solve(input, w: 0, h: 0, n-bytes: 0) = {
|
||||||
|
assert(w != 0, message: "Width cannot be 0")
|
||||||
|
assert(h != 0, message: "Height cannot be 0")
|
||||||
|
let grid = ((false,) * w,) * h
|
||||||
|
|
||||||
|
let obstacles = input.split("\n")
|
||||||
|
for obs in obstacles.slice(0, n-bytes) {
|
||||||
|
let (x, y) = obs.split(",").map(int)
|
||||||
|
grid.at(y).at(x) = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = find-path(w, h, grid)
|
||||||
|
return path.len() - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#let visualize(input, w: 0, h: 0, n-bytes: 0, s: 2em) = {
|
||||||
|
let grid_ = ((false,) * w,) * h
|
||||||
|
|
||||||
|
let obstacles = input.split("\n")
|
||||||
|
for obs in obstacles.slice(0, n-bytes) {
|
||||||
|
let (x, y) = obs.split(",").map(int)
|
||||||
|
grid_.at(y).at(x) = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = find-path(w, h, grid_)
|
||||||
|
for (x, y) in path {
|
||||||
|
grid_.at(y).at(x) = grid.cell(fill: green.lighten(60%))[O]
|
||||||
|
}
|
||||||
|
|
||||||
|
let cells = grid_.flatten().map(c => {
|
||||||
|
if c == false []
|
||||||
|
else if c == true {grid.cell(fill: red.lighten(60%))[\#]}
|
||||||
|
else {c}
|
||||||
|
})
|
||||||
|
|
||||||
|
grid(
|
||||||
|
columns: (s,) * w,
|
||||||
|
rows: (s,) * h,
|
||||||
|
align: center + horizon,
|
||||||
|
stroke: black,
|
||||||
|
..cells
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#show-puzzle(
|
||||||
|
18, 1,
|
||||||
|
solve.with(w: 71, h: 71, n-bytes: 1024),
|
||||||
|
example: (
|
||||||
|
(result: 22, args: (w: 7, h: 7, n-bytes: 12)),
|
||||||
|
),
|
||||||
|
visualize: visualize.with(w: 7, h: 7, n-bytes: 12)
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#pagebreak()
|
||||||
|
#set page(width: auto, height: auto)
|
||||||
|
#visualize(get-input(18), w: 71, h: 71, n-bytes: 1024, s: 1em)
|
||||||
|
*/
|
117
src/day18/puzzle2.typ
Normal file
117
src/day18/puzzle2.typ
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#import "/src/utils.typ": *
|
||||||
|
#let offsets = (
|
||||||
|
(1, 0),
|
||||||
|
(0, 1),
|
||||||
|
(-1, 0),
|
||||||
|
(0, -1)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let get-lowest(nodes, scores) = {
|
||||||
|
let lowest-score = none
|
||||||
|
let lowest-i = none
|
||||||
|
for (i, (x, y)) in nodes.enumerate() {
|
||||||
|
let score = scores.at(y).at(x)
|
||||||
|
|
||||||
|
if lowest-i == none or score < lowest-score {
|
||||||
|
lowest-score = score
|
||||||
|
lowest-i = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if lowest-i == none {
|
||||||
|
panic()
|
||||||
|
}
|
||||||
|
return lowest-i
|
||||||
|
}
|
||||||
|
|
||||||
|
#let make-path(parents, end) = {
|
||||||
|
let path = (end,)
|
||||||
|
let (x, y) = end
|
||||||
|
let pos = parents.at(y).at(x)
|
||||||
|
while pos != none {
|
||||||
|
(x, y) = pos
|
||||||
|
path.insert(0, pos)
|
||||||
|
pos = parents.at(y).at(x)
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
#let find-path(w, h, grid, start: (0, 0), end: auto) = {
|
||||||
|
let end = if end == auto {(w - 1, h - 1)} else {end}
|
||||||
|
let (x, y) = start
|
||||||
|
let open = ((x, y),)
|
||||||
|
let closed = ()
|
||||||
|
let g-scores = ((0,) * w,) * h
|
||||||
|
let f-scores = ((calc.inf,) * w,) * h
|
||||||
|
let parents = ((none,)*w,)*h
|
||||||
|
while open.len() != 0 {
|
||||||
|
let cur = open.remove(get-lowest(open, f-scores))
|
||||||
|
|
||||||
|
if cur == end {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let g-score = g-scores.at(y).at(x)
|
||||||
|
let f-score = f-scores.at(y).at(x)
|
||||||
|
|
||||||
|
let (x, y) = cur
|
||||||
|
for (dx, dy) in offsets {
|
||||||
|
let (x2, y2) = (x + dx, y + dy)
|
||||||
|
if x2 < 0 or x2 >= w or y2 < 0 or y2 >= h {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if grid.at(y2).at(x2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (x2, y2) in closed {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let g = calc.abs(x2 - start.first()) + calc.abs(y2 - start.last())
|
||||||
|
let h = calc.abs(end.first() - x2) + calc.abs(end.last() - y2)
|
||||||
|
let f = g + h
|
||||||
|
|
||||||
|
if f < f-scores.at(y2).at(x2) {
|
||||||
|
g-scores.at(y2).at(x2) = g
|
||||||
|
f-scores.at(y2).at(x2) = f
|
||||||
|
parents.at(y2).at(x2) = (x, y)
|
||||||
|
open.push((x2, y2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closed.push(cur)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
#let solve(input, w: 0, h: 0, n-bytes: 0) = {
|
||||||
|
assert(w != 0, message: "Width cannot be 0")
|
||||||
|
assert(h != 0, message: "Height cannot be 0")
|
||||||
|
let grid = ((false,) * w,) * h
|
||||||
|
|
||||||
|
let obstacles = input.split("\n")
|
||||||
|
let a = 0
|
||||||
|
let b = obstacles.len()
|
||||||
|
|
||||||
|
while b - a > 1 {
|
||||||
|
let m = calc.div-euclid(a + b, 2)
|
||||||
|
let grid2 = grid
|
||||||
|
for obs in obstacles.slice(0, m) {
|
||||||
|
let (x, y) = obs.split(",").map(int)
|
||||||
|
grid2.at(y).at(x) = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if find-path(w, h, grid2) {
|
||||||
|
a = m
|
||||||
|
} else {
|
||||||
|
b = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obstacles.at(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
#show-puzzle(
|
||||||
|
18, 2,
|
||||||
|
solve.with(w: 71, h: 71),
|
||||||
|
example: (
|
||||||
|
(result: "6,1", args: (w: 7, h: 7)),
|
||||||
|
)
|
||||||
|
)
|
BIN
src/main.pdf
BIN
src/main.pdf
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user