From 80e48c29c6001122f9c853a03883aab9403ab798 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Fri, 10 Dec 2021 16:29:28 +0000 Subject: [PATCH] Done day 10 --- advent-of-code21.cabal | 5 + advent09/Main.hs | 3 - advent10/Main.hs | 93 +++++++++++++++++++ data/advent10.txt | 102 +++++++++++++++++++++ data/advent10a.txt | 10 ++ problems/day09.html | 168 ++++++++++++++++++++++++++++++++++ problems/day10.html | 201 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 579 insertions(+), 3 deletions(-) create mode 100644 advent10/Main.hs create mode 100644 data/advent10.txt create mode 100644 data/advent10a.txt create mode 100644 problems/day09.html create mode 100644 problems/day10.html diff --git a/advent-of-code21.cabal b/advent-of-code21.cabal index d7c0fa8..626e0ae 100644 --- a/advent-of-code21.cabal +++ b/advent-of-code21.cabal @@ -129,3 +129,8 @@ executable advent09 import: common-extensions, build-directives main-is: advent09/Main.hs build-depends: array, containers, linear + +executable advent10 + import: common-extensions, build-directives + main-is: advent10/Main.hs + build-depends: containers diff --git a/advent09/Main.hs b/advent09/Main.hs index a5c4ccc..df5b1be 100644 --- a/advent09/Main.hs +++ b/advent09/Main.hs @@ -15,7 +15,6 @@ main :: IO () main = do text <- readFile "data/advent09a.txt" let grid = mkGrid text - print $ bounds grid print $ part1 grid print $ part2 grid @@ -64,10 +63,8 @@ breadthFirstSearch grid agenda basin else S.insert here basin agenda' = S.union candidates $ S.delete here agenda - neighbours :: Grid -> Coord -> [Coord] neighbours grid here = filter (inRange (bounds grid)) [ here ^+^ delta | delta <- [V2 -1 0, V2 1 0, V2 0 -1, V2 0 1] ] - diff --git a/advent10/Main.hs b/advent10/Main.hs new file mode 100644 index 0000000..fea8a99 --- /dev/null +++ b/advent10/Main.hs @@ -0,0 +1,93 @@ +-- Writeup at https://work.njae.me.uk/2021/12/10/advent-of-code-2021-day-10/ + +import qualified Data.Map.Strict as M +import Data.List + +-- data ParseState = ParseState [Char] String -- expected closer stack, remaining text + +data ParseResult = Complete String -- remaining text + | Incomplete [Char] -- remaining closing chars + | Corrupted [Char] String -- remaining closing chars, remaining text + deriving (Eq, Ord, Show) + +closingChars :: M.Map Char Char +closingChars = M.fromList + [ ('(', ')') + , ('[', ']') + , ('{', '}') + , ('<', '>') + ] + +main :: IO () +main = + do text <- readFile "data/advent10.txt" + let commands = lines text + let parsedCommands = map parseLine commands + print $ part1 parsedCommands + print $ part2 parsedCommands + +part1 :: [ParseResult] -> Int +part1 parsedCommands = sum $ map scoreIllegal corruptChar + where corrupts = filter isCorrupt parsedCommands + corruptChar = map extractCorrupt corrupts + +part2 :: [ParseResult] -> Int +part2 parsedCommands = sortedScores !! (length scores `div` 2) + where scores = map scoreIncompleteString $ filter isIncomplete parsedCommands + sortedScores = sort scores + +isCorrupt :: ParseResult -> Bool +isCorrupt (Corrupted _ _) = True +isCorrupt _ = False + +isIncomplete :: ParseResult -> Bool +isIncomplete (Incomplete _) = True +isIncomplete _ = False + +extractCorrupt :: ParseResult -> Char +extractCorrupt (Corrupted _ (c:_)) = c +extractCorrupt _ = ' ' + +scoreIllegal :: Char -> Int +scoreIllegal ')' = 3 +scoreIllegal ']' = 57 +scoreIllegal '}' = 1197 +scoreIllegal '>' = 25137 +scoreIllegal _ = 0 + +scoreIncomplete :: Char -> Int +scoreIncomplete ')' = 1 +scoreIncomplete ']' = 2 +scoreIncomplete '}' = 3 +scoreIncomplete '>' = 4 +scoreIncomplete _ = 0 + +scoreIncompleteString :: ParseResult -> Int +scoreIncompleteString (Incomplete chars) = foldl' buildScore 0 $ map scoreIncomplete chars + where buildScore total this = total * 5 + this +scoreIncompleteString _ = 0 + + +parseLine :: String -> ParseResult +parseLine [] = Complete "" +parseLine command = case chunk of + Complete remaining -> parseLine remaining + _ -> chunk + where chunk = parseChunk0 command + +parseChunk0 :: String -> ParseResult +parseChunk0 [] = Complete "" +parseChunk0 (next:remaining) = case M.lookup next closingChars of + Just nextCloser -> parseChunk [nextCloser] remaining + Nothing -> Corrupted [] (next:remaining) + +parseChunk :: [Char] -> String -> ParseResult +parseChunk [] remaining = Complete remaining +parseChunk stack [] = Incomplete stack +parseChunk (closer:stack) (next:remaining) + | next == closer = parseChunk stack remaining -- expected closing character + | otherwise = case M.lookup next closingChars of + -- next is a new opening character + Just nextCloser -> parseChunk (nextCloser:closer:stack) remaining + -- wrong character + Nothing -> Corrupted (closer:stack) (next:remaining) diff --git a/data/advent10.txt b/data/advent10.txt new file mode 100644 index 0000000..deb0613 --- /dev/null +++ b/data/advent10.txt @@ -0,0 +1,102 @@ +([<{(<{(({<{{{[]<>}<<>()>}<<()()>[()()])}{({()[]}[<>{}])<(<><>)<[]{}>>}>{{((()<>)<[]()>)[{[]<>}(()[])] +<<[[<[(<[<[[[{()<>}(<>{})]]][{(<{}{}>(<>))[[<>](<><>)]}[({{}<>}<[]()>){<{}{}>[{}[]]}]]><{(<([][] +{<([[[({{(<[([{}<>]<{}{}>)[[<>[]]]]{{(()<>)[()]}}>){((([{}<>]{[]{}})<<[][]><<>{}>>){([[]{}]<<>()>){ +{{[{({{(({<[<{[]{}](<>)>][<(()[])(()[])>[[<>{}](<>())]]><<([{}]{{}{}})[{[]}{{}[]}]>[{<()<>><<>>}]> +(<<<[(({[[[{<[{}<>]{<><>}><({})>}{{{()}{(){}}}}][{[({}{})[<><>]]<({}[])[()()]>}(<([]<>)<[]( +<[{[((<<[[<[({[]()}{(){}})[{<>[]}<()()>]]>]]<[{{[[[][]]<[]()>][<<>{}><<><>>]}}({[<[]()><{}[]>]{<[] +(({((({{[[(([<[]<>>(())]{{()<>}<<>[]>}))]]([<([{{}()}(<>{})][({}<>)])>](({{<()<>>[{}())}{((){}){[]()}}}) +({{({(<<{<<([<{}>])(<[()<>][{}[])>{[()()][{}{}]})>[[[{{}[]}[(){}]][{<>{}}{()<>}]]({<<>[]>{{ +<[<<{[(<{[{({({}[])(()[])}[{{}<>}{{}<>}]){<{<>[]}[<>()]>{<{}()>}}}{{{{()()}}[{{}<>}({}<>)]}}}}>{{[[{<[ +[{([<{{<<<[([<[]()>])]([{{<>{}}}{(()[])[<>[]]}])><[(<{()<>}{<>}>[([]{})<<>{}>]}([{()<>}({}[])]<<{}[]>({}{} +<([<([{{<<{<(([]<>)<{}{}>)>({[(){}]}((<>[])<{}[]>))}<{<(()[])<[]>>({[][]}(()[]))}(<{()[]}{[]()}})>>[([({()[ +{{{[({(<[{[[{{()<>}[<>()]}{({}<>)<{}()>}]{{[()()][(){}]}[{<>()}]}]}]>)(({<<(({{}<>}([]<>))({<>[]}<[]{ +({{({<([{[{{[[[]()><{}[]>]({{}[]}[{}()])}}<{[{[]()}[<>]]<[{}<>]<()<>>>}>]{<<(((){}){<>()})[[[][]]]>[([<><>]{ +(<[[{{[(([{{<((){}){<>{}}>{<{}[]><<>[]>}}(({<>[]}<<><>>)({()[]}<()<>>))}<{(<()()>[{}{}]){{ +{{{[{<<(<<[{({(){}}[{}{}])}[{[<>[]]{()()}}{[()]{(){}}}]]>>)><{((<<{<[]{}>([]{})}{{{}{}}}><([{}[]](()()))> +[<(<<<[(([((<<<><>>>[<[]<>>(()[])])[{((){}){<><>}}<<{}{}>(()[])>]){(([[]<>]<[]>)<{[]}[[]<>]>)<<{{}{}}[[ +<(<<({(([[({[[[])(()[])][<[]()>{{}[]}]}{({{}}{(){}})(((){})([]<>))})([[([][])<{}<>>]<<()><<>()>>]( +[{[[<{<<{<{<{<()()><{}[]>}([(){}](<>()))>(<{<>[]}([])><[[][]](<>{})>)}(({<[]<>>{()()}}<<[][]>>){({()[] +<([<{((({({[<(()[])[{}]>({[]()})]<<[[]]>>}<[[{[]{}}[{}{}]]([{}[]]{(){}})]({(<>())})>)}({<[{{{} +({{([(<<{({(<(<><>)<{}<>>><<{}()>[()()]>){<{{}()}(<>[]>>}})}>>[<<<{(({{}<>}(()[])){<[][]><{}>}) +[<((<<{{<[[[[{[]()}][{[]{}}(<>())]]]]{<<{(()<>)((){})}<[<>[]]{[][]}>>(<(()())(()[])><{{}<>}({}())>)>[<<[( +[(<<(<<[(([{((()())<<><>>}[{()<>}({}<>)]}]{{<(<>[]){(){}}>([<>()]({}{}))}})<<(<[[][]][[][]]>[([][]){(){ +<[([[<<[{(<([([]{}){{}<>}][{()}([][])])>)({<({(){}}){[[]{}][()()]}>{{{[]()}({}{})}(<[]{}><<>()>)}}[{[<[]()>< +{<{<[[{({<[<<({})<()[]>>((<>{})<[]{}>)>]>})}((<[[(<<{}{}>{[][]}>)<<[()[]]{<>{}}>{{()[]}[()]}>]<({[ +[({({(<<<<<[[<[]{}>]{<<>{}><[]{}>}]><<<([]{})<{}[]>><[{}[]][()<>]>>[[<{}[]>{[]}](<{}()>[{}<>])]>>>>{<{([(( +<({[({<{[<({{<()[]]}[{()[]}[{}<>]]}{[{()<>}{<><>}]([[][]]<[]<>>)})>[[[(<()<>>({}[]))<[(){}]<<><>>>]][[<({}{} +{<(<<(([[{(<[[()[]]<()[]>]{<()<>><()[]>}><{<[]{}>{()()}}>)([([(){}]{<>{}})[{<>{}}[<>{}]]]<<[[]{}]{() +{[([[{[<[<{(<<[]{}]>({<><>}({})))([{{}<>}]<{()<>}[{}[]]>)}<([(()[])<()()>])<{{[]{}}[{}()]}(<<><>>[()()] +<<[{<[({((<<({{}()}{()[]})>[<<{}{}>{<><>}>]>){{<[{[]()}[[]()]]{[{}[]]}>[{<{}{}>{[]<>}}([{}[]]((){}))]}( +<<{((([[({<{[(()<>)<()[]>]({()[]}({}<>))}{{{[]<>}[{}[]]}[{<><>}]}>}<[[([{}()]{(){}})<({}<>)[[]() +{(([({{(([<{{{<>()}<<>()>}[{<>()}(()())]}>]{(<([()<>]{()<>}){{()<>}}><<{{}}{[][]}>(<(){}><{ +{<(({{[<([(<<([][])(<>()]>{{{}{}}{[]<>}}>)[{(<()[]>{<>{}})[{()[]}<[]<>>]}{<{{}[]}><<{}>[{}<> +(<{{([<[[{{[{[[]()][()()]}{<<>{}>}][{{<>()}<()()>}(((){}){<>{}})]}{<(({}()))<[(){}]<(){}>>>(<({}[]>[[][]]>)}} +(({({[({<{{{[[()()]({}())]}[([{}]<{}()>)([{}()]{{}{}})]}[((<{}<>><()()>))]}[{{{(<>{}){<><>)}[<()() +(<({{<([{[([[({}<>)][([]<>){[]{}]]][[<()[]>]])][<{[[{}[]](())]<<()[]>(())>}{<{{}[]}[<>{}]>{<[]<>> +(([[([([<[{[(({}[])<[]{}>)]}][[{({()<>}[{}[]])(([]())(()<>))}<[<[]{}>({}<>)]{{{}{}}{[][]}}>]{{{ +<[{[{<<{[[<{(({})(<>{}]){([]())[[]()]}}{(<()()>([]())){([]{})<[][]>}}>]{({[[<><>]{[]()}](<{}[]><[]<>>)} +([{<({{([([[{{()[]}}({(){}}[<>{}])>]({{(())([]<>)}<[()<>][[]()]>}([{()[]}{()()}])))](([[[{<>{}}[<>( +<[[[(<[{{[[{{{<>[]><<>>}[{()[]}({}())]}[<[{}<>]<[][]>>]]]}{{({{{<>()}{()<>}}<<{}[]>({}[])>}[[(<>< +[[<[<({<[({{[[<>{}][[]{}]]{<()()>{<>{}}}}[<<<>{}><[]<>>><<{}<>>(()[])>]}){<[(([]())[<>()))[({}[])< +<<(<<<<((([[<<{}[]>(<>())>]]<{{[[]<>]<[]>}{[{}()]{<>[]}}}<[[<>{}]({}())]>>)){{([(({}[])({}[] +([{<([<[[[{[[{<>[]}{[]()}>([[]])]<({{}{}}({}[])){(<>{})<()()>}>}<{(([]()){()<>})[{<>{}}{<>()}]}<(([] +<{[<(({([[((((<>[])[[]{}])({[][]}))(<[()<>]{<><>}>)){<<{<>[]}<<>()}>>{({{}{}}(()()))}}]][{ +({<{<<<{{{(((([]())[<>]){<(){}><{}[]>})<{([]<>)[<><>]}[{()<>}({}<>)]>){((<[]()>[<>{}]){<()<>>( +[{<(([(<[((([[(){}]{[]()}])))]>)[<{(<<[<<>[]><()()>]>>){[<{{(){}}({}[])}([{}()][<>])><((()<>)[[]])[[{}()](<> +{<<[<{[(<{<([{()[]}({}<>)]{[{}<>][{}()]})([{<>{}}<<>>])>{(<{{}())<{}()>>(({}[])<<>()>))[({<>()}[()[]])<<{}<> +[<([<<<[({([<<(){}><{}[]>>[[<>{}][{}<>]]]<[<()[]><(){}>]([<>{}][<>[]])>)<<{<[]<>>[[]{}]}<({}( +<[[(<[{[[({{{<<>[]][{}[]]}[[[]{}]]}}){{[[(<>{})(()<>)]({<>()})]({({}{})<[]{}>}[<()<>>])}{<{[()[]]}[< +<(<(<((<[((([[<>()]]){<[<>[]]><([]{})>})[<<{<>()}{{}<>}>(((){})[<>[]])>{[[<>()][{}[]]](([][])([]))}])(( +[(<{{<(((<<{[[<>[]]]{([]<>)<{}[]>}}[<{{}{}}[{}()]><{[]()}[{}]>]>{[<{{}[]}([]<>)>[[(){}][()()]]] +<(<(([[{[<<<(({}))[{[][]}]>[[([]{})({}[])]]>[<<(<>[]){<>[]}><[()<>]>)<[{{}<>}(<>{})]{[<>()]{{}{}}}>]>{[{<{ +({<({{{[[(([<<()[]><<><>>>])(<((<>()))(<<><>><[]<>>)>)){{({[[]()]{[]<>}}[[{}[]]<[]()>])}({({()()}<[]() +{{{<[<{<{[<(<{[]()}><[()[]]{[][]}>){<<[]>[<><>]>([<>()][<>()])}>)<<<(([]())[<>[]]){[[][]](<>{})}><([(){}]{{}{ +<[((<<<({<[((<{}<>>[[]{}})((<>[])))({<()()>{<><>}}{(<><>){(){}}})][[<<[]>>[{<>[]}{[]()}]]([{ +(((<<{<({<[[[{()()}(()<>))(<()[]>((){}))][{({}[])[{}()]}<<{}{}>{()()}>]]>})<<{{<[[<>{}]<[][]>]((<>< +[<[{[[{{<{[(<<<>[]><{}()>>)({[{}[]]}((<>())<()[]]))]{{({()[]}([]<>)){{<>[]}[[][]]}}}}{({(<<>[]>{[]})[[{} +<<[({[[[[([<(<<>[]>{()[]})>{<[()<>]>[[[]<>]({})]}]<(<{{}}([])>[<{}()>])[{{<>()}<(){}>}<<<>{}}[{}{}]>] +([(((([[<[{({<{}>})<([{}<>][(){}])<<[]()><()[]>>>]{[([<>[]](()()))[{{}[]}[{}<>]]]({({}<>)[<>()]}<{()<>}{[]{ +[[<{[{<{{(<(<[<>{}]><([]{})[{}<>]>)>{{[{<>[]}[{}()]]<<()>{[]}>}[[((){})([])]{<<>()>([][])}]}) +{<[{{{<{([<[<{{}{}}[[]{}]><{{}[]}>]{(<{}<>><{}[]>)(<(){}><()()>)}>]<<<({{}}(<>()))[<{}[]>(<>{})]>({<[]>{()< +{<[{[<(({[{{({{}[]}[()[]]}}<(([]())[()[]]){(()){<>()}}>}[<<{<><>}>[([]{}){{}<>}]>[{{<>{}}{()[]}} +<{[{([<{<((<[<()[]>{[][]}]<<()[]><<>{}>>><([<><>]<()()>)({{}()}<(){}>)>){<(([][]){[][]})(<[]><{}{}>)> +(([<((((({{{[<()[]]{{}<>}]{<()()>({}<>)}}([[{}()]<<>>][((){})<<>[]>])}}(<{{[(){}]{()()}}}{([{}() +<<<((<[[{[<([<{}<>>(<><>)]<{[]<>}<[]<>>>)>]{([{[[]<>][<>()]}({[]<>}<<>[]>)])[[{{<>[]}(()())} +{<(<<<(({{(((([]<>)(<>[]))))}[(([[[][]][{}()]])<<(<>{}><{}{}>>{(()[])([]())}>)]}([({((<>){[]<>}){<[][] +({(([[[[<{[{(<{}[]>[{}<>])(<[]<>>({}[]))}{([<><>]{{}{}}){{{}[]}[[][]]}}]<[((()[])([]<>))[{[][] +[<([[([[<({({<[]()>}<[[]()]([]<>)>)([[()[]]]{[<>{}][()()]})))>]<({{[{<{}{}>}{{()()}[<>[]]}]{([{ +({<<{{({[{[{{[[]<>]<(){}>}<<<>{}>({}{})>}<{[{}<>]}(<[]>[()[]]))]}]<<<<<{(){}}<<>[]>>{<[]{}>{(){}} +(({<([<((<((({{}[]}[[]()])){{[[]()]<[]{}>}(<[][]>{<>})})({{[()()]{{}<>}}(({}{})[<><>])}[[([]{})[ +({{[(<{{<<<<[{{}{}}{{}{}}][<[]()>[[]()]]>([{{}}<[]<>>][<[]{}>{()<>}])>[<{({}{})({}<>>}[<{}<>>[<>()]]>]><< +{[((({{(<(<{[{[]()}}<<[][]>(<>[])>}<(<[]()><()<>>){[<><>]<<>()>}>><[{<()[]>}{[{}[]](<>{})}]>)<({<{<><>}>}{ +[(([{([<<<([[(()())][([]{})[<>{}]]]({((){})((){})}(([][])[()<>])))[<((<>())[<>{}])>{{[[]<>]( +<(({<([(<<<{([{}[]]<[]>)}({{<>{}}[[]{}]}(<{}[]>(()<>)))>>({<{<<>()>((){})}((()())[<>{}])><[<[]()>]{< +[<[{({<[({[(<[{}[]]{[]<>}>(({}{}){{}[]}))(<{()[]}>)]{<([[][]][{}<>])<<<>{}>>>{{((){}){()()}}<{{}} +[<([{<(<(<<{([[]<>]{(){}})((()<>)[[]])}<[<{}()>]<{<><>}<{}{}>>>>([{({}<>){{}()}}]<((()()))<<[][]> +({[{((<{[{([<{()()}{<>()}>[[()[]]]])}[{([[{}]{<>{}}]({[]()}[{}[]]))<{<{}<>>}>}]][[[(<({}{}){{} +[[<{{<{[([(<([[]<>][()<>]))[[[<>[]]]({()()}([][]))])(([[[][]]([]())])<{{{}<>}([]{})}<{[][]}{ +<<({<[{[<{<<([<>()]({}<>))][([{}()][{}[]])]>}>]}{[<[[[[[[]{}]<{}>]<<{}()>{()[]}>]][<{({}()) +(<<[({[([([[(<<>{}>){[(){}][()]}][[[(){}]{[]<>}]]]<[([<>[]]([]))[{{}<>}{()()}]]<[<{}[]>(()())]<<<><>>{{}[] +{([[[<[(<({<{{{}{}}[[]<>]}<[()[]]{<>[]}>>}<<<(()())<{}[]>>[([][])<<><>>]>[(((){})(()[])){<{}()>(()[]) +{[<{[[[((<{[{[[]<>]{{}()}}[{{}<>}{<><>}]][<<()<>>{<>{}}>[{[]{}}((){})>]}(<[<[][]>({}())]<[<>[]](()[]) +{({(<<{({({([<(){}>[()()]](<[]><[]<>>))([{<>()}<{}<>>]{<[]<>>[[][]]})})({[(([]<>)[[]])]{([[]{}]{{}()} +{{[<{<<{<{({(({}()))[<<>{}]{()()}]}({{[]{}}([][])}[<<>()>{[]<>}]))}>(<<[{<[]()><<>{}>}]{((<>[]))<( +{{[<[{<(([({([{}{}]({}[]))<<()>(<>[])>})[<<{[][]}<[]()>><{{}[]}<<>{}>>>{{{{}{}}{<>{}}}([{} +[[([(<{{[{{{{{()()}[[][]]}([{}()](<>))}<{<<>[]>[{}[]]}<<{}()>>>}}]<<[{[<{}>({})](<()[]>)}](<<<[][]>( +{<[([{{{((<{((<>())){<[]<>>}}<<{<><>}[<>{}]>{{()[]}(()[])}>>{{{<()()>[[]{}]}[[<><>]<[]()>]}([{{}}{()()}][(<>[ +[{<{[([((<(<(((){})[<>]){({}[])<{}<>>}>(((()())([]{}))<[()()]{[]{}}>))([((()<>)<{}()})<{{}[]}<<> +{(({{{<[<({([<{}()>]{<<><>>{<><>}})}){<(((<>[])<[][]>)(<[]<>>{{}<>}))(<{<>{}}<()[]>>[[{}[]]({}())])> +{<([{(<{<<{(<{()}{<>[]}>)([[{}()]{<>{}}]<({}{})>)}[<<<()[]>({}<>)>[<[]>[<>{}]]><(<{}()>[<>{}])>] +<{{{{(({{{[{<[[][]]<()<>>>}[({{}[]}([]<>))({{}{}}{<>()>)]]}}}([{<{{<{}<>><<><>>}}{([{}<>]<<>{}>) +{<[<<{<([[[[[[<>[]](()[])]({{}[]}<{}>)][((()())({}()))<{{}[]}(<>())>]]([<[{}[]][<>[]]>]<{([]{})}{( +{<{[[([<([[[(<()()>({}[]))[{()[]}]]((({}[]><()()>)[({}){[]<>}])]]{<<{<()[]>}{<<>[]>{<>()}}>><[{(()<>)({}< +[[<[[<{{{{<<{{[][]}<(){}>}><{([]())[[]<>]}<<{}[]>(<>())>>>}<{{[[(){}]<<>()>]<{{}()}[[][]]>}}<(<<( +<[[(({({(({{{([]{}){<>{}}}{[<><>]{[]<>}}}}))[({[[({}<>){<><>}]{<<>{}><<><>>}]}[<{<{}<>>(<>{})}(([ +({<<([{[<[<([((){})([]())][(()<>)({}[])]){{[{}()]({}[])}[{{}()}{{}()}]}>{{({<>[]}{<>})[<(){}> +<(<{<[<{({{[<{{}[]}{[]<>)>][{[{}{}][()<>]}(<[]<>>[[]{}])]}(([[[]<>]{()()}]<[{}[]]{<>{}}>)((([][])) +<{<(<<((<<[[{<()()><<><>>}<(()<>)({}<>)>>[<<[][]>(<><>)>{(<>[])}]](<{<()[]>([]())}[{<><>}<{}[]>]>)>>{( +{(({(<(<<[[[{<<>()><{}()>}[[<><>]{()<>>]]{[{(){}}]}]]>>)(<<(<({([]())<<><>>}({[]()}({}<>)))> +<{<<[<<{[<([[(()())<<><>>][<<>[]>(<>())]]({<{}{}><<><>>}{[{}]<<>[]>})){[{{[]}<{}[]>}[[(){}]{[]<>}]] +({[[{<[([[[{[[(){}]{[][]}]<({}[])({}())>}{{<()[]>{<><>}}<{<>}>}]{<<<()<>]{<>{}}>[<[]<>>{{}()}]><[<< +<{{{([({<{{([{()}[()<>]][(<>())(())])([({}[])[{}{}]]({{}{})([]())))}{(<[<>()]{()<>}><[()<>][<>[]] +((<[(<[(({{(<<(){}>{(){}}>({()[]}[<>[]]))<(((){})({}()))<<[]{}><()[]>>>}})<[{([<<>{}>]){<{<>{}}{()<>}>}}{{( \ No newline at end of file diff --git a/data/advent10a.txt b/data/advent10a.txt new file mode 100644 index 0000000..2f182d8 --- /dev/null +++ b/data/advent10a.txt @@ -0,0 +1,10 @@ +[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]] \ No newline at end of file diff --git a/problems/day09.html b/problems/day09.html new file mode 100644 index 0000000..87f1779 --- /dev/null +++ b/problems/day09.html @@ -0,0 +1,168 @@ + + + + +Day 9 - Advent of Code 2021 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 20*

   $year=2021;

+ + + +
+ +

--- Day 9: Smoke Basin ---

These caves seem to be lava tubes. Parts are even still volcanically active; small hydrothermal vents release smoke into the caves that slowly settles like rain.

+

If you can model how the smoke flows through the caves, you might be able to avoid it and be that much safer. The submarine generates a heightmap of the floor of the nearby caves for you (your puzzle input).

+

Smoke flows to the lowest point of the area it's in. For example, consider the following heightmap:

+
2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+

Each number corresponds to the height of a particular location, where 9 is the highest and 0 is the lowest a location can be.

+

Your first goal is to find the low points - the locations that are lower than any of its adjacent locations. Most locations have four adjacent locations (up, down, left, and right); locations on the edge or corner of the map have three or two adjacent locations, respectively. (Diagonal locations do not count as adjacent.)

+

In the above example, there are four low points, all highlighted: two are in the first row (a 1 and a 0), one is in the third row (a 5), and one is in the bottom row (also a 5). All other locations on the heightmap have some lower adjacent location, and so are not low points.

+

The risk level of a low point is 1 plus its height. In the above example, the risk levels of the low points are 2, 1, 6, and 6. The sum of the risk levels of all low points in the heightmap is therefore 15.

+

Find all of the low points on your heightmap. What is the sum of the risk levels of all low points on your heightmap?

+
+

Your puzzle answer was 524.

--- Part Two ---

Next, you need to find the largest basins so you know what areas are most important to avoid.

+

A basin is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height 9 do not count as being in any basin, and all other locations will always be part of exactly one basin.

+

The size of a basin is the number of locations within the basin, including the low point. The example above has four basins.

+

The top-left basin, size 3:

+
2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+

The top-right basin, size 9:

+
2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+

The middle basin, size 14:

+
2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+

The bottom-right basin, size 9:

+
2199943210
+3987894921
+9856789892
+8767896789
+9899965678
+
+

Find the three largest basins and multiply their sizes together. In the above example, this is 9 * 14 * 9 = 1134.

+

What do you get if you multiply together the sizes of the three largest basins?

+
+

Your puzzle answer was 1235430.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file diff --git a/problems/day10.html b/problems/day10.html new file mode 100644 index 0000000..96dd71b --- /dev/null +++ b/problems/day10.html @@ -0,0 +1,201 @@ + + + + +Day 10 - Advent of Code 2021 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 20*

  {:year 2021}

+ + + +
+ +

--- Day 10: Syntax Scoring ---

You ask the submarine to determine the best route out of the deep-sea cave, but it only replies:

+
Syntax error in navigation subsystem on line: all of them
+

All of them?! The damage is worse than you thought. You bring up a copy of the navigation subsystem (your puzzle input).

+

The navigation subsystem syntax is made of several lines containing chunks. There are one or more chunks on each line, and chunks contain zero or more other chunks. Adjacent chunks are not separated by any delimiter; if one chunk stops, the next chunk (if any) can immediately start. Every chunk must open and close with one of four legal pairs of matching characters:

+
    +
  • If a chunk opens with (, it must close with ).
  • +
  • If a chunk opens with [, it must close with ].
  • +
  • If a chunk opens with {, it must close with }.
  • +
  • If a chunk opens with <, it must close with >.
  • +
+

So, () is a legal chunk that contains no other chunks, as is []. More complex but valid chunks include ([]), {()()()}, <([{}])>, [<>({}){}[([])<>]], and even (((((((((()))))))))).

+

Some lines are incomplete, but others are corrupted. Find and discard the corrupted lines first.

+

A corrupted line is one where a chunk closes with the wrong character - that is, where the characters it opens and closes with do not form one of the four legal pairs listed above.

+

Examples of corrupted chunks include (], {()()()>, (((()))}, and <([]){()}[{}]). Such a chunk can appear anywhere within a line, and its presence causes the whole line to be considered corrupted.

+

For example, consider the following navigation subsystem:

+
[({(<(())[]>[[{[]{<()<>>
+[(()[<>])]({[<{<<[]>>(
+{([(<{}[<>[]}>{[]{[(<()>
+(((({<>}<{<{<>}{[]{[]{}
+[[<[([]))<([[{}[[()]]]
+[{[{({}]{}}([{[{{{}}([]
+{<[[]]>}<{[{[{[]{()[[[]
+[<(<(<(<{}))><([]([]()
+<{([([[(<>()){}]>(<<{{
+<{([{{}}[<[[[<>{}]]]>[]]
+
+

Some of the lines aren't corrupted, just incomplete; you can ignore these lines for now. The remaining five lines are corrupted:

+
    +
  • {([(<{}[<>[]}>{[]{[(<()> - Expected ], but found } instead.
  • +
  • [[<[([]))<([[{}[[()]]] - Expected ], but found ) instead.
  • +
  • [{[{({}]{}}([{[{{{}}([] - Expected ), but found ] instead.
  • +
  • [<(<(<(<{}))><([]([]() - Expected >, but found ) instead.
  • +
  • <{([([[(<>()){}]>(<<{{ - Expected ], but found > instead.
  • +
+

Stop at the first incorrect closing character on each corrupted line.

+

Did you know that syntax checkers actually have contests to see who can get the high score for syntax errors in a file? It's true! To calculate the syntax error score for a line, take the first illegal character on the line and look it up in the following table:

+
    +
  • ): 3 points.
  • +
  • ]: 57 points.
  • +
  • }: 1197 points.
  • +
  • >: 25137 points.
  • +
+

In the above example, an illegal ) was found twice (2*3 = 6 points), an illegal ] was found once (57 points), an illegal } was found once (1197 points), and an illegal > was found once (25137 points). So, the total syntax error score for this file is 6+57+1197+25137 = 26397 points!

+

Find the first illegal character in each corrupted line of the navigation subsystem. What is the total syntax error score for those errors?

+
+

Your puzzle answer was 339537.

--- Part Two ---

Now, discard the corrupted lines. The remaining lines are incomplete.

+

Incomplete lines don't have any incorrect characters - instead, they're missing some closing characters at the end of the line. To repair the navigation subsystem, you just need to figure out the sequence of closing characters that complete all open chunks in the line.

+

You can only use closing characters (), ], }, or >), and you must add them in the correct order so that only legal pairs are formed and all chunks end up closed.

+

In the example above, there are five incomplete lines:

+
    +
  • [({(<(())[]>[[{[]{<()<>> - Complete by adding }}]])})].
  • +
  • [(()[<>])]({[<{<<[]>>( - Complete by adding )}>]}).
  • +
  • (((({<>}<{<{<>}{[]{[]{} - Complete by adding }}>}>)))).
  • +
  • {<[[]]>}<{[{[{[]{()[[[] - Complete by adding ]]}}]}]}>.
  • +
  • <{([{{}}[<[[[<>{}]]]>[]] - Complete by adding ])}>.
  • +
+

Did you know that autocomplete tools also have contests? It's true! The score is determined by considering the completion string character-by-character. Start with a total score of 0. Then, for each character, multiply the total score by 5 and then increase the total score by the point value given for the character in the following table:

+
    +
  • ): 1 point.
  • +
  • ]: 2 points.
  • +
  • }: 3 points.
  • +
  • >: 4 points.
  • +
+

So, the last completion string above - ])}> - would be scored as follows:

+
    +
  • Start with a total score of 0.
  • +
  • Multiply the total score by 5 to get 0, then add the value of ] (2) to get a new total score of 2.
  • +
  • Multiply the total score by 5 to get 10, then add the value of ) (1) to get a new total score of 11.
  • +
  • Multiply the total score by 5 to get 55, then add the value of } (3) to get a new total score of 58.
  • +
  • Multiply the total score by 5 to get 290, then add the value of > (4) to get a new total score of 294.
  • +
+

The five lines' completion strings have total scores as follows:

+
    +
  • }}]])})] - 288957 total points.
  • +
  • )}>]}) - 5566 total points.
  • +
  • }}>}>)))) - 1480781 total points.
  • +
  • ]]}}]}]}> - 995444 total points.
  • +
  • ])}> - 294 total points.
  • +
+

Autocomplete tools are an odd bunch: the winner is found by sorting all of the scores and then taking the middle score. (There will always be an odd number of scores to consider.) In this example, the middle score is 288957 because there are the same number of scores smaller and larger than it.

+

Find the completion string for each incomplete line, score the completion strings, and sort the scores. What is the middle score?

+
+

Your puzzle answer was 2412013412.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file -- 2.34.1