diff --git a/day10.rkt b/day10.rkt new file mode 100644 index 0000000..5eb6f2b --- /dev/null +++ b/day10.rkt @@ -0,0 +1,53 @@ +#lang racket + +(define data (map string->list (file->lines "day10.txt"))) + +(define pairs (list (list #\{ #\}) (list #\( #\)) (list #\[ #\]) (list #\< #\>))) +(define opening (map first pairs)) +(define closing (map second pairs)) + +(define (go input stack) ; returns the incomplete list OR the first broken bracket if corrupted + (if (= 0 (length input)) ; if we've run out of input.. + stack ; we've got an incomplete chunk. return the stack + (let ([x (first input)] [xs (rest input)]) ; grab the first element of the input + (if (member x opening) ; if it is an opening bracket + (go xs (cons x stack)) ; push it on the stack and recurse + (let* ([y (first stack)] ; otherwise, it's a closing bracket. grab the top of the stack.. + [matching (second (assoc y pairs))]) ; and find its matching closing bracket + (if (equal? matching x) ; if they match.. + (go xs (rest stack)) ; remove it and recurse + x)))))) ; if they don't match, return the offending bracket + +(define part1 + (let* ([res (map (λ (x) (go x '())) data)] + [bads (filter (λ (x) (not (list? x))) res)] ; filter out the lists - they're the incomplete chunks + [costs (list (list #\) 3) (list #\] 57) (list #\} 1197) (list #\> 25137))] + [points (map (λ (x) (second (assoc x costs))) bads)] + [total (apply + points)]) + total)) + +part1 + +; PART 2 + +(define (complete input stack) ; find the necessary closing brackets to complete the chunk + (if (= 0 (length input)) + stack + (let* ([x (first input)] + [matching (second (assoc x pairs))]) + (complete (rest input) (cons matching stack))))) + +(define (score chunk) + (let ([costs (list (list #\) 1) (list #\] 2) (list #\} 3) (list #\> 4))]) + (foldl (λ (x acc) (+ (second (assoc x costs)) (* 5 acc))) 0 chunk))) + +(define part2 + (let* ([res (map (λ (x) (go x '())) data)] + [rev (reverse res)] ; reverse so we can use `first` & `cons` + [incompletes (filter (λ (x) (list? x)) res)] ; filter out the lists - they're the incomplete chunks + [completing (map reverse (map (λ (x) (complete x '())) incompletes))] ; un-reverse it + [scores (map score completing)] + [sorted (sort scores <)]) + (list-ref sorted (/ (- (length sorted) 1) 2)))) ; find the median scoring chunk + +part2 \ No newline at end of file diff --git a/day10.test.txt b/day10.test.txt new file mode 100644 index 0000000..b1518d9 --- /dev/null +++ b/day10.test.txt @@ -0,0 +1,10 @@ +[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]] diff --git a/day10.txt b/day10.txt new file mode 100644 index 0000000..6b0ede5 --- /dev/null +++ b/day10.txt @@ -0,0 +1,98 @@ +{<{[<((<[<({<{(){}}(()())>[<<><>>((){})]}(<<{}{}>(<><>)>))(<[(<>{}){()()}]{{{}[]}(()())}>[ +((<{[<([<<{[<(()())([]())>)<<<{}{}>{[][]}>{<<>>(()[])}>}<(((()[])[{}<>])[<[]{}>{{}[]}])[[({}{}) +({(<[([((<(<[(<>{}){()[]}]<[[]<>]<(){}]>><{(<>())[<>{}]}{(<>[])(<>{})}>)([(<(){}>[(){}]){{()[]}{<>{}}}][<<[] +{{{[(([{{{[{[(()())[<>[]]]{([]{}){()<>}}}]{{{((){})[[][]]}[[{}{}]<[]()>]}(<(<>()){{}{}>>([{}() +[<{{{[[(<[(([<{}[]>{()()}][[<>{}]]))]([<<{{}[]}>>([(<>[])<(){}>][[{}{}](()())])]{[{[<><>]}((<>{})[ +{<[<[[<<(<<<<(<>[])(<>[])>{([]())}>[{{[]()}}<({}())[<>()]>]>{[((<>{})[[]<>])([()<>]{<>()})](((<>() +([({({[{(([<[<[]>]>]<<({[]()}<[]<>>)[[()[]]{[]{}}]>>))((<<{<<><>>}{(<>{})<[]()>}>([[<>{}]<<>{}> +{(<([{{{{(((({{}[]}))){[(({}<>))({<><>}<[][]])][<<[]{}>[{}{}]>{<[]>{[]{}}}]})({[{([]<>)([]<>)} +{([{{{(([<[[[<(){}>{()[]}][([]<>)<[]{}>]]<{(<>())[[]()]}[{(){}}[()<>]]>]([({[]{}}{()[])){{<>()}{()[]}}])>[<[ +[([{<{(<({<{[[<>{}][<>[]]]<{{}<>}<{}{}>>}[({()[]])[[<>()]({}<>)]]>{<([{}<>]<[]<>>)[{[]()}{{}[]}]>[[{[][] +{{<(<{(<[<(((<[]<>><{}[]>))({(<>{}){[][]}}([[]()]({}<>))>)>[((((()<>)<<>[]>){(<>{}){<>{}}})(<({}( +{{[{<{<([{[<{[{}{}]{(){}}}{{[]<>}<()[]>}>]<[({[][]}<{}<>>)(<{}{}><[]()>)]<[{<>{}}(()())]([[]{}]<[]<>>)>>>[{[{ +<(([<<{{<(([(({}{})[[]{}])[<{}>(<>{})]]<([{}{}]{()[]})>))({(<(()<>)<<><>>>(([]<>)))}<<<[() +<<<(({{([{({({()()}<<>[]>)<{()[]}[<>()>>}){[<[<>{}][<><>]>[{()[]}[<><>]]]<<[<>[]]{<>()}>>}}[(<[[(){}](() +<<[[{{([(([([[<>{}][(){}]])]{({{()}(<>{})}{{{}<>}{<><>}})(([<><>])({{}[]}<<><>>))})([{({()<>}<[][]>)}])) +[(<<<<<{[<({[{{}[]}<()<>>]<[{}[]][[]<>]>})>[<<{(()())({}<>)}{({}())(<>[]]}><<<{}<>>([]<>)><[ +<<({({{([(<([[{}()]<[]{}>]<<<>()>>)><{(<{}<>><{}()>)<{(){}}[<>]>}{([[]{}][[]<>])<({}()){{}[ +{<{([[[[[{<<[[{}{}]([]<>)]{{{}()}[<><>]}><[<()()>[{}{}]](((){})<()>>>>}]<{({{([]()){{}<>}}<{<>{}}({}{} +{[{[[<[((<(<<{<>}{()[]}>><{<<>[]>[()[]]}{{()()}[()[]]}>)(({[[]](<>[])}{({}())<{}()>})([[{}[]]<[]()>][{ +[{[(({[{{([[[<()()>{{}{}}]{([]<>){<><>}}]](<<<(){}>(()())>{[[]]{<>{}}>>))<[<((<>{}){(){}}){[{}<>]}>([[<>< +<{<(<([(<[({<<[]()>[[]{}]>(<{}<>>)}(<[{}[]][{}[]]>{<{}[]>[(){}]}))[<(<[]<>>{{}<>}]([[][]]<()<>>)>{({{}<>}[<>[ +{({({{<({[{[{<<>()>[[]{}]}](([{}<>]{()()})[([]()){[]()}})}[[((()())[()<>])(<<>{}><{}>)]]]<([{([] +(<[([{({<([<(([]<>)<()[]>){{<>{}}[()()]}>])(([({[]()}<{}{}>)][<{{}[]}({})>[[<><>][<><>]]])<[({()[]}[[]{ +{{{<{{[[{[[<({[]()}{()[]})<[<>()][()()]>>(({{}{}}))][({[(){}](()[]]}){{<<>()>({})}{<{}[]>[{}<>]}}]]{[< +{<([((<{<<<{(({}{})<<>[]>)(((){}){[]})}{({[]<>}[[]{}])<[{}[]][()()]>}}[{([<>()][<>{}]){(<> +{([([(({[<[[[(())(<>[])]{[()()][<>]}]]>([{[(<><>)(<>())]<(()<>)[<><>]>}({{<>{}}({})}([{}][ +([[[({[{{<{{{[{}()]{(){}}}[{()}({}[])]}[{[[]<>>(()[])}<{[][]}{[]}>]}>}}]}{[<[[[[(({}{}){{}[]} +<[{<([<({((([[<>{}]([]())]<[()[]]<()<>>>){<<{}{}>[<><>]>[((){}){{}<>}]}))}({[({[()())(<>[])}{({}())}){([()[] +{([[{[<<[[<{([<>()][{}{}])<([]{})(()[])>}{{{()()}{[][]}}<[[]{}]<<>{}>>}>(({<()()>({}())}[{<>[]}({}<>)])([[< +({[<{{[<{{(((([]<>){<>()})([()<>]([]{})))){{<{()()}[{}<>]>}({<{}[]>}{([]<>)<{}[]>})}}<<([{{}()}[{}[]]]<{( +<({{([{[({<([({}())[()[]]]{([]{})})(([[]{}]{{}[]})([{}()><()<>>))>(<(({}{})<{}{}>)[{<><>}{[] +[{[{<{([[[<[[{[][]}(<>{})]{{[]<>}[{}{}]}]><{({{}()}<[]()})}>]{{(<[[][]]{[]()}>{(()())(<>[])})( +(<{(<[[<{[[<<([]<>)<{}{}>>({{}[]}({}()))>]({([[]<>]([]())){[<>{}]<{}()>}}[{({}())[(){}]}(({}{})[[]] +<[<<([{[{<{{<[[][]]<<>[]>>({<>{}}[<><>])}([[{}<>]<()()>][<[][]>(()[])])}[({[()()][[]()]}[{{}()}<[]<>>])]>{< +<(([[{(([[([[{{}()}{[]}]]<((<><>}({}[]))((()())[()[]])>)[{{<[]<>>((){})}}<(<(){}>{{}[]})({()}{{}<>})>]]<[(<{ +[{<(((<(<({(({{}()}{<><>})[{[][]}{(){}}])({{[]{}}[<>{}]>)})>((([<(<><>){{}<>}><[<>{}]>]([[<>[]][{}{} +[<{{({([({({{{()<>}([][])>}((({}<>)(()[]))<(<>()){{}<>}>)){[([()()](<>[]))]{({[]}[[]{}])([[]<> +{({[<{(<<([[[<{}{}>[{}{}]](<<>>(()))]{[([]<>)<{}{}>]<[<><>]>}]<[[{{}<>}<<>{}>][([]<>)<(){} +([{{{[[(<<[<[[<>]{[]}]((<>{})({}[]))>({{()[]}<<><>>}{{<>{}}({})})]{{{{[][]}<{}()>}}<[[<><>][{}<>]]< +[<{<{<[{{[([(([]<>))[{<>()}<{}{}>]]{[<<>{}>[(){}]){<[][]>[<><>]}})](([<([]{})[{}()]>(({}())(<>{}))] +[<[<{(<(([{<{([]{}){[][]}}><{[{}[]]([]<>)}[[()[]]<()()>]>}][{(<[(){}]{()<>}><<[]()>[[]()]>){[[<>[]](()[]) +<(<<<([[<([[({[]<>}<[]()>){{<>[]}[{}{}]}]([[[][]]<[]()>])]<{{(<><>){<>[]}}}{(<[][])(()[]))[([]{})[[ +(([{<{{([<<{({[]{}}[()[]])[<()()><()[]>]}[(<()>[()()])[[<>[]]]]>>{{{{<[]()>[()<>]}}{{<()[]>[()[]]}<[[][]] +(<<[([[{{({<[([][])<{}()]][<()()>(()())]>})}<([[{(()<>)<[]()>}((()[])[<>{}])]]([<{(){}}({}<>)>][< +[<<((<[<<{(((({}()))({<>{}}([]<>))){{<()<>><{}[]>}{(()())}}){({([]<>)<<>{}>})}}<{{<[()][<><>]>{{[] +<{[<[((([{<{{{<>[]}[[]()]}([<><>])}>((<<<>()>({}<>)><[{}[]]<()[]>>)[{{[][]}{()<>}}[{()<>}(()[])]])}(([<{{ +{<{<[(({([<[<[[][])([]{})>[{(){}}[[]<>]]][(<{}<>>{()<>}){[<><>]{{}[]}}]>([[<[][]>{[]<>}]({[][]}(()()))]{ +(<{{{[{<{(<[({{}[]})]><<{(()<>)[{}{}]}{<()()>}>>)[[(({()<>}(<>{})))([<(){}>(()<>)]{((){})([][])})] +<<[(<([<(({[{({}{})}<{()<>}{<>{}}>][([[]()](()<>))]}[[({{}()}<[]{}>)[<[]()>[()()]]]((<{}{} +<<{[{[<{{{([<<<>{}>{()[]}>({{}[]}<<>{}>)][[<()[]>[{}[]]]({()<>}(()()))])[<<<<>()>{[]{}}>><{{[]{}}<()<>>}(<<>[ +[{{<({[([({{{(()())[<><>]}{[()()][(){}]}}}{[([<>[]])[{[]()}((){})]]([<[]{}>(()<>)]{[<>]})})(< +<<<{{(({<{<[<<<>{}>>(<<>[]>{()()})]<([()<>])>>[(<({}[]){{}[]}>{[{}{}][[]()]})[<[<>[]]<()[]>>(< +[([<<<(<[[[[[([]{}){{}()}}<<[]()>{[]}>][([<>[]]({}))[(()<>){()()}]]]]]>{[([[<([]())<{}<>>>({<>()} +[([{{[[(({[<{[{}[]]{[][]]}<{<>()}[<>[]]>>(<{<>()}<[]()>>)]}))<<<<<{{()[]}{{}[]}}[<<>{}>]><{[{}<>]{( +[{{{<((([{([{[[]()][<>()]}([[]()]{{}()})]{([{}{}](<>{}))({()<>}(<>{}))})<[({(){}}[()<>])}>}( +{<<{{({[[[[[{[()]({})}<[<><>]{{}}}][[{()<>}({}{})][<<>[]>{<><>}]]]({<(<>)<<><>>>({<>()}<<> +<[[[[({([[{<[{{}()}]{(()<>)<[]()>}>{[{<>{}}(()[])][{()[]}<()()>]}}]]<{[(({<>{}}{<>()})<[[]()]<<>{}>>)<((()[]) +({{{<{[({[[[<{()<>}<<>[]>>{[[]<>][<>()]}]([(()<>)[[]()]]({{}[]}(()[]))]]][{{{<<>>({}<>)}<<<>{} +[{[((<{<([[{<<()[]>[[][]]>}<{({})}[<{}[]>[[][]}]>]]<<{(([]<>)[[]()])}<{<{}()>{[]}}{[()[]]({})}>> +[{([[{[({<[<(<<>{}>({}[]))([{}<>]{(){}})}({<[][]>}{[()()]<{}[]>})]<<[<(){}>[<>{}]][<<>{}>({}{ +[<([{<<[((([<[<>()]({}())><([]{})<{}[]>>]))[{[[[[]()]]]}{{[{[]()}([][])]{<[][]>{{}()}}}}])<(({{(<>()){ +{{[[<{{(({{{(<{}<>>{()[]})[<[]()>]}[{<[]{}>[()[]]}]}<[{[[]<>][[][]]}<<(){}>((){})>][([()<>]<<>>)< +<<{[(([{<((({([][]){[]<>}}{({}())}))({[<<>{}><<>>]}{<[<>{}](()())><<{}[]>{()<>}>)))({[<(<>[ +<[<((<<[[<[((([]<>)<(){}>)[<(){}>])({<{}{}>{<><>}}<(()())<[]{}>>)]{{({(){}}(()[]))}<({<><>}({}()))>} +[<{(<([{[({[{({}{})<{}()>}[{[]<>}({}<>)]]})[<[([{}[]][()[]])((<>()){{}<>})][[[(){}][[][]]][< +<(({([[(<[[{(<<><>><{}()>)<(()()){()[]}>}({[()<>][{}[]]}([<>{}]<<><>>)}]]{{[<[<>[]]>({<><>}([]{}))][(([][])< +{[[[[<<[{(({{{[]()}[{}[]]}}{[[()()][{}{}]]}){[{{{}()}}[[[][]]<()()>]]}){[{((()<>)[{}<>]){<<>()>[()()]}}(([{}< +[[<<<{<({[<([[()<>]]({()<>})){[{{}[]}]}>][({[<()<>>({}[])]}((<<><>>[<>])[({}())<{}{}>]))]})>}>[{{(({{[ +{{[[{{(([[[[({[]()}<{}()>)<(()[])<<>[]>>]]<(<{[][]}<{}()>>(({})[[][]]))>]<<{({()[]}[(){}]]({ +({{((<([<({<(<[]<>><<>[]>){[{}<>]}>(<[{}{}]>)}[<{{<>{}}{[]()}}[<<><>>[[][]]]>[[<()()><(){}>]{< +[[[(({{<(<{<[{()[]}]({<>{}})>[<<<>()>{{}{}}>{({}<>)<<>()>}]}<({{()()}}<(()()){<><>}>){<((){})(<>() +{<{{(<{{<[[({<<>>}<[(){}]({}())>)[<{()<>}[{}()]>[({}[])<()()>]]]]{<[({<>{}}{[][]})]{[(<>{})({}())]} +[<[<{<<({[[(((<>())[{}<>]))<(({}[])(()[])){{{}{}}[[]<>]}>]<[(<{}{}]{{}{}})<(()<>)>][[{<>{}}<[ +[({<(<[([<({([<>()]{[][]}>{<<>[]>[[]()]}}[{<()<>>([]<>)}])<<<[[]()](())>><[<<>[]>{{}()}]{<() +{{[{(<<{[{({[<[]()>{{}<>}]([()<>]{{}[]})}<<<[]()>[[]<>]><[<>{}][()()]>>)}<{<[{[]()}{<>{}}]>{({[][]}<[] +[[{[<<<[{[[<({<>()}((){})){{<>[]}<(){}>}>[<(()<>)({}<>)>{<[]()>(<>)}]]]{<<{[<>[]]>>(<<{}()>(<>())>( +{({{[([<{{{<((<><>)<()()>][<{}[]>{<>[]}]><({<>()}(()<>))({{}[]}<()[]>)>}([({{}[]})({{}()}[<>[]])])} +{<[[({{((<[{[{<>()}(<>())]<({}[])<<>{}>>}([(()())<<>[]>]((<>[]){{}{}}))]{({<()()>(()<>)}[{[][]}([]())])<<[() +([{((({<<<{<{{<><>}(()<>)}>}>)[{{[[[[][]]]][<(<>{}){[]}>([{}()][[][]])]}<{([()()][<>()])(<[]()> +<(((<(({<<[{<(()())>[[[][]]<[]{}>]}[{{<>()}(<><>)}(({}())({}()))]]>((<({{}[]}(<>())){({}[]) +<<{[(<([<(<{{[<>{}]}(<<>()>({}{}))}><({<<>()>(<><>)}<<[][]>[[]()]>)(([<>()){{}()})<[[][]]{<>{} +<<[[([{{{{[<{[(){}]<[]()>}>[[([])<[]<>>>[({}{})([][])]]]}<<({<()[]><{}<>>}<{()<>}(<><>)>)>(([ +{[[[{{[{{((<{[{}[]](()[])}<(<>{})(<><>)>>){(<<<>{}>>)(([()[]]<[]{}})[({}[])(()())])})}}]}{[{{({({([] +([{[{((([[{{([[][]][{}[]])[{[]<>}<<>[]>]}}]][<[{[(<>{})[[]<>]][{[]<>}[(){}]]}]{<[[{}[]]{{}[]}]><(({} +{(<(<{<<([<<<[{}{}]<{}{}>>><[{<><>}{{}<>}]([[]<>]{{}()})>>])>>{{[{{{<<<>()>[{}()]>{<[]()>[<>{}]}}}}<(<[( +{<[{<<({[({(([[]<>](<><>)))[[[{}()]<()[]>]<{<>{}}[()<>]>]})([<([(){}]{<>[]})<<<>()><(){}>>><([<>[]>([][]))(<< +[[[[<<(<({(<[{(){}}[()[]]][[{}[]]{[]{}}]>([{[][]}([]{})][{{}[]}<[]()>]))[{[{()()}({})]({(){}}[<>[] +{<{(<[<(<<<{<[()<>]>{{()[]}}}<<([]<>)[()<>]>>>[{[<<><>>[{}<>]][<<><>>{(){}}]}[{[[]()]{<>()}} +<[[<{<<[{{[[(([][])[[][]])<({}<>){{}[]}>]](<<({}[])[[][]]>((<><>))>[([()[]]((){}))])}}{[([((<>()) +{(<{[[((<<<{<{<>{}}([]{})><{()}>}[{(()<>)[[][]]}{<{}{}><{}{}>}]]<[[<{}()>]<([]{})>]{{[<>()]{{}{ +<{<{<{[{(((<(<[]{}>)([{}{}]({}{}))>([{[]<>}[[]{}]]<([]()){[]<>}>))<[(<[]{}>[()[]])]>)<{{[{{ +{{<([<{[(([(({[]<>}{()[]})<(()){(){}}>)[{({}<>)<[]<>>}<{{}()}<<><>>>>][{<({}<>)[()()]><<()<>>> +[[[<([<<[[[{<<[][]>{()()}>[[(){}][<><>]]}{[{<>[]}[[]{}]]}]{<<({}<>)[[]]>[(<>[])]><<[()[]]<[]>>[{[]<>}({}{})]> +{{{[{(<<{({{<{<>[]}>[{<><>}[()[]]]}[({()()})([<><>]<<>[]>)]}({[{{}[]}{{}[]}]}[(<[]()>[<>[]])({<><>}[(){}])] +(<<[{[{[({<[{{(){}}<(){}>}{{()[]}[<>{}]}]{{(<>{})<{}>}{((){})}}>[{([<>()](<>{}))<{{}[]}[[]{}]>}{(<[][ +(<[[{<<{({<([<<>()>[<>()]]{{()<>}[<>[]]))>({<<<>()><()<>>>}({{[]<>}{{}()}}{<(){}><<>{}>}))})}<([<({[[]]{{}< +([((<[((([{<((()<>))[([])]>({(()<>)([]{})}([{}<>](()<>)))}{<[[[]()]([]{})]>}]({([{[]{}}][{(){}}{(){} +(({{<[<{<{([<([]<>){()}><([]<>)<[][]>>]<<[()<>][[]<>]><{()()}>>)[(<[[]{}](<>())>{{{}()}{[]()}} diff --git a/day11.rkt b/day11.rkt new file mode 100644 index 0000000..0e9e695 --- /dev/null +++ b/day11.rkt @@ -0,0 +1,84 @@ +#lang racket + +(define SIZE 10); + +(define (map-map f lst) ; map . map + (map (λ (x) (map (λ (y) (f y)) x)) lst)) + +(define (char->num chr) ; i hate this + (second (assoc chr (list '(#\0 0) '(#\1 1) '(#\2 2) '(#\3 3) '(#\4 4) '(#\5 5) '(#\6 6) '(#\7 7) '(#\8 8) '(#\9 9))))) + +(define (subtract l1 l2) ; retun list of items that are only in l1 + (filter (λ (x) (not (member x l2))) l1)) + +(define grid ; file -> flat vector of the grid digits + (list->vector + (flatten + (map-map char->num + (map string->list + (file->lines "day11.txt")))))) + +(define (display-grid grid) + (for-each (λ (i) + (printf "~s " (vector-ref grid i)) + (if (= 0 (modulo (add1 i) SIZE)) (printf "~n") (printf ""))) + (range 0 (* SIZE SIZE)))) + +(define (neighbors idx) ; find all the neighboring indicies, filtering out out-of-bounds + (filter (λ (idx) (and (>= idx 0) (< idx (* SIZE SIZE)))) ; remove ones off the top or bottom of board + (filter identity ; remove #f + (flatten (list (if (= (modulo idx SIZE) 0) #f ; if it's on the left edge, #f + (list (- idx (add1 SIZE)) (+ idx (sub1 SIZE)) (sub1 idx))) + (if (= (modulo (add1 idx) SIZE) 0) #f ; if it's on the right edge, #f + (list (- idx (sub1 SIZE)) (+ idx (add1 SIZE)) (add1 idx))) + (list (- idx SIZE) (+ idx SIZE))))))) + +(define (flash grid tens seent flash-count) ; recursively flash tens + (for-each (λ (i) (hash-set! seent i #t)) tens) ; mark these tens as having been seen + (let* ([ns (flatten (map neighbors tens))] ; find all the neighbors of the tens + [ns-filtered (filter (λ (i) (not (hash-has-key? seent i))) ns)] ; filter out the ones we've flashed + [new-flash-count (+ flash-count (length tens))]) + (for-each (λ (i) (vector-set! grid i (add1 (vector-ref grid i)))) ns-filtered) ; add 1 to all the neighbors + (let* ([new-tens (remove-duplicates (filter (λ (x) (<= 10 (vector-ref grid x))) ns-filtered))]) + (if (< 0 (length new-tens)) + (flash grid new-tens seent new-flash-count) ; if so, flash em + (list new-flash-count (vector-map! (λ (x) (if (>= x 10) 0 x)) grid)))))) ; otherwise set our 10s to 0 and return the vector + +(define (vector-find vect proc) ; returns list of indicies where val is found in vect + (foldr (λ (i acc) (if (proc (vector-ref vect i)) (cons i acc) acc)) '() (range 0 (* SIZE SIZE)))) + +(define (step grid) ; grid is actually '(count grid).... + (let* ([g (second grid)] + [flash-count (first grid)] + [incd (vector-map add1 g)] + [seent (make-hash)] + [tens (vector-find incd (λ (n) (>= n 10)))] + [res (flash incd tens seent flash-count)]) + res)) + +(define part1 + (let loop ([n 100] [g grid] [flash-count 0]) + (if (= n 0) + (list g flash-count) + (let* ([res (step (list flash-count g))] + [new-count (first res)] + [new-grid (second res)]) + (loop (sub1 n) new-grid new-count))))) + +part1 +(display-grid (first part1)) + +(define (all-flashing? grid) + (= 100 + (vector-length (vector-filter (λ (x) (= x 0)) grid)))) + +(define part2 + (+ 1 (let loop ([n 0] [g grid] [flash-count 0]) + (let* ([res (step (list flash-count g))] + [new-count (first res)] + [new-grid (second res)]) + (if (all-flashing? new-grid) + n + (loop (add1 n) new-grid new-count)))))) + +part2 \ No newline at end of file diff --git a/day11.test.txt b/day11.test.txt new file mode 100644 index 0000000..03743f6 --- /dev/null +++ b/day11.test.txt @@ -0,0 +1,10 @@ +5483143223 +2745854711 +5264556173 +6141336146 +6357385478 +4167524645 +2176841721 +6882881134 +4846848554 +5283751526 diff --git a/day11.txt b/day11.txt new file mode 100644 index 0000000..a769718 --- /dev/null +++ b/day11.txt @@ -0,0 +1,10 @@ +4438624262 +6263251864 +2618812434 +2134264565 +1815131247 +2612457325 +8585767584 +7217134556 +2825456563 +8248473584 diff --git a/day12.rkt b/day12.rkt new file mode 100644 index 0000000..a57bce3 --- /dev/null +++ b/day12.rkt @@ -0,0 +1,50 @@ +#lang racket + +(define connections + (map (λ (s) (string-split s "-")) + (file->lines "day12.txt"))) + +(define (small-cave? cave) + (and (equal? (string-downcase cave) cave) + (not (equal? cave "start")))) + +(define (find-connections cns cave) + (filter (λ (x) (not (equal? "start" x))) + (append (map second (filter (λ (x) (equal? cave (first x))) cns)) + (map first (filter (λ (x) (equal? cave (second x))) cns))))) + +(define (go cns cave seent) + (define nexts (find-connections cns cave)) ; find every cave you can reach next from node + (define unvisited (filter (λ (x) (not (member x seent))) nexts)) ; filter out the caves we've seen't + (define new-seent (if (small-cave? cave) (cons cave seent) seent)) ; if it's a small cave, add it to the seen't list + (define paths (map (λ (x) (go cns x new-seent)) unvisited)) ; recurse over all of the connections + (cons cave (if (equal? "end" cave) ; if we've reach the end.. + '() ; don't go back up the tree + paths))) + +(define part1 + (let* ([tree (go connections "start" '())] + [flat (flatten tree)] + [ends (length (filter (λ (x) (equal? "end" x)) flat))]) + ends)) + +part1 + +; PART 2 + +(define (go2 cns cave seent revisitable) + (define nexts (find-connections cns cave)) ; find every cave you can reach next from node + (define new-seent (if (small-cave? cave) (cons cave seent) seent)) + (if (equal? "end" cave) + 1 ; add one when we get to the end + (foldl (λ (x acc) (+ acc (if (and (member x new-seent) revisitable) ; if it's a small cave, and we haven't revisited yet + (go2 cns x new-seent #f) ; recurse setting revisitable to #f + (if (not (member x seent)) ; otherwise, if we hadn't seen it yet + (go2 cns x new-seent revisitable) ; recurse + 0)))) ; otherwise, it doesn't end. add 0 + 0 nexts))) + +(define part2 + (go2 connections "start" '() #t)) + +part2 \ No newline at end of file diff --git a/day12.test.txt b/day12.test.txt new file mode 100644 index 0000000..6fd8c41 --- /dev/null +++ b/day12.test.txt @@ -0,0 +1,7 @@ +start-A +start-b +A-c +A-b +b-d +A-end +b-end diff --git a/day12.txt b/day12.txt new file mode 100644 index 0000000..f60a240 --- /dev/null +++ b/day12.txt @@ -0,0 +1,26 @@ +CV-mk +gm-IK +sk-gm +ca-sk +sx-mk +gm-start +sx-ca +kt-sk +ca-VS +kt-ml +kt-ca +mk-IK +end-sx +end-sk +gy-sx +end-ca +ca-ml +gm-CV +sx-kt +start-CV +IK-start +CV-kt +ml-mk +ml-CV +ml-gm +ml-IK diff --git a/day13.rkt b/day13.rkt new file mode 100644 index 0000000..6e915bf --- /dev/null +++ b/day13.rkt @@ -0,0 +1,52 @@ +#lang racket + +(define (map-map f lst) ; map . map + (map (λ (x) (map (λ (y) (f y)) x)) lst)) + +(define data + (let* ([input (file->lines "day13.txt")] + [point-lines (filter (λ (l) (string-contains? l ",")) input)] + [points (map-map string->number (map (λ (p) (string-split p ",")) point-lines))] ; e.g. '(6 10) + [fold-lines (filter (λ (l) (string-contains? l "fold")) input)] + [folds (map (λ (l) (let* ([matches (regexp-match #rx"(.)=(.+)" l)]) ; e.g. '("y" 7) + (list (second matches) (string->number (third matches))))) fold-lines)]) + (list points folds))) + +(define points (first data)) +(define folds (second data)) + +(define (draw points) + (let* ([width (apply max (map first points))] [height (apply max (map second points))]) + (for-each (λ (row) (begin + (for-each (λ (col) (printf "~a" (if (member (list col row) points) "#" "."))) (range 0 (+ 1 width))) + (printf "~n"))) (range 0 (+ 1 height))))) + +(define (move-point point dir loc) + (let* ([which (if (equal? "x" dir) first second)] ; which coordinate to change. x -> fold left -> change the first digit, etc. + [diff (* 2 (- (which point) loc))] ; calculate the amount the point should move left/up + [diffX (if (equal? "x" dir) (λ (x) (- x diff)) identity)] + [diffY (if (equal? "y" dir) (λ (x) (- x diff)) identity)]) + (if (< (which point) loc) ; if it is below the fold + point ; just return it + (list (diffX (first point)) (diffY (second point)))))) ; otherwise, move the point + +(define (fold points f) ; should have picked a different name.. + (let* ([direction (first f)] + [location (second f)] + [new-points (map (λ (point) (move-point point direction location)) points)]) + (remove-duplicates new-points))) + +(define part1 + (let* ([first-fold (first folds)] + [next (fold points first-fold)]) + (length next))) + +part1 + +; PART 2 + +(define part2 + (draw + (foldl (λ (f sheet) (fold sheet f)) points folds))) + +part2 \ No newline at end of file diff --git a/day13.test.txt b/day13.test.txt new file mode 100644 index 0000000..282114c --- /dev/null +++ b/day13.test.txt @@ -0,0 +1,21 @@ +6,10 +0,14 +9,10 +0,3 +10,4 +4,11 +6,0 +6,12 +4,1 +0,13 +10,12 +3,4 +3,0 +8,4 +1,10 +2,14 +8,10 +9,0 + +fold along y=7 +fold along x=5 diff --git a/day13.txt b/day13.txt new file mode 100644 index 0000000..63d24c5 --- /dev/null +++ b/day13.txt @@ -0,0 +1,840 @@ +602,683 +1297,593 +1118,603 +534,850 +221,383 +524,835 +735,194 +117,872 +1233,648 +1160,509 +278,558 +20,697 +622,675 +60,217 +120,460 +296,505 +206,29 +20,131 +73,791 +1014,535 +708,473 +1042,371 +1243,672 +1197,798 +1218,586 +62,885 +48,843 +880,170 +788,729 +816,401 +969,47 +1119,567 +335,721 +160,45 +718,120 +666,427 +295,815 +850,109 +1208,618 +388,427 +177,481 +149,481 +676,197 +216,708 +646,696 +206,546 +641,749 +242,353 +1250,421 +520,568 +234,614 +1218,308 +817,579 +934,586 +84,737 +244,676 +1208,564 +1220,409 +473,665 +426,740 +1118,792 +928,201 +1061,213 +577,200 +862,641 +892,492 +150,201 +898,322 +641,847 +848,703 +392,329 +1266,341 +228,712 +494,493 +838,271 +1148,778 +1146,86 +493,91 +1126,105 +576,551 +234,651 +838,267 +561,502 +606,801 +1062,521 +1074,402 +166,45 +460,480 +1308,103 +1067,476 +1250,116 +15,592 +865,358 +979,121 +1014,743 +848,102 +1198,311 +120,253 +358,599 +316,299 +520,326 +1116,148 +1160,201 +880,778 +736,295 +335,173 +438,809 +1178,544 +74,565 +902,659 +831,859 +564,185 +776,44 +376,275 +125,812 +922,330 +130,205 +671,317 +92,308 +295,303 +771,744 +492,534 +380,840 +902,683 +65,86 +887,448 +1032,765 +120,641 +488,339 +1293,23 +733,470 +952,595 +909,831 +99,642 +166,555 +922,841 +1118,352 +191,719 +401,735 +652,791 +131,255 +18,827 +1000,488 +1178,527 +850,480 +474,712 +232,562 +294,185 +539,744 +395,105 +776,64 +231,253 +1292,382 +954,408 +488,401 +382,649 +842,427 +634,131 +150,649 +1302,827 +462,792 +1148,116 +262,742 +716,217 +729,159 +425,366 +463,175 +1044,427 +1228,703 +668,61 +1294,854 +1062,373 +79,194 +296,702 +659,243 +773,872 +806,833 +671,302 +686,299 +480,722 +88,75 +92,243 +882,607 +850,253 +1012,856 +1032,250 +410,71 +142,789 +1262,597 +647,397 +622,877 +160,712 +646,205 +1108,885 +582,575 +771,150 +624,299 +411,726 +132,445 +505,861 +376,558 +974,56 +132,320 +877,635 +624,254 +629,689 +746,402 +1114,129 +815,848 +298,67 +1056,716 +356,255 +356,827 +624,147 +216,123 +142,341 +900,218 +910,709 +1168,789 +954,827 +818,330 +492,360 +629,17 +664,319 +602,435 +196,241 +974,491 +970,285 +350,75 +1299,894 +1285,205 +884,488 +72,166 +1168,322 +370,178 +1280,819 +1220,485 +321,844 +95,357 +90,485 +77,470 +8,67 +298,603 +934,308 +644,369 +192,191 +248,359 +575,334 +298,291 +62,120 +100,288 +903,642 +147,543 +898,775 +1178,599 +719,476 +1062,7 +1118,827 +1118,219 +708,883 +401,831 +1295,78 +917,178 +472,715 +885,528 +102,134 +1116,752 +3,46 +1118,675 +1081,156 +22,371 +184,789 +1015,591 +644,427 +417,343 +1307,46 +755,866 +954,255 +325,159 +151,213 +32,877 +1210,288 +1119,623 +82,683 +60,778 +989,50 +348,322 +708,683 +278,765 +336,295 +733,694 +560,292 +564,402 +1049,758 +1094,771 +412,322 +1044,521 +900,659 +1245,30 +1290,770 +509,247 +576,103 +686,75 +705,574 +110,339 +934,619 +676,763 +294,644 +192,827 +124,457 +231,701 +1076,243 +102,842 +192,281 +1193,134 +788,165 +736,31 +1084,607 +1114,241 +1009,205 +1094,533 +336,765 +102,564 +458,241 +838,715 +214,815 +684,774 +175,859 +676,131 +838,579 +406,821 +249,213 +855,806 +848,227 +1222,75 +1116,253 +214,729 +32,628 +1168,372 +295,79 +393,30 +1114,404 +1033,320 +1245,86 +734,343 +1216,292 +602,473 +807,651 +520,165 +1140,397 +151,651 +504,649 +1213,366 +918,565 +263,777 +600,693 +326,723 +336,129 +571,642 +1232,723 +130,59 +783,582 +107,757 +1057,894 +1218,651 +1250,217 +167,885 +1033,126 +562,19 +191,175 +848,542 +181,199 +1280,864 +769,684 +1193,872 +1098,653 +1198,79 +1159,651 +562,586 +458,404 +1168,329 +248,439 +624,523 +1200,339 +406,535 +544,85 +584,301 +435,842 +571,54 +512,372 +651,243 +1034,600 +132,747 +756,158 +771,879 +537,648 +922,229 +227,700 +676,770 +1180,689 +769,798 +1068,289 +310,488 +130,891 +1047,441 +401,63 +1089,383 +952,702 +749,392 +134,326 +410,676 +1101,694 +18,830 +594,105 +440,815 +82,703 +460,871 +1176,326 +758,564 +818,116 +160,849 +807,203 +102,276 +221,831 +1145,222 +8,632 +965,871 +1175,175 +577,718 +60,116 +1036,449 +790,568 +52,446 +1012,603 +1089,259 +766,533 +1048,742 +602,11 +880,676 +716,116 +569,437 +94,12 +975,173 +102,341 +509,329 +360,560 +718,774 +142,249 +329,735 +12,61 +316,859 +84,775 +838,495 +43,117 +492,116 +592,774 +787,527 +488,567 +534,460 +932,294 +606,93 +227,553 +602,448 +458,852 +248,887 +1250,373 +602,813 +1233,669 +524,675 +1232,171 +1096,135 +328,310 +917,30 +1278,266 +20,763 +644,817 +1278,877 +1036,445 +462,227 +1226,775 +594,169 +1036,813 +472,271 +433,259 +918,329 +962,315 +840,789 +595,35 +1280,613 +194,253 +962,572 +733,1 +1175,551 +726,301 +52,11 +1295,592 +885,156 +214,135 +1144,45 +676,579 +552,217 +639,86 +716,677 +458,42 +294,485 +425,290 +594,725 +1068,353 +728,575 +719,418 +1302,487 +974,151 +527,582 +987,121 +333,498 +212,138 +1064,843 +1226,723 +900,823 +209,200 +969,369 +1116,673 +175,707 +32,516 +1268,121 +880,249 +1133,145 +875,894 +1150,45 +1077,726 +1091,757 +1238,268 +221,187 +571,28 +77,225 +219,620 +1086,329 +102,330 +984,275 +156,721 +95,607 +1232,383 +728,709 +271,506 +160,182 +97,696 +296,432 +167,9 +224,106 +1128,579 +740,801 +974,743 +1101,200 +196,490 +705,350 +818,267 +209,694 +1292,399 +837,665 +1303,845 +107,836 +428,793 +733,893 +440,576 +323,773 +162,778 +734,882 +296,417 +1150,182 +1280,371 +268,523 +1211,252 +472,267 +1213,528 +786,891 +629,205 +985,159 +428,607 +852,490 +82,647 +231,0 +25,689 +459,703 +1208,330 +28,588 +1057,103 +199,88 +430,170 +395,789 +805,861 +62,437 +788,126 +130,577 +338,747 +904,551 +733,718 +816,600 +195,703 +974,407 +356,603 +1193,806 +602,367 +674,67 +1262,51 +1203,757 +773,22 +887,446 +1044,467 +2,551 +591,453 +102,106 +581,287 +723,131 +651,651 +716,105 +242,373 +308,719 +1208,665 +1036,459 +710,649 +664,696 +1076,84 +1216,602 +1178,449 +828,408 +54,245 +554,549 +10,525 +728,319 +734,103 +30,96 +1228,683 +960,75 +768,583 +1144,339 +331,121 +298,186 +1160,833 +472,623 +341,47 +624,371 +433,635 +1066,683 +1042,523 +1298,61 +90,492 +1039,670 +626,120 +1278,516 +112,79 +54,201 +410,659 +996,285 +524,219 +60,617 +1086,149 +830,620 +534,512 +805,33 +1290,197 +410,218 +1196,821 +129,15 +430,676 +986,847 +1303,49 +1210,345 +1154,397 +1067,418 +321,50 +740,871 +1268,684 +816,787 +534,64 +750,292 +412,775 +376,308 +301,205 +482,486 +1079,253 +1104,796 +534,253 +1159,691 +151,233 +740,775 +1126,789 +535,588 +296,295 +1258,473 +192,352 +410,255 +336,39 +1220,709 +1079,894 +1111,88 +473,199 +1056,166 +166,742 +494,271 +1248,550 +1089,187 +1054,476 +1208,553 +1215,565 +1044,564 +160,555 +132,893 +681,877 +831,187 +577,1 +8,262 +398,749 +892,402 +1082,182 +1156,498 +984,723 +318,151 +423,448 +391,441 +806,385 +1133,481 +298,197 +594,217 +1292,64 +418,492 +1238,136 +1226,23 +1215,537 +147,95 +1237,791 +1036,670 +684,421 +1280,23 +266,521 +1091,274 +589,86 +1208,394 +1119,719 +78,723 +135,343 +1261,126 +80,683 +940,268 +65,850 +234,691 +400,716 +1048,210 +32,334 +927,388 +821,222 +758,106 +196,129 +1135,651 +890,467 +93,392 +1158,620 +8,39 +715,35 +806,201 +97,366 +997,847 +438,634 +246,683 +102,394 +60,169 +10,77 +1082,712 +488,493 +370,268 +156,397 +1218,728 +30,595 +77,246 +107,137 +904,535 +987,773 +344,406 +1308,551 +324,847 +348,315 +1118,281 +1278,334 +658,103 +426,236 +462,165 +426,658 +659,46 +1168,645 +972,77 +406,73 +42,684 +1014,505 +226,607 +8,407 +728,185 +313,847 +1178,893 +1166,399 +848,729 +452,9 +542,352 +1280,595 +524,689 +105,259 +1068,745 +1081,80 +639,368 +756,233 +639,317 +92,586 +1116,221 +112,718 +624,747 +1233,1 +1215,607 +1039,388 +382,245 +1295,86 +582,185 +952,599 +440,191 +458,689 +62,550 +186,467 +1084,287 +1245,416 +790,820 + +fold along x=655 +fold along y=447 +fold along x=327 +fold along y=223 +fold along x=163 +fold along y=111 +fold along x=81 +fold along y=55 +fold along x=40 +fold along y=27 +fold along y=13 +fold along y=6 diff --git a/day14.rkt b/day14.rkt new file mode 100644 index 0000000..5e58fa6 --- /dev/null +++ b/day14.rkt @@ -0,0 +1,104 @@ +#lang racket + +(define input + (let* ([lines (file->lines "day14.txt")] + [template (first lines)] + [rule-strings (drop lines 2)] + [rules (map (λ (rs) (string-split rs " -> ")) rule-strings)]) + (list template rules))) + +(define template (first input)) +(define rules (second input)) + +(define (find-pairs template) + (reverse + (foldl (λ (el acc) (cons (substring template el (+ 2 el)) acc)) + '() + (range 0 (sub1 (string-length template)))))) + +(define (find-inserts pairs rules) + (map (λ (p) (second (assoc p rules))) pairs)) + +(define (insert-pairs template inserts) + (foldl (λ (idx acc) + (let* ([x (string (string-ref template idx))] + [insert (list-ref (append inserts (list "")) idx)]) + (string-append acc x insert))) + "" (range 0 (string-length template)))) + +(define (step template rules) + (let* ([pairs (find-pairs template)] + [inserts (find-inserts pairs rules)] + [next (insert-pairs template inserts)]) + next)) + +(define (element-counts str) + (let* ([lst (map string (string->list str))] + [ht (make-hash)]) + (for-each (λ (x) (hash-set! ht x (+ 1 (hash-ref ht x 0)))) lst) + ht)) + +(define part1 + (let* ([final (foldl (λ (i acc) (step acc rules)) template (range 0 10))] + [counts (element-counts final)] + [values (hash-values counts)] + [minimum (apply min values)] + [maximum (apply max values)] + [diff (- maximum minimum)]) + diff)) + +part1 + +; PART 2 +; uhoh. start over + +(define (inc-hash ht key amount) + (hash-set! ht key (+ amount (hash-ref! ht key 0)))) + +(define (dec-hash ht key amount) + (hash-set! ht key (- (hash-ref! ht key 0) amount))) + +(define (step2 ht) + (define pairs (filter (λ (p) (> (cdr p) 0)) (hash->list ht))) + (for-each (λ (pair-and-count) + (let* ([pair (car pair-and-count)] + [count (cdr pair-and-count)] + [ins (second (assoc pair rules))] + [new1 (string-append (substring pair 0 1) ins)] + [new2 (string-append ins (substring pair 1 2))]) + (inc-hash ht new1 count) + (inc-hash ht new2 count) + (dec-hash ht pair count))) + pairs) + ht) + +(define (pairs->element-counts ht) + (let* ([el-ht (make-hash)] + [pair-counts (hash->list ht)]) + (for-each (λ (p) (let* ([pair (car p)] + [el1 (substring pair 0 1)] + [el2 (substring pair 1 2)] + [count (cdr p)]) + (inc-hash el-ht el1 count) + (inc-hash el-ht el2 count))) + pair-counts) + el-ht)) + +(define part2 + (let* ([ht (make-hash)] + [pairs (find-pairs template)]) ; find the initial pairs in the template + (for-each (λ (pair) (inc-hash ht pair 1)) pairs) ; add them to the hash table + (let* ([res (foldl (λ (el acc) (step2 acc)) ht (range 0 40))] ; step! + [el-counts (pairs->element-counts res)] + [first-char (substring template 0 1)] + [last-char (substring template (sub1 (string-length template)))]) + (inc-hash el-counts first-char 1) ; add the first.. + (inc-hash el-counts last-char 1) ; and last chars twice.. + (let* ([lst (hash-map el-counts (λ (key val) (list key (/ val 2))))] ; then divide everything by 2 + [values (map second lst)] + [minimum (apply min values)] + [maximum (apply max values)] + [diff (- maximum minimum)]) + diff)))) + +part2 \ No newline at end of file diff --git a/day14.test.txt b/day14.test.txt new file mode 100644 index 0000000..b5594dd --- /dev/null +++ b/day14.test.txt @@ -0,0 +1,18 @@ +NNCB + +CH -> B +HH -> N +CB -> H +NH -> C +HB -> C +HC -> B +HN -> C +NN -> C +BH -> H +NC -> B +NB -> B +BN -> B +BB -> N +BC -> B +CC -> N +CN -> C diff --git a/day14.txt b/day14.txt new file mode 100644 index 0000000..56c7184 --- /dev/null +++ b/day14.txt @@ -0,0 +1,102 @@ +BNSOSBBKPCSCPKPOPNNK + +HH -> N +CO -> F +BC -> O +HN -> V +SV -> S +FS -> F +CV -> F +KN -> F +OP -> H +VN -> P +PF -> P +HP -> H +FK -> K +BS -> F +FP -> H +FN -> V +VV -> O +PS -> S +SK -> N +FF -> K +PK -> V +OF -> N +VP -> K +KB -> H +OV -> B +CH -> F +SF -> F +NH -> O +NC -> N +SP -> N +NN -> F +OK -> S +BB -> S +NK -> S +FH -> P +FC -> S +OB -> P +VS -> P +BF -> S +HC -> V +CK -> O +NP -> K +KV -> S +OS -> V +CF -> V +FB -> C +HO -> S +BV -> V +KS -> C +HB -> S +SO -> N +PH -> C +PN -> F +OC -> F +KO -> F +VF -> V +CS -> O +VK -> O +FV -> N +OO -> K +NS -> S +KK -> C +FO -> S +PV -> S +CN -> O +VC -> P +SS -> C +PO -> P +BN -> N +PB -> N +PC -> H +SH -> K +BH -> F +HK -> O +VB -> P +NV -> O +NB -> C +CP -> H +NO -> K +PP -> N +CC -> S +CB -> K +VH -> H +SC -> C +KC -> N +SB -> B +BP -> P +KP -> K +SN -> H +KF -> K +KH -> B +HV -> V +HS -> K +NF -> B +ON -> H +BO -> P +VO -> K +OH -> C +HF -> O +BK -> H diff --git a/day16.rkt b/day16.rkt new file mode 100644 index 0000000..ef29682 --- /dev/null +++ b/day16.rkt @@ -0,0 +1,152 @@ +#lang racket + +(define (string->string-list str) + (map string (string->list str))) + +;(define input "D2FE28") +;(define input "38006F45291200") +;(define input "EE00D40C823060") +;(define input "8A004A801A8002F478") +;(define input "620080001611562C8802118E34") +;(define input "C0015000016115A2E0802F182340") +;(define input "A0016C880162017C3686B18A3D4780") + +;(define input "C200B40A82") ; 1 + 2 +;(define input "04005AC33890") ; 6 * 9 +;(define input "880086C3E88112") ; min 7 8 9 +;(define input "CE00C43D881120") ; max 7 8 9 +;(define input "D8005AC2A8F0") ; 5 < 15 +;(define input "F600BC2D8F") ; 5 > 15 +;(define input "9C005AC2F8F0") ; 5 = 15 +;(define input "9C0141080250320F1802104A08") ; 1 + 3 = 2 * 2 + +(define input (first (file->lines "day16.txt"))) + +(define bins (list (list "0" "0000") + (list "1" "0001") + (list "2" "0010") + (list "3" "0011") + (list "4" "0100") + (list "5" "0101") + (list "6" "0110") + (list "7" "0111") + (list "8" "1000") + (list "9" "1001") + (list "A" "1010") + (list "B" "1011") + (list "C" "1100") + (list "D" "1101") + (list "E" "1110") + (list "F" "1111"))) + +(define (all-but-last lst) + (take lst (- (length lst) 1))) + +(define (h2b hex-str) ; todo make this suck less + (let* ([hex-list (string->string-list hex-str)] + [binary-list (map (λ (x) (second (assoc x bins))) hex-list)]) + (apply string-append binary-list))) + +(define (b2d bin-str) + (string->number bin-str 2)) + +(define versions (make-hash)) + +(define (parse-literal str) + (let* ([res (read-literal str)] + [len (string-length res)] + [rest (substring str (+ (/ len 4) len))] + [dec (b2d res)]) + ;(printf "parse-literal. returning: ~s~n" (list dec rest)) + (list dec rest))) + +(define (read-literal str) + ;(printf "read-literal ~s~n" str) + (let loop ([group str]) + (let* ([first (substring group 0 1)] + [next-four (substring group 1 5)] + [rest (substring group 5)]) + (if (equal? first "0") + next-four + (string-append next-four (loop rest)))))) + +(define (length-id-0 str) + (let* ([len (b2d (substring str 0 15))] + [inner (substring str 15 (+ 15 len))] + [rest (substring str (+ 15 len))] + ;[_ (printf "length-id-0 str: ~s len: ~s inner: ~s rest: ~s~n" str len inner rest)] + [res (parse-multiple inner)] + [res-value (all-but-last res)]) + (list res-value rest))) + +(define (parse-multiple str) + ;(printf "parse-multpile ~s~n" str) + (let loop ([group str]) + (let* ([res (parse group)] + [data (first res)] + [rest (second res)]) + ;(printf "parse-multiple loop res: ~s data: ~s rest: ~s~n" res data rest) + (if (= 0 (string-length rest)) + (list data rest) + (cons data (loop rest)))))) + +(define (length-id-1 str) + (let* ([num (b2d (substring str 0 11))] + [rest (substring str 11)] + ;[_ (printf "length-id-1. str: ~s num: ~s rest: ~s~n" str num rest)] + [res (parse-n rest num)]) + ;(printf "length-id-1 done. res: ~s~n" res) + res)) + +(define (parse-n str num) + ;(printf "parse-n ~s ~s~n" str num) + (let loop ([group str] + [n num]) + ;(printf "parse-n loop ~s ~s~n" group n) + (let* ([res (parse group)] + [data (first res)] + [rest (second res)]) + ;(printf "parse-n loop res: ~s data: ~s rest: ~s n: ~s~n" res data rest n) + (if (= 1 n) + (list data rest) + (cons data (loop rest (sub1 n))))))) + +(define (parse-operator str) + (let* ([length-type-id (substring str 0 1)]) + ;(printf "parse-operator ~s. length-type-id: ~s~n" str length-type-id) + (if (equal? length-type-id "0") + (length-id-0 (substring str 1)) + (length-id-1 (substring str 1))))) + +(define (gt x y) (if (> x y) 1 0)) +(define (lt x y) (if (< x y) 1 0)) +(define (eq x y) (if (equal? x y) 1 0)) + +(define (parse str) + ;(printf "parse ~s~n" str) + (let* ([version (substring str 0 3)] + [dec-version (b2d version)] + [type-id (substring str 3 6)] + [body (substring str 6)] + [op (cond [(equal? type-id "100") first] + [(equal? type-id "000") (λ (x) (apply + x))] + [(equal? type-id "001") (λ (x) (apply * x))] + [(equal? type-id "010") (λ (x) (apply min x))] + [(equal? type-id "011") (λ (x) (apply max x))] + [(equal? type-id "101") (λ (x) (gt (first x) (second x)))] + [(equal? type-id "110") (λ (x) (lt (first x) (second x)))] + [(equal? type-id "111") (λ (x) (eq (first x) (second x)))])] + [res-list ((if (equal? type-id "100") parse-literal parse-operator) body)] + [res (flatten (all-but-last res-list))] + [post-op (op res)] + [rest (last res-list)]) + ;(printf "bottom of parse. res: ~s rest: ~s post-op: ~s~n" res rest post-op) + (hash-set! versions 'count (+ dec-version (hash-ref! versions 'count 0))) + (list post-op rest))) + +(define go + (let* ([str (h2b input)]) + (first (parse str)))) + +go +versions \ No newline at end of file diff --git a/day16.txt b/day16.txt new file mode 100644 index 0000000..c108eef --- /dev/null +++ b/day16.txt @@ -0,0 +1 @@ +A052E04CFD9DC0249694F0A11EA2044E200E9266766AB004A525F86FFCDF4B25DFC401A20043A11C61838600FC678D51B8C0198910EA1200010B3EEA40246C974EF003331006619C26844200D414859049402D9CDA64BDEF3C4E623331FBCCA3E4DFBBFC79E4004DE96FC3B1EC6DE4298D5A1C8F98E45266745B382040191D0034539682F4E5A0B527FEB018029277C88E0039937D8ACCC6256092004165D36586CC013A008625A2D7394A5B1DE16C0E3004A8035200043220C5B838200EC4B8E315A6CEE6F3C3B9FFB8100994200CC59837108401989D056280803F1EA3C41130047003530004323DC3C860200EC4182F1CA7E452C01744A0A4FF6BBAE6A533BFCD1967A26E20124BE1920A4A6A613315511007A4A32BE9AE6B5CAD19E56BA1430053803341007E24C168A6200D46384318A6AAC8401907003EF2F7D70265EFAE04CCAB3801727C9EC94802AF92F493A8012D9EABB48BA3805D1B65756559231917B93A4B4B46009C91F600481254AF67A845BA56610400414E3090055525E849BE8010397439746400BC255EE5362136F72B4A4A7B721004A510A7370CCB37C2BA0010D3038600BE802937A429BD20C90CCC564EC40144E80213E2B3E2F3D9D6DB0803F2B005A731DC6C524A16B5F1C1D98EE006339009AB401AB0803108A12C2A00043A134228AB2DBDA00801EC061B080180057A88016404DA201206A00638014E0049801EC0309800AC20025B20080C600710058A60070003080006A4F566244012C4B204A83CB234C2244120080E6562446669025CD4802DA9A45F004658527FFEC720906008C996700397319DD7710596674004BE6A161283B09C802B0D00463AC9563C2B969F0E080182972E982F9718200D2E637DB16600341292D6D8A7F496800FD490BCDC68B33976A872E008C5F9DFD566490A14 diff --git a/day17.rkt b/day17.rkt new file mode 100644 index 0000000..edad495 --- /dev/null +++ b/day17.rkt @@ -0,0 +1,79 @@ +#lang racket + +(define target + (let* (;[input "target area: x=20..30, y=-10..-5"] + [input "target area: x=144..178, y=-100..-76"] + [regex #rx"x=([^\\.]+)\\.\\.([^\\.]+), y=([^\\.]+)\\.\\.([^\\.]+)"] + [matches (regexp-match regex input)] + [coords (drop matches 1)]) + (map string->number coords))) + +(define (point-in-target? point) + (match-let* ([(list x y) point] + [(list x1 x2 y1 y2) target]) + (and (>= x x1) (<= x x2) + (>= y y1) (<= y y2)))) + +(define (point-past-target? point) + (match-let* ([(list x y) point] + [(list x1 x2 y1 y2) target]) + (or (> x x2) (< y y1)))) + +(define (step point velocity) + (match-let ([(list x y) point] + [(list dx dy) velocity]) + (let* ([new-point (list (+ x dx) (+ y dy))] + [dx-op (if (= dx 0) identity (if (> dx 0) sub1 add1))] + [new-velocity (list (dx-op dx) (sub1 dy))]) + (values new-point new-velocity)))) + +(define (good-velocity? point velocity) + (if (point-in-target? point) + #t + (if (point-past-target? point) + #f + (let-values ([(p2 v2) (step point velocity)]) + (good-velocity? p2 v2))))) + +; shoot it as high as you can +; such that it never goes *below* the bottom of the target +; bottom of target: -10 in the example +; by the time it gets back to 0, dy is equal to -initial dy +; so.. initial dy can't be > -10? set it to 9 and find a valid x + +(define (find-max-velocity) + (let* ([dy (sub1 (* -1 (third target)))]) + (let loop ([dx 0]) + (if (good-velocity? '(0 0) (list dx dy)) + (list dx dy) + (loop (add1 dx)))))) + +(define (find-max-height velocity) + (let loop ([p '(0 0)] + [v velocity]) + (let-values ([(p2 v2) (step p v)]) + (if (= 0 (second v2)) + (second p2) + (loop p2 v2))))) + +(define part1 + (let* ([v (find-max-velocity)] + [height (find-max-height v)]) + height)) + +part1 + +; PART 2 + +(define part2 + (let* ([dy-max (* -1 (third target))] + [dy-min (* -1 dy-max)] + [dx-max (* 2 (second target))] + [all (apply append + (for/list ([dy (range dy-min dy-max)]) + (for/list ([dx (range 0 dx-max)]) + (list dx dy (good-velocity? '(0 0) (list dx dy))))))] + [goods (filter (λ (x) (third x)) all)]) + (length goods))) + +part2 \ No newline at end of file diff --git a/day8.rkt b/day8.rkt index 205cdac..ea5a4dd 100644 --- a/day8.rkt +++ b/day8.rkt @@ -22,17 +22,7 @@ part1 ; part 2 ; Can we just count the number of times a segment appears? -; From the example: -; -; a = 8 -; b = 6 -; c = 8 * dup -; d = 7 -; e = 4 -; f = 9 -; g = 7 * dup again -; -; So no. But it's still helpful. Naming the segments A - G +; No. Damn. But it gets us close. Naming the segments A - G ; ; A has 8 instances and IS NOT in 1 ; B has 6 instances @@ -90,4 +80,4 @@ part1 (define part2 (foldl (λ (l acc) (+ acc (line->number l))) 0 data)) -part2 \ No newline at end of file +part2 diff --git a/day9.rkt b/day9.rkt new file mode 100644 index 0000000..d2f039f --- /dev/null +++ b/day9.rkt @@ -0,0 +1,84 @@ +#lang racket + +(define (map-map f lst) ; map . map + (map (λ (x) (map (λ (y) (f y)) x)) lst)) + +(define (char->num chr) ; i hate this + (second (assoc chr (list '(#\0 0) '(#\1 1) '(#\2 2) '(#\3 3) '(#\4 4) '(#\5 5) '(#\6 6) '(#\7 7) '(#\8 8) '(#\9 9))))) + +(define grid ; file -> list of lists of numbers + (map-map char->num + (map string->list + (file->lines "day9.txt")))) + +(define (grid-value grid row col) ; value of grid at (row, col) + (if (or (< row 0) (> row (sub1 (length grid))) (< col 0) (> col (sub1 (length (first grid))))) ; if out of bounds + #f + (list-ref (list-ref grid row) col))) + +(define (neighbors grid row col) ; list of values of neighbors to (row, col) + (filter identity ; filter out #f + (list (grid-value grid row (sub1 col)) + (grid-value grid row (add1 col)) + (grid-value grid (sub1 row) col) + (grid-value grid (add1 row) col)))) + +(define (is-lowest? grid row col) ; is (row, col) a low point + (let ([ns (neighbors grid row col)] + [val (grid-value grid row col)]) + (foldl (λ (n acc) (and (< val n) acc)) #t ns))) + +(define (low-point-coords grid) ; list of all low point coordinates in the grid + (let ([width (length (first grid))] + [height (length grid)]) + (apply append ; flatten the list one level + (for/list ([row (range 0 height)]) ; using a for. i caved + (filter identity ; filter out #f + (for/list ([col (range 0 width)]) + (if (is-lowest? grid row col) + (list row col) + #f))))))) + +(define (low-point-values grid) ; the values of all of the low points in a grid + (let* ([points (low-point-coords grid)]) + (map (λ (p) (grid-value grid (first p) (second p))) points))) + +(define part1 + (let* ([points (low-point-values grid)] + [risk-levels (map add1 points)]) + (foldl + 0 risk-levels))) + +part1 + +; PART 2 + +(define (neighbors-coords row col) ; list of _coordinates_ of neighbors to (row, col) + (list + (list row (sub1 col)) + (list row (add1 col)) + (list (sub1 row) col) + (list (add1 row) col))) + +(define (find-basin-around-point grid row col) + (define visited (make-hash)) + (let loop ([r row] [c col]) + (let* ([ns (neighbors-coords r c)] ; get all the neighboring coordinates + [ns-to-visit (filter (λ (n) (and + (grid-value grid (first n) (second n)) ; filter out out-of-bounds + (not (equal? (grid-value grid (first n) (second n)) 9)) ; and 9s + (not (hash-ref visited n #f)))) ns)]) ; and the ones we've seen + (hash-set! visited (list r c) (grid-value grid r c)) ; add this to the list of coordinates we've visited + (for-each (λ (n) (loop (first n) (second n))) ns-to-visit) ; recurse over the neighbors + (hash->list visited)))) + +(define (find-all-basins grid) + (let* ([points (low-point-coords grid)]) + (map (λ (p) (find-basin-around-point grid (first p) (second p))) points))) + +(define part2 + (let* ([basins (find-all-basins grid)] + [top3 (take (sort basins (λ (x y) (> (length x) (length y)))) 3)] + [lengths (map length top3)]) + (foldl * 1 lengths))) + +part2 \ No newline at end of file diff --git a/day9.test.txt b/day9.test.txt new file mode 100644 index 0000000..6dee4a4 --- /dev/null +++ b/day9.test.txt @@ -0,0 +1,5 @@ +2199943210 +3987894921 +9856789892 +8767896789 +9899965678 diff --git a/day9.txt b/day9.txt new file mode 100644 index 0000000..6e3e84e --- /dev/null +++ b/day9.txt @@ -0,0 +1,100 @@ +7857679876545987643256789767894592129875432345678987543234598754567892349964345943210127899434954345 +6746567987796997664146789656953989349754321234799998999109989843467993498895659854322345678949893233 +5434458998989876543234599545899878998654320123678999878998975432358789987789798765563456899998789102 +4523347999978989854845678938798767999865431334567898965987654321345678965678969887678567943987678913 +3210156899866698766789789325679656799876565457678967994398775210123889323589943998789689659876568995 +6521238789654569977899999734569545689987897568989356789219885424344994214567892129899898798765456789 +7434345699943456998988997645698734567899998689396467896323965435656789105878964298901949899876569893 +6575656897899569879567998787987645678954349891296598985434597545669993216789995987912934978987679932 +7689787896798979967467899898998776789763212989987679876545698756778954323899989876899899867899889321 +8799898965987898652379997999319887898765343679998993997677789767889997434568979785679759878998995432 +9890969754346789743498985689929998969876954567899612398798999878997986545679765654349643989876799546 +6921349943235997655697674579898789456989895678996543459989989989876597876789654321238952099865688957 +5432677890196898766987543498766564349998789989989965569878979998765498997899766610177893198764567898 +6563456789989929877999432349654323298987678996569896698767767898754349898949877532456789299853466789 +9874569899878912988998921234965210197656588923456789987654356789895456789234998743767899985432345789 +5986798998767893499987990159874343299743486794578994596543246899976567890126789654879998976545456789 +4987987979878989598896889346989554987632375689689753987854345678997688921347899767989987987698578899 +3299876768989569987675679956987665696521234678999762598985457899998789435489965988999875698987679998 +2198765656795498795454567897898796985432345989689653459876578999989899876567894599998764529498789767 +4987654345694349654323479989999989876568656796577994967989789789865956989978953456989843213359895456 +5698963236589298765474589767898767987899978965466789878999896678954545792989432349876543101234976569 +7987892123478929898765678945698656898923989654245699989865934569532234891094310123998753219759897678 +9876431012567912999876789234987745769944598765656899992994325378931046979195465255999654398998789989 +2998542123878901987987892129876434657895679876787998901989101289542123468987654349898765987899699997 +0129656939989212396598943012965421347896890987898987899879312348953235779899799998769879895446599876 +1298789898994324987439984329876532456797951298989896798768993567894345698799987859897998654323478965 +2349898767965739876519876545997544587898942349876645987656789978999456998688976545976569785434567894 +6556987657899846987326987656789665688939993498965535698545678989898969887567997437895459876745678912 +7679876546798957899634898787899878999123989987854324987435789898767898765434589546942345998858989923 +9798765435677998998546799898999989932019876796543219876566796649656987654323578967921959219967895894 +9899985324576789987656789969789999893998765987632102989678895432347976543413489978949898939879976789 +5999764412345789999978898658679899789897544598543212398789976541239897632101257899998677899989999992 +4998743101789899999989999543498798676789432987654353459899987982349798543212345945989556789999987890 +9899654313599999898798998764987676565878941299765478967999999864598689955323969899876435678999876789 +9798774323458998789657869879996543454567890129876567898998999765987577896539898788987548789498765412 +7659885457667897697546556998999652123678921236987678999857899879875476789798767687898959892349974301 +8969986569789934589432345987898843016789432345698989999645989998764325678999654576789767921298765213 +9878997679899845678921239896987652145689543456789495878999879999875434789998793434599898932349654324 +7989898989998756789210198765698653235678964567994324567989767878996545898987672125678999654598765455 +6796789997569879898431259874789864356789986788965212789877653456789656997698543234799998765999986776 +4345679986456998987652349989899975456789998899976523499765442346678968989549765745678999879895697987 +3239798765345987899767898991998996767899899976595434598654321245567899679939876967989999998754569998 +4998998743229876788979977892987987979998789987989545679865410123456954567899987899798789439865678999 +9867897651013954567898765679896798989887679999878956798754321236569432978999899999657678913976789588 +8756789543129876779999976798795459998756568898767898899895435345678999899987652198745459904698893467 +7545679956789997889999989989689979876545459799956799989876546789989989799876543987832345799799942343 +4234567897893498999989898976567899987434345678945678978987678893299875678987959876421234678989431012 +3123499998912989568976797985498998654321236789136789357899899932129654567999899987210124569878942134 +4534589999109875477895986543387998767410147991045995212999978994298943478998799995341234678967899245 +6645679989212954356954397432136799878924756789127894329889765789987912345789678998532399989456898956 +8767789878999864167891298543245678989865667993236789498765634698976793456896567997543987894345987897 +9878896569989873298999987659656789899976798954345678999654323567895689597925457987659876789239976789 +9989956469878999349898798798767895789989899765766989998765212678954578989012349999769985679198765678 +8797643359767898956789659899889954578999999879878999979975323467953468978923498999898654568999654356 +7659451298656987999896543945999876899998799989989679865986654578921234569654987899987643247899875268 +8943210987649876789987969324567987899979569894394597654987785679210456678969976789999532126799994345 +9874349876436545899999898901234598998767498765213986543499898789431567899798765678998673035698765567 +8765456985321434578999767892345679987656349954323997432345999896542398927679876789987662129999898689 +9876567984310123678998756789459789897543234965549876541069899987665489312568999899876543298789959799 +6998779876321234789987545678998999789732179878699987432198789998796569103459878944998654397699649899 +5329899965435345679876434589237998698943467989989997543987678899898678923999965432139865987578932978 +9212999876547656989864323489456987567894588999878998659876545799959989549889876744014979876467894567 +8901987987956787998765434569569765456799679998767898767965434689345497698778989865923989989878975678 +7899876598767899899896545678998764345678989987656799979854324593212398987656197979894597694999989799 +6798765439878998789987756989998653234567893299549893298768435689323459987643236898789789543212399897 +5689876323989987698999897897987643123456999398767989349976566795434567899765345797678997659865459976 +4768993212398634567897998976698431014597898999878978956987789999595978949876459986567798767986598785 +3656789325987545678976579654569542198789967899989657898999891298989899234987898875435699878997999654 +2345679434597656989865457993498674599895456789994345999997910987678789199898987654323989999109897743 +9456898995679878999974325689598788789944345699875467899876329876545698989769398543219878889298765432 +8967997889799999999989434578959999895321234589976799923995498768434567979653239876498956778999876321 +7898986678989319988996546989732012943210165678997891014986987654321345767992123987987434567899987210 +6569975454878998767897999997653223959323456989898989123987898773210123459989344899876123456789974323 +5498764343568989856989878989885439898965567899769678934598959765621245768979956798985012345678965434 +4329873212345678934976965678976599767896898997654569945679349878854359879567897987654126787789878545 +5497983101296789129865134569988987656799999898763456797895219989976567993456899698643245698999989967 +6986543212989993298754245678999876545678996789432345898994398999987678912345798549954356999578998798 +7897765329979894359765657989798765434799874896544578919989497989999789923456796539865677899989987689 +8959875498767799459878768995679877321898763789655789329878976878999899894667987621979788989999876598 +9245986997658678967989899434899943210989654678966898999867864567897998789779998710989899878999988987 +9967899876546567898992990123799994332378969989878967789956323456795498678989899931296999769889999876 +9898902995423488959101989235698989944569998799989555698743212345899987567896789892345987658778999975 +8789899875212679543219878946987869895878997689995434987652101596998795456965679793459876543567898764 +7678789984343789954398767899876556789989876578976720198763212678987654357894565689567987652489999753 +6565678995458997895987656678997435678997535459987631679874343489398965457893434578979876543459998764 +6434569998767896789895434567954323459789421299876543567989654799569896767952123456893998654598989978 +5323456789878945998754323459873212355694320678987654689998765678998789899543234567892198766987778999 +4212378999989239876543212398765101234589431489998765999999896789987678978954345678963019879876567889 +2103569129894345998632101239954323445678932378929879899889987899876589667895656789954198998767452878 +3414678998795456896549543398765654756789965469434998768779998953987334556996778999865987869654321267 +4925789987689987987698994999878965678999876589546987654667899932993212346889899432978986759769834346 +9896789764567898998997789899989876789897987678959896543558999899854301235678989543989975345998765756 +6789897643476799109976678788997987896796599789998765432445898798765472345789678959899894234599879877 +5678975432125689398765567677896498965989434999987654321234789679876567887896567899798753145689989988 +4567996645054578987654323456954329254578923459876543210123689543987879998987378965699432015678998999 +3456789752123567898765104569543210123469212369987656521234597652398989879998567894987653123789567789 +2127897654345878949874325678998323345578903578998867432345689321239998969999678943499868944695465698 +4578998765456789234965456789976534559679214678959998553456789875347897657898789452349979855894324567 +5689439877677890125987767894987865698789325889546799767868895987656789545689894321348998766893212398 +6789521998889921236799878923598978999895456789634569878978934599867996534899943210767999987964323569