From a35be7ec92359cd8f64f42515e6d97a1606d784b Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Mon, 9 Dec 2024 20:45:58 +0100 Subject: [PATCH] added visualization for day 9 puzzle 2 --- src/day9/puzzle1.typ | 49 +++++++++++------------ src/day9/puzzle2.typ | 91 +++++++++++++++++++++++++------------------ src/main.pdf | Bin 153648 -> 153895 bytes 3 files changed, 78 insertions(+), 62 deletions(-) diff --git a/src/day9/puzzle1.typ b/src/day9/puzzle1.typ index 9f7ab9d..754c05b 100644 --- a/src/day9/puzzle1.typ +++ b/src/day9/puzzle1.typ @@ -72,40 +72,41 @@ 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 col-gradient = gradient.linear(red, orange, yellow, green, aqua, blue, purple) - - let show-fs(size, 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 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)) diff --git a/src/day9/puzzle2.typ b/src/day9/puzzle2.typ index 2048d90..7d37143 100644 --- a/src/day9/puzzle2.typ +++ b/src/day9/puzzle2.typ @@ -1,43 +1,9 @@ #import "/src/utils.typ": * - -#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 -} +#import "puzzle1.typ": parse-input, compute-checksum, insert, show-fs #let solve(input) = { - let blocks = () - let holes = () - - let block-i = 0 - let is-block = true - let pos = 0 - for c in input { - let size = int(c) - if is-block { - blocks.push((pos, size, block-i)) - block-i += 1 - } else { - holes.push((pos, size)) - } - pos += int(c) - is-block = not is-block - } - + let (blocks, holes) = parse-input(input) + let blocks2 = () for (bi, bl, bid) in blocks.rev() { for (i, (hi, hl)) in holes.enumerate() { @@ -57,6 +23,54 @@ 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, @@ -64,7 +78,8 @@ "1": 132, "2": 2858 ), - only-example: true + only-example: true, + visualize: visualize ) // Too long to recompile everytime diff --git a/src/main.pdf b/src/main.pdf index 7a62a2f3426e8d716154c94dedcb8ab13e260cae..a83c066864b4013f7635542f879215b9c0d55685 100644 GIT binary patch delta 3203 zcmZuwc|4R`AJ51(mMH6_P-F|UJTqo$CL!CPg|TNDJ1JS3?2l#SlBFc$GRQ^tr5i?M z6gPW9vW9MmY*VimM)B5r|LL0d{PTQ1-{*JEcRQ!HR-oihfoLjM9Rw=LjYMN;y6Rj? zAl=k|4zs_L^<6b1(q&d3>;7P)Y0V{wzgAGFgQ1v^YeJXL61esI9$jYScE(=`O-hW3 zE0cfbU{)l{-Zm$FzGJWU%H&&A@rM@=_fPZ9wCpr)T`plCC=ap-xg&UJ7>lQt%B1*e*_r|!e zz_{1;^3v8CJ7)^4t~l$hEY8z`fX!6ol`lEBFjc1(bDEZ_!NhB?;=^L@&QHI&?upFE z&`Y;wXO0iVig>jPmX!a#;Yt@t$_IOQwojeqA3YE^{uZyj-eO_B*T2Ila{JTEW{_#B zhbpY-zb5J~0|FuebNFRud#NFGXv#?T0o+L~kaVbc-8MQmohU6OHOrlvD?c=CAi(qe z_QktIoW5NKy+|jcPHdWo6>PI~GuX$1uU3b1n zl{y38)*D8wkv6&3j>K{GVZwdzO2^}X_&V8_C#uFil=;<6%m$WkulKS^$CG?R?W?R` zz98jV8;L(PCWn%!flea4Bp<^?5MLJ~#Ai~jL+Y{ng7>|#5==KSE$S%S{B-m_2|8aa zGEAfB6Pjv_d9{k)oAS}q7cGY~1My|gcn!n3l$3}~F4(2A^*kVfxgXRZS9mj>o#Q=U z6&($|?A&VLKf~OX>)7H;Wj>wJYW8n6dLT!6{avcNrU>4Ws&1GvaF5Z9Z20Jo9y{({ z;FRiOU{dNXUVvm?D1}{>)LY25l zM8#{^65j8h7lUv-1CDu<8$X>WxoHdh^Dtu9=4^5kMQB#tne-x9Sw9KImOg=BU`+oha-b+pU;eVO>66<-#t*)k?+ z_(1pJi#uXF-`6R6i8s2c3zkMM+&v7lN=!M=_A4dYQr{fYykNlNs=r7fse2qx<`xvY z=`t#$Yx!CkjR6~6V#l?7(b*|%#iD%^Z89QfNvaon|90&aT23ggij@!KcQB! z_hOlYuka)dp}@Aupq5jat<=@7kdrDpCViRu9pBC?9FlFGp6!Iulcb)PO6KVZ9X)o@ z^q^E#c{?Uyonp_G(6uj;hj%*9)oW<@>pXXM{X}Ci)EMNwc*qE)|1~4Pe!@21-QPP4 zm!hQI!G7lBvT{r}$M$Tv#h7TLoGANVNM*a*mz1}~PO=M9E2tx%GO?)JUz_h6OL#6y zFKdb4x{)g{e@;K(!)$3fcrLCFVt36bk*;}U+I3s6<90@+vEWxLd}6&c5LllR2G^a&clsKlaRrF3(x?zv=QJWt$e6pa~kbM((8uaF(ZzK;j`>Uz*&VyWu~TDd%}Av&)6^TJ-E9v#2Z!fK-)Y^7)!ajd zh0(bPwLF&&Fp3oKpwtvLlsy{p2ks6DlVNRsGUVErrx$KHN4Cyx>b(#ryF~N}lQpHu zsUP(zRMVCyPodzluK}8{SbmgFDAC7E`>Zd080%w6FZy8B?C$Yt$w52qwDs8R+zMDq zYgDrxToXc9hFMgeAR3ITYW2T%iyeP04WqUAX|~&|JGAO&qF|5FA(uXkyjiW?lbKrY z*2+w@4A|##?S?iO?S93ihhGSW!`$jUeKb%O3ttORL&6I;}l&Wj>-bh}e~8@lksH zC?mYTRBmamR4)6Scz}O#FKk(zWF-k)vUGZC<9x~QKT)j#9jS#I_cpKl!-r z&^TasGAK|R$KeEpL+)-H0N|V{07!u2Kmdi|s1pFN9PtAf?f=c0{d%hbZO)$1@L%Kl z#|avN;UNC;4ggw~4a6Pz|F4NaP<4c!It2|1CI<$G1bTQv5kE8lNT`yM!8ybK0-M@~ delta 2954 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