diff --git a/src/day1/puzzle1.typ b/src/day1/puzzle1.typ index 008842f..a92f547 100644 --- a/src/day1/puzzle1.typ +++ b/src/day1/puzzle1.typ @@ -15,7 +15,7 @@ } #show-puzzle( - 1, + 1, 1, solve, example: 11 ) \ No newline at end of file diff --git a/src/day1/puzzle2.typ b/src/day1/puzzle2.typ index fcde641..8c0936a 100644 --- a/src/day1/puzzle2.typ +++ b/src/day1/puzzle2.typ @@ -1,4 +1,5 @@ #import "/src/utils.typ": * +#import "@preview/cetz:0.3.1": canvas, draw #let solve(input) = { let lines = input.split("\n") @@ -29,8 +30,57 @@ return total } +#let visualize(input) = { + let lines = input.split("\n") + let (l1, l2) = ((), ()) + let reg = regex("^(\d+)\s+(\d+)$") + for line in lines { + let digits = line.match(reg) + l1.push(digits.captures.first()) + l2.push(digits.captures.last()) + } + + let unique = l1.dedup() + let colors = (red,green) + canvas({ + for (i, n) in l1.enumerate() { + let y = -0.9 * i + draw.circle( + (0, y), + radius: 0.35, + stroke: black, + name: "l" + str(i) + ) + draw.content((0, y), n) + } + for (i, n) in l2.enumerate() { + let y = -0.9 * i + draw.circle( + (4, y), + radius: 0.35, + stroke: black, + name: "r" + str(i) + ) + draw.content((4, y), n) + } + for (i, a) in l1.enumerate() { + for (j, b) in l2.enumerate() { + if a == b { + draw.line( + "l" + str(i), + "r" + str(j), + stroke: colors.at(unique.position(n => n == a)) + 1.5pt, + mark: (end: "straight") + ) + } + } + } + }) +} + #show-puzzle( - 1, + 1, 2, solve, - example: 31 + example: 31, + visualize: visualize ) \ No newline at end of file diff --git a/src/main.pdf b/src/main.pdf index 2f9ca51..090bee2 100644 Binary files a/src/main.pdf and b/src/main.pdf differ diff --git a/src/utils.typ b/src/utils.typ index 86d36dd..cc435f0 100644 --- a/src/utils.typ +++ b/src/utils.typ @@ -1,5 +1,7 @@ #let star-state = state("stars", (:)) +#let star = text(font: "Twitter Color Emoji", emoji.star) + #let get-input-path(day) = { return "/res/inputs/day" + str(day) + ".txt" } @@ -13,8 +15,15 @@ return read(get-input-path(day)) } -#let check-example(day, func, target-result, suffix: none) = { - let result = (func)(read(get-example-path(day, suffix: suffix))) +#let check-example( + day, + func, + target-result, + suffix: none, + visualize: none +) = { + let input = read(get-example-path(day, suffix: suffix)) + let result = (func)(input) let passes = (result == target-result) let name = if suffix == none [Example] else [Example '#suffix'] let badge = box( @@ -38,6 +47,14 @@ } [#badge #h(0.6em)] + + if visualize != none { + linebreak() + figure( + visualize(input), + caption: [#name (visualization)] + ) + } } #let show-result(result) = { @@ -46,30 +63,35 @@ radius: 1.2em, baseline: 35%, fill: blue.lighten(20%), - text(fill: white)[Result: #result] + text(fill: white)[Result: #raw(repr(result))] ) } -#let show-puzzle(puzzle, func, example: none) = { +#let show-puzzle(day, puzzle, func, example: none, visualize: none) = { + let check-example = check-example.with(visualize: visualize) if example != none { if type(example) == dictionary { for (suffix, result) in example.pairs() { - check-example(puzzle, func, result, suffix: suffix) + check-example(day, func, result, suffix: suffix) } } else { - check-example(puzzle, func, example) + check-example(day, func, example) } linebreak() } - let input = get-input(1) + let input = get-input(day) let result = (func)(input) show-result(result) } #let day-template(day, puzzle1, puzzle2, stars: 0) = { pagebreak(weak: true) - let title = [Day #day] + ((emoji.star,)*stars).join() + let title = [Day #day] + box( + baseline: -1pt, + ((star,)*stars).join() + ) + [ = #title #label("day-" + str(day)) @@ -108,7 +130,7 @@ dir: ttb, spacing: 0.2em, cell, - h(3pt) + ((emoji.star,)* stars.at(str(i))).join() + ((star,)* stars.at(str(i))).join() ) if links { cell = link(label("day-" + str(i)), cell)