From a272661df6af053569de4e7f2f080f79457814c4 Mon Sep 17 00:00:00 2001 From: hazel levine Date: Sun, 12 Dec 2021 14:10:21 -0500 Subject: [PATCH] last few days --- data/day10.test.txt | 10 +++ data/day10.txt | 90 +++++++++++++++++++++++++++ data/day11.txt | 10 +++ data/day12.txt | 25 ++++++++ day10.rkt | 89 +++++++++++++++++++++++++++ day11.rkt | 146 ++++++++++++++++++++++++++++++++++++++++++++ day12.rkt | 90 +++++++++++++++++++++++++++ 7 files changed, 460 insertions(+) create mode 100644 data/day10.test.txt create mode 100644 data/day10.txt create mode 100644 data/day11.txt create mode 100644 data/day12.txt create mode 100644 day10.rkt create mode 100644 day11.rkt create mode 100644 day12.rkt diff --git a/data/day10.test.txt b/data/day10.test.txt new file mode 100644 index 0000000..b1518d9 --- /dev/null +++ b/data/day10.test.txt @@ -0,0 +1,10 @@ +[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]] diff --git a/data/day10.txt b/data/day10.txt new file mode 100644 index 0000000..6b75869 --- /dev/null +++ b/data/day10.txt @@ -0,0 +1,90 @@ +({[[{{({<<<<(<{}()><()[]>)[([]{}){<>[]}]><[{<>()}{<><>}]<(()[])([]<>)>>>){<([(())<()<>>][{{}{}}[(){ +({{<{<<(([({<[[]()]<()<>>>{(()())(<>())}}[{[(){}]}(<{}[]>[<>])])<[[[{}()](<>{})]]<<{{}()}[<>]>[({})[{}()]]>> +<[<{{<<{[{{([(())<{}{}>][{<><>}(<><>)])}}]((<(<{[]<>}>(<()()>[[]()]))>))}([(<<({[]()})>(({[][]}([]{})){(()() +({<{{{{<<{([{[<>()][<>()]}[((){})([]())]])[[<[()()]<()<>>>[{<>()}{(){}}]][[{<>{}}[{}[]]][([]())[{}() +[((<[[{<[<{[<[<>[]]<(){}>><(()[])(()())>]((<<>{}>[<><>]){[()<>]{{}<>}})}>]<<[<[<()()>](({}{})( +[{{([([[<([[<[()()][()<>]>][<<{}{}>[<>{}]>(((){}){[][]})]][<[<()()><{}()>](<<><>><[]{}>)><<<<>()><{}<>>>(([]( +<{[{(<{<[[{{{[[]{}]<{}<>>>{{{}()}<[]<>>}}([(()[])]{[{}<>][<>()]})}((<(<>{})<<>[]>>[[{}[]][{}{}]]) +[<[<(<{[<([({(<>())[{}()]}[[<><>]])]){<{(((){})[{}<>])<<<>[]>(()[])>}(<([]{})<<>[]>><[{}<>][{}()]>)><<({( +(([{[<[{{[<[{{{}{}}<[]{}>}[[{}{}]{(){}}]][(<{}()>([][])){<<><>>({}[])}]>[(<(<>{})<<>{}>><{(){}}[ +<<[{[{[(<(<({{[]{}}[<>]])[{{[]{}}{[]()}}(<<>{}>[<>{}])]>{{(<{}[]>[{}[]])<{[]{}}<[]<>>>}{<{{}[]}([]( +({<<<[[({(<{{<{}()><()<>>}[{[]{}}<[]<>>]}>[<({<>{}}[[]<>])(<(){}>{[]<>})>[[(()()}(<>[])][(<><>)<{} +[(<[{[[(<{({<[[]<>]><<()[]>[{}()]>}([{<>}<[]<>>]({{}()}<{}{}>])){({(()[])([][])}<<{}{}>({}{}) +{(<<<(([[((<(<()<>>{(){}}){{{}[]}{{}()}}><(({}){<>()})<((){})({}())>>))][[{[<[<>[]]{(){}}>]( +{[<((<[[[<<[[<{}<>>{[]()}]<[{}<>][[]{}]>]{<<{}>[()[]]>{[<><>][<>]}}>{{{{{}()}}[{[]<>}<<><>>]}}>]< +([(<[[<({{[([{[]()}{<>()}]{[()<>]<<>{}>})({{()()]([]<>)})]{<((<>())[[][]])[[()<>][<>[]]]>}}}{{[[(<<><>> +<({{({<([[({<{[][]}[{}[]]>}([(<>[])((){})]([[]<>]([]{}))))}({{<<[][]>[()()]>[<()[]>{<>{}}]}[{[{}{}] +<<<[<<(<(<{{[[()()]{[][]>]<<[]()><[]<>>>}[{(<>()){<><>}}[<()<>>[[]<>]]]}>{(<(<<>>[<><>])([ +[[{({[<{(([<<[<>()](<><>)>{({}<>)(()[])}>{(({}<>){{}<>})}]([<[()[]]>><[(<>[])[<>()]]>)))[{{(({ +[<[<[{{[{{(([{()[]}{<><>}]<[{}()]({}{})>)([{()<>}{[][]}]({<><>}([]<>))))<<{<{}{}]}<(<>())([] +([(<{<{([<[((<()<>>{[][]}))([<<><>><[]{}>]({()[]}(<>())))]([<[[]<>](())><[(){}]{()[]}>]{[[[] +[{[{({{[[(([[<{}()]{{}{}}]]){([([][])([]<>)]<[()<>](<>())>){[<(){}>[<>()]]{[{}<>][{}<>]}}})(<[<{()()}([]<>) +(({<[<[<{({[(<[]<>>{(){}})[<[][]>([]{})]]{<<<>{}>(()<>)>[[()[]]}}})}{<<<((()<>)[{}{}]){<<>{}>[<>()]}><< +<[{[<[([[{{<{(<><>)[{}[]]}<<<>{}><{}()>>>}}{<<(({}[])([]{})}{(<>{}){[]<>}}>((([]<>)<{}()>){{{}<>}})><<<< +[<[([[{({(<<<(<>())>(([]())[<>{}])><<<[]()>[()<>]><(<>){<>{}>>>><({[[]{}]<{}[]>}([<>{}][{}<> +{(<[<<(<[({(({[]()}<[]{}>)({[]<>}{<><>})){<(()[]){[][]}>([()]<<>()>)}}{{((<>())[()]){[{}<>]<<> +(<{{<(({{{<[[([]()>]<{<>()}[{}{}]>]>[([[()<>](<>())][{<>{}}<[][]>])<[<()[]>]({()[]}[[]()])>]}}}))>[[< +((({{<[{[((<(<[][]>([]())){[()<>][{}{}]}>){<{{<><>}<<><>>}<([]<>)>>{([{}()][()[]])}})<[<{{<>}[[][]]}[[()[]] +([<((<(<{<{{[<[]<>>{(){}}](<{}[]>(()[]))}}>}>)<{([{<<{()()}{()[]}>[{{}()}({}[])]><[[{}[]](<>())]{[()( +<<[<<(({({((([[][]]<[]{}>)<({}<>){()()}>)[<[{}<>][[]()]>{<[]()><<>>}])})}{(([[[<[][]><[]{}>](<{}[]>{ +<<[(<<(((<([[{()()}<(){}>]({()<>}[()<>])][{((){})(<><>)}{<<>[]>({}{})}]){(<{()[]}[<>()]>)<({<><>}){[ +{(<[{([<(<[(({<>()})<[{}<>]{()<>}>)(([<>()]{[][]}))]{[<{[]{}}>[(()<>)])(<({}{})><[{}<>]{<><>}>) +{((<{[<{{[[{(<<>[]>{{}[]})}{[({}<>)[<>[]]]}]]<[[[[()]{{}<>)]{({}()){[][]}}]<[{<><>}<[][]>]((<> +{(<({[<<<(<<{[{}{}]}([[]()]({}[]))>(({<>()}<[]>)<{{}()}{{}{}}>}>)(<{{[()[]]{()}}(<<>()>{[]<>})}>)>[([[<{< +(<<[<<[(([[{({()}[<>[]])}][<(<[][]>{(){}})>(<<{}{}>{{}[]}>[({}<>)<<>[]>])]]))]((({[{{<[]{}>{{}()}}[([][])({}< +(({{<({<{{(<<{<>{}}{()[]}><[(){}][()[]]>><[<<>[]>{{}}](<()[]>{[]{}})>)}<{<([()<>]{<>{}})[([ +(<<[<{<{{<(({({}())([]{})}<({}())>)[[({}{})[<>()]]]>{{<{{}{}}<{}()>>(({}{})[{}{}])}}>({({<< +[[{([{<<<{<({[()[]][{}()]})>[{[({}{})[()()]](<<>()><<>[]>)}<(<<><>><[]{}>)<(<><>)<[]()>>>]}>>>}])}({(<<[[ +(<{(<<({[[{({{{}{}}[<>()>}[[<><>]])}]<{(<{()<>}{[]()}>[([][])[{}[]]])<[[<>][(){}]]{<[][]>([]{})}>}[((<<><> +<(({[(<<[<[[{{()()}(<>())}(<[][]><<><>>)]][[(<[]>[<>[]])([[]{}]{<>()})]{{[[]{}](<>[])}({()()}([]()))}]>]({({ +<<([<(((<{{[(<<>()>(()[])){{[]<>}<[]{}>}]<{[<>()][(){}]}>}<<[<{}<>>]>{([<><>]{<><>}){{{}[] +(([{[[[<{[{[[[()()]<()>]<[{}{}][(){}]>]}]}{[<{{[()<>][()[]]}}[{{()()}}[[<>[]][{}()]]])<<({<>()}<{}()>)>({([ +{[(<{{({[{{[{([]>({}<>)}<<{}[]>>][[{(){}}[<><>]]{<(){}>({}())}]}}[{([({}()){()[]}]{({})<[]<>>})[[[[]<>]]([<> +(([{[({{<([[([[]{}]<()[]>)(<<>>[<>[]])]{[{()()}<{}{}>](<{}()>([]{})>}])<[<{{<>{}}}<[<>[]]>>{[{[] +{({<<({<<<<{(([]()))(<<>()>)}({<()<>>{{}{}}})>[{[(<>)]{<[][]>[{}()]}}]>({[[[{}[]]({}[])]]})>>{{ +[(<[<((<[(([((<><>)([]{})){([][])[()()]}]<{{{}{}}{(){}}}>)<{{({}{})<()>}({()()}[[]{}])}<[[<>()]{()<>}>({<>} +<{{[(({{<((<({[]{}}(()()))[[{}{}]{{}<>}]>[([<>[]>(()<>))]))[[([{<><>}<<>[]>][[()<>]([][])]){<((){}){{}[ +((<[({<<({{[<[(){}](<><>)>[{[][]}[{}[]]]]}<([(<><>){[]{}}])([[()()]<()[]>])>}(([[[[]()]{{}{}}]{[{}<>]{() +(({{[<<<[[{<<[<><>]<{}<>>>[<<>()>(<>{})]>}<{(<()()><{}()>)<([]())[<>{}]>}>]]<<{([(<>{})[<>()]]{{[]()}{()( +<[{{{<<<[{[{<[()[]]({}[])>}[{({}{}){<>[]}}{<<>[]>[{}[]]}]]<[<({}{})>(([]())<{}{}>)]{([{}[]]([]<>) +{<<<[[(([{{[[(()<>)<()()>]][[{{}[]}[()()]]]}<<{[{}()]<{}[]>}[{()[]}<[]<>>]>>}]))][{(<[(<[<<><>>(()())]<({}{ +(<<<{{(<{[[[[(()())<<>[]>]<[[][]]>]((<{}<>><[][]>)[([]())[()()]])]([(<{}>(()[]))<([]()){[]{}}>]))}>)}({ +({<(({{{<{{[{<()<>>[<>[]]}([[]()][()()])]{([()<>]({}())){{{}()>{[]<>}}}}}>}<[{[<[<{}()>[{}{}]]<<()()><()( +<[{<<<([{<[{{<[][]><[]{}>}{[{}]{{}}}}<<{()[]}([]{})>([{}[])(()()))>][<[{[][]}{(){}}]{[()[] +{<[{{[<([[[[<{()[]}[<>()]>{<<>[]>{{}()}}]<({[]{}}{()<>}){{()[]}(<>{})}>]({[<()[]]([]{})][<<>()>(<><>)]}<< +({{[(([<[<[[{(()[])}{(()[])[()()]}]{[(<><>){<>{}}]<<[]<>><<><>>>}]>]<[(([<<>[]>]))]<((<{{}{}}{(){}}> +({[[(({[[<(<({<>{}})[([]<>)([]{})]>[<([][])<{}{}>>(<()()>)]){<[[<>()]{[]{}}]({{}{}}([]()))>}>]]}<{<{ +[[{([<({[[[<<<[]{}>({}())>([{}<>][<><>])>{<(()<>)<<><>>>{[<>{}]{[]{}}}}]{{((()[]))[({}[])<[]{}>]}[({<>{} +([[(([<[<([(<(<>()){{}{}>><<<>[]>[{}<>]>)<(<[]()>[()[]])>])>(<{([{[][]}<<>()>]<[<>[]]>)(<<{ +([{({<<<<[[({[[]<>]({}<>)}[({}[])(<>{})])][<{((){}){[]()}}<[{}[]]<[]{}>>>(<<()[]><{}<>>]{[<><>][{}<>]} +<<<<{{({<{{[([<>()][[][]]){{[]{}}<{}()>}][(<[]{}>[{}<>]>[{<>[]}((){})]]}}(<<<{[]{}}{{}}><([]{})({}<>)>>({(( +[[<<{<{<(<{({{{}[]}}((<>)(<>[]))){{{[]()}<()()>}[{<>()}<[]{}>]}}{[{({}{})<{}[]>}({<>[]}{[]<>})]{([{} +{{{[{[([[{{[{<{}>({}<>)}[([][]){<><>}]]([{{}[]}])}[<[[[]()]]{[[]{}]}>{<{<>()}>}]}]{[{[[[<>{}]{[]}](( +(<[[<<<({[[{{[<>[]]<(){}>}}<({<><>}{<>{}}){((){})([]<>)}>](<[[{}[]][[]]][{{}<>}[{}{}}]>((([][])[()()]){<() +{([((<{{{[[<<{()()}<[])>[{<>()}<()()>]>]((<[{}<>]<{}()>>{{{}<>}(()())}){{<()[]>(<><>)}{[[]()](<>())}})]} +{{<<<<({[<{<([{}<>]([][]))<<{}[]>([]{})>><[{<>()}{[]()}](<(){}><[]()>)>}<[<<[][]>({}())>(<[] +{[<[[((<({<<[<{}<>><{}()>]><<<{}<>>{<>}>{{{}[]){()<>}}>>([[{[][]}(()[])](({}[]){{}{}})])}<<({(<> +[[[<([[([<[{[{()[]}{{}[]}][(()()){[]{}}]}{{{<><>}{[][]}}{<{}<>]({}())}}]>[[<[{()<>}<{}{}>]<{[]()}({}<>)>>{<< +({[{<[[[([[((({}<>)((){})){({}{}){{}()}})[[(()())<{}[]>]]>[[[<{}()>]<[[]]<()[]>>][<(()<>){[]()} +[[<[{[<<<<{{({[]<>}({}[]))[<<><>>([]{})]}[<{<><>}<[]{}>><([]())[()<>]>]}<([{<><>}<()()>]<[(){}]({})> +[{(<<{{((({[<{<>[]}>](<[[]]({}[])>(<{}{}>{()()}))}<([({}<>)<{}()>]({[][]}({}())))>)<{{((<><> +{{((<(<[[<<(<([]()){()<>}><[()()]{[]{}}>)[[({}{})({}{})]<<{}{}><[][]>>]>[(<(())[<>[]]>)<<[<>() +[{([({<<{<<[{<[]>({}{})}((<>[])<<><>>)][<([])><{[]<>}<[]{}>>]><{({<>()}<<>[]>)}>>(([[({}{})[()[]]] +<{([({{{{(([{<[]()>(<>())}{{{}{}}{{}()}}]<{<{}()>[()<>]}({()[]}{<><>})>)<((<<>()>{<>{}}))({([]<>)[{}{}]}<([] +<{<[(<<({<(([(<><>)([]())]){{<<>()>}(<{}{}>{<>[]})})[{[{()<>}[<>[]]]([()()]{{}})}{([<>()]<[]()>)<[<>[]]{{}() +<{<{[[({<[[([[{}<>][{}<>]][(<>[]){()[]}])<([()[]])[<()<>>[{}()]]>}{[{[{}[]]<[]<>>}[(<>[])<()()>]]([< +[<{(<{<(([{[<<()()><()[]>>{({}{})<[][]>}]<(<(){}>)>}[<<<[]()>>[({}<>)([]())>><<((){}){<><> +[[[(((<({[([[<<>()>]{(<><>)<[]<>>}]([<[]()>{()()}]{[{}()]{<>}}))[[([<><>](<>[]))({<>()})]]](<(([[] +<{({(([{<[(<{{[]()}}>({[{}{}]{[]{}}}[{()}(<>{})>))]<(([[()][[][]]])<<<{}<>><(){}>>>)({<(<>{})>(([]())({}<>)) +<([([[[<([(<(([]<>)){[[]()][()]}>{[{<>()}([]{})]{([]<>)({}[])>})]<[<({(){}}(()<>)){{{}()}<[]{}>}><[[<>{}] +([(<[({<<(<{{(()<>)<(){}>}{<{}{}>}}>[<<(<>())<{}[]>><[<>()][<><>]>><<([]{}){[]()}>>])<[<{<[]()>[[]{}]}{([])<( +(<<{[<[(<(<<[<(){}>[[]{}]][({}())<[]{}>]>>{[<(<>())<{}()>>][<{{}<>}<[][]>><[<>()](()())>]}]>{({[<<[]() +[([<<<([<<[{{<()()><{}()>}{<[]{}>}}]{[{[[]()]}]({<(){}>(()[])})}>(<{{<<>{}>{()()}}<(()[])[[]()]>}(<<(){}>{ +<(<([((<((({(((){})]{{{}}<{}>}}<<(()())({}())>((<>[])([]()))>)){{[<((){})<<><>>>]}})><<[<[({[]{}}(<><>)){(< +<{[<[[({<[<<{(<>[])[()[]]}{<<>>(()[])}><[{(){}}[<>()]][{[][]}(()<>)]>>{<<(<>[])[[]()]>{{<>()}<{} +<<({[({{[([{[<[]><<>[]>]}<{{{}[]][()<>]}{{()[]}[{}<>]}>])]}<<{([{(<>[]){{}<>}}]([[<>()][()<>]]))({(<{ +(<{{{[[([<[{{{[]<>}[()<>]}<<<>()>>}[((()[]){()[]})]]>{{([([][])])<([<><>]{()<>})(<<>{}><<>{}>)>}{<<<[] +[[([<([[<[<{({()<>}{[]{}}){[{}[]][<>[]]}}>]>]{{({(([{}[]]({}{})){[<>{}]{{}<>}})<((<>()))[{[]{}}]>}(((( +({[<<[[[{{{[<<[]>([]<>)>(([]<>)<[]{}>)][<<{}[]>({}{})>]}([[<{}{}>[()[]]]((()<>)[<>[]])]{([()<>]{[][]}){{<>< +{<[{({[<({({[{{}[]}[[]{}]]({{}{}}([]()))}[(<()<>>{[]{}}){<[]{}>[()]}])}<({<{[]()}({}[])>[(()){<>()}]} +[([{{(([[{<[{(()())[{}[]]}<<<>><{}[]>>]{[{[]()}[[]<>]](<{}{}>[()()})}>}[([(<{}<>><{}<>>)(<<>{}>([]{}))]({([]{ diff --git a/data/day11.txt b/data/day11.txt new file mode 100644 index 0000000..674e736 --- /dev/null +++ b/data/day11.txt @@ -0,0 +1,10 @@ +8826876714 +3127787238 +8182852861 +4655371483 +3864551365 +1878253581 +8317422437 +1517254266 +2621124761 +3473331514 diff --git a/data/day12.txt b/data/day12.txt new file mode 100644 index 0000000..82a4862 --- /dev/null +++ b/data/day12.txt @@ -0,0 +1,25 @@ +BC-gt +gt-zf +end-KH +end-BC +so-NL +so-ly +start-BC +NL-zf +end-LK +LK-so +ly-KH +NL-bt +gt-NL +start-zf +so-zf +ly-BC +BC-zf +zf-ly +ly-NL +ly-LK +IA-bt +bt-so +ui-KH +gt-start +KH-so diff --git a/day10.rkt b/day10.rkt new file mode 100644 index 0000000..0f7e555 --- /dev/null +++ b/day10.rkt @@ -0,0 +1,89 @@ +#lang racket +(require "lib/common.rkt" + data/either + data/monad + megaparsack + megaparsack/text) + +(define left-delim/p + (char-in/p "([{<")) +(define (right-delim/p ch) + (match ch + [#\( (char/p #\))] + [#\[ (char/p #\])] + [#\{ (char/p #\})] + [#\< (char/p #\>)])) + +(define expr/p + (do [x <- left-delim/p] + (many/p expr/p) + (right-delim/p x))) + +(define (day10a lines) + (define (score ch) + (match ch + [#\) 3] + [#\] 57] + [#\} 1197] + [#\> 25137] + [_ 0])) + (for*/sum ([line (in-list lines)] + [parsed (in-value (parse-string expr/p line))] + #:when (failure? parsed)) + (score (message-unexpected (from-either parsed))))) + +(define (day10b lines) + (define incomplete-lines + (for*/list ([line (in-list lines)] + [parsed (in-value (parse-string expr/p line))] + #:when (and (failure? parsed) + (equal? (message-unexpected (from-either parsed)) + "end of input"))) + line)) + + (define (to-recover str) + (define (get-recovery fail) + (define msg (from-either fail)) + (for/first ([ch (in-list (message-expected msg))] + #:when (not (set-member? (set "'('" "'['" "'{'" "'<'") ch))) + (string-ref ch 1))) + + (let loop ([recov ""]) + (define res (parse-string expr/p (string-append str recov))) + (cond [(success? res) recov] + [else (loop (string-append recov (string (get-recovery res))))]))) + + (define (score recovery) + (for/fold ([current-score 0]) + ([ch (in-string recovery)]) + (+ (* current-score 5) + (match ch + [#\) 1] + [#\] 2] + [#\} 3] + [#\> 4] + [_ 0])))) + + (define recoveries + (for/vector ([line (in-list incomplete-lines)]) + (to-recover line))) + + (define (vector-middle vec) + (vector-ref vec (floor (/ (vector-length vec) 2)))) + + (vector-middle (vector-sort (vector-map score recoveries) <))) + +(module+ main + (call-with-input-file "data/day10.txt" + (λ (prt) + (define lines (port->lines prt)) + (answer 10 1 (day10a lines)) + (answer 10 2 (day10b lines))))) + +(module+ test + (require rackunit) + + (call-with-input-file "data/day10.test.txt" + (λ (prt) + (define lines (port->lines prt)) + (check-equal? (day10a lines) 26397)))) diff --git a/day11.rkt b/day11.rkt new file mode 100644 index 0000000..45d79cf --- /dev/null +++ b/day11.rkt @@ -0,0 +1,146 @@ +#lang racket +(require "lib/common.rkt" + threading) + +(struct posn (x y) #:transparent) + +(define (posn+ p1 p2) + (posn (+ (posn-x p1) (posn-x p2)) + (+ (posn-y p1) (posn-y p2)))) + +(define (explode str) + (map string (string->list str))) + +(define (parse str) + (~>> str + string-split + (foldl string-append "") + explode + (map string->number) + (apply vector))) + +;; boards are 10x10 +(define (board-ref vec i j) + (vector-ref vec (+ j (* 10 i)))) +(define (board-set! vec i j val) + (vector-set! vec (+ j (* 10 i)) val)) + +(define (adjacents x y) + (define (valid? p) + (match-define (posn x y) p) + (not (or (< x 0) (< y 0) (>= x 10) (>= y 10)))) + + (for/list ([path (in-list (list (posn 1 1) (posn 1 0) (posn 1 -1) + (posn 0 1) #|.........|# (posn 0 -1) + (posn -1 1) (posn -1 0) (posn -1 -1)))] + #:when (valid? (posn+ path (posn x y)))) + (posn+ path (posn x y)))) + +(define (tick-board board) + (define res (vector-copy board)) + (vector-map! add1 res) + + (define seen (mutable-set)) + (define (tick-until-stable) + (cond [(for/and ([v (in-vector res)]) + (not (>= v 10))) + #f] + [else + (for* ([i (in-range 10)] + [j (in-range 10)] + #:when (>= (board-ref res i j) 10)) + (set-add! seen (posn i j)) + (for ([adj (in-list (adjacents i j))] + #:when (not (set-member? seen adj))) + (match-define (posn x y) adj) + (board-set! res x y (add1 (board-ref res x y)))) + (board-set! res i j 0)) + (tick-until-stable)])) + (tick-until-stable) + + res) + +(define (day11a board) + (for/fold ([current-board board] + [current-sum 0] + #:result current-sum) + ([_ (in-range 100)]) + (define r (tick-board current-board)) + (values r (+ current-sum (vector-count zero? r))))) + +(define (day11b board) + (let loop ([current-board board] + [current-iter 0]) + (cond [(for/and ([v (in-vector current-board)]) + (zero? v)) + current-iter] + [else (loop (tick-board current-board) (add1 current-iter))]))) + +(module+ main + (call-with-input-file "data/day11.txt" + (λ (prt) + (define board (parse (port->string prt))) + (answer 11 1 (day11a board)) + (answer 11 2 (day11b board))))) + +(module+ test + (require rackunit) + + (define step0 #<lines prt)) + (answer 12 1 (day12a lines)) + (answer 12 2 (day12b lines))))) + +(module+ test + (require rackunit) + + (define lines #<