commit ec29c015d2e9d27129490ecb55969acb371943f7
parent 2373adf06d166f9e2def29abd05f2aabeb405867
Author: Louis Burda <quent.burda@gmail.com>
Date: Sun, 12 Dec 2021 16:54:51 +0100
Add day 10 solution
Diffstat:
A | src/10/Cargo.toml | | | 8 | ++++++++ |
A | src/10/input | | | 90 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/10/input.test | | | 10 | ++++++++++ |
A | src/10/part1 | | | 87 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/10/part2 | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/10/src/main.rs | | | 111 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 387 insertions(+), 0 deletions(-)
diff --git a/src/10/Cargo.toml b/src/10/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "aoc"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+lazy_static = "*"
+bimap = "*"
diff --git a/src/10/input b/src/10/input
@@ -0,0 +1,90 @@
+((<(<{(<([<<{<[]<>><()>}<([]{})[<><>]>>({<{}<>><()()>})>{[({{}()}{<>()})]}]}>)[(({{<((<><>)([][])
+{{[({{{[[<<{<([]{})({}())>}>([({()<>}{<><>})]{<(<>[])[()()]>{(<><>)(<>)}})><(<[[<>{}]<{}<>>]{<[
+([{<[[((([([(({}))[<[]()>{[][]}]][<{{}{}}({}{}]><(<>{})([][])>])[<((()<>))>[<<<>{}>({}{})>(
+({<{<[<<((<({<[]>{{}}}{<<>[]>(<>)}){<{<>()}{[]{}}>[[<>[]][[]{}]]}>[<<[<>()]>>(<<{}()><<>()>>[{{}{}}{()[
+{(<[{[<{[<{{{[{}{}]{[]{}}}[<()()><[]<>>]}[[<()()>{[]<>}}{{{}<>}(<>())}]}{<[<[]()>([][])]({[]{}}
+[<<({{({[[({{<[]()><<>[]>}{<(){}>{[]{}}}}[({<>()}({}[])){[{}{}]<()[]>}])[{<(<>[])>}<([()<>])((())(()[]
+<<<({<[[[({([<()<>>([]{})](<[]()>([]{})))(<[<>[]][[]{}]>([()()]<[]>)]})]{{{<[[()[]](<>())]{[<>{}]{<
+{(<{{{<[{{<<{[[]()][{}<>]}>(({[]}[()<>])([()<>][()<>]))>[{([()][[]<>])}]}}<([([[[][]]{[]<>}]{([][])({}())})]
+[[([<{[(<(<[[([]<>)]{[<>()](<>{})}]{{[{}{}]{{}{}}}}><<[([]{}){<>{}}]{[[]{}]{[]<>}}>(({(){}}){{()[]
+[<((<<[{<[(<[<()()>]<<()<>>([]<>)]>({{()[]}{()[]}}[{{}()}<<>[]>]))([([[]<>]<(){}>)[<{}{}>[[
+[[{{<{({<[([((()[]){{}<>})[<<><>>{{}<>}]](<<{}[]>[[][]]>{{()}<[][]>}))<<(({}<>)([][]))>(<([]
+<[({<(<[(<(([{{}[]}]<[<>()]<()<>>>)({{<>()}{{}[]}}{({})({}[])})){[[{<><>}[{}[])][[[]()][()[]]]][{([]())[()()]
+<(<[{<[{{(<{{[[]]{<>[]}}}(({{}<>}<<>[]>)[<<><>>{()[]}])><([(<>())]<[()[]]{(){}}>)(<[<>[]][<>()]>({[]<>}[
+<([[({[((({(<<()[]>{[][]}>(<()[]>(<>()))){{(<>()){{}{}}}[<{}{}]({}<>)]}}{{<([]){[]{}}>}[{{{}[
+<[{[<(([{[<<((()()){<>()})((<>{}))>(([()[]]([]())){{()[]}[[]<>]})>](([<[[]<>]({}<>)>{(<>){{}()}}]))}(
+<([{[({{(<[[{<<><>>{[]()}}{<{}[]><()[]>}]<(<{}[]>{{}[]})>]>[{<<{[][]}<()()>>>[<(()[])<()[]>>[[()[
+{<[{[{([[[(({{[][]}{[]}}<[()[]]<<>{}>>)<<(<>()){{}{}}><<[]<>>({}())>>)(((<{}[]>[()[]]){([]())((){})})
+[{<[<([{([{(<{[]<>}>(<()[]>{{}{}})){<[[]<>]{()()}>{[[]](()[])}}}<{(({}{})<[]<>>){[()<>]}}>]<([({{}<>}({}[]))]
+{[[{({[({{[[({()()}<<>()>)[[()()]{{}[]}]][([[]<>][()()])<([]())([][]}>]]}})[((([(({}{}))<({}<>)<{}[
+{<[{([[<{{<<({<>{}}<<><>>)<{<>}([][])>>[{([]())}<{{}[]}>]>}}<<{(({(){}}))}><([(<()[]>((){}))({()<>})]
+<(({(<{([((<<<()()>{{}{}}>{[(){}]([][])}><({(){}}[[]()])<<{}>>>)<<(<[][]]([]()))<{[]{}}(<>
+<<<[<([<([(((<{}{}>){<()[]>{[]<>}})({(<>())[{}{}]}))([(<()[]>{<>[]})<[(){}][()()]>])])>]<(<({{(<[]{}){()<
+({<(<{{(<([(<(()())<{}[]>>[[{}<>][<>]])]{([{[]{}}[[][]]]([<>()]{()})){<([]())[[]<>]>}}){{[{(()<>){
+<{{{[<<(<<{([<()[]>([]())]<{[]{}}<{}<>>>)[[<[]{}>]{[{}<>]{<>{}}}]}<[<[[][]][[][]]>]({<(){}><{}()>}({
+<[[<(([([(<{[({}{}){()[]}]{[{}[]]([]<>)}}[<(())[()]]]>([([()[]][()()])]([(()<>)(<><>)](([]())[{}{}]))))])]))(
+([<[<{[{[([((([])]({<>[]}{{}[]}))(<{[]{}}{{}()}><{()[]}[{}{}]>)])<[{[(()[])<()<>>]<<{}<>>(()<>)>}{({<>
+([{{{[<[({(({([][])[()<>]}{{[][]}[()[]]})({{[][]}<[]{}>}{{{}[]}<{}[])})){<<<<>{}>({}{})>{{
+{<{[([{<[({<{{{}{}}}{{[]}{()[]}}>}{(([()[]][{}[]])]})]<<(<[{()<>}([][])][{<>()}]>(({[][]}{<>[]})[[[][]]]))
+[([<(<[{<({<({[]()}<<>{}>)<<()[]>[[]()]>>}[{<[()[]]{{}[]}>}<[[()[]]((){})]<({}{})[[][]]>>])[[[{(()())({}())}(
+{{<([([[{<<[<[[][]){<><>}>]>[<[[{}<>]<()[]>]{{<><>}[{}<>]}>[[<{}[]>{[]{}}](<<>{}>)]]><<{{({}<>)}}
+{{<[<<<[<(([((()[]){<>[]})]{((()[]))<[[][]]([][])>})[({(<>)[()()]}([()<>]{()[]}))])((<[{<>[]}]>))>]>((((
+[<{(((<[{(<[<<<><>><{}()>>]><{{(()[])(()[])}}{[[<>()]<<>[]>]{{<>()}[()[]]]}>)((<[<[]{}><{}[]>]{{[]()}{
+{[<([{(<{([<[{{}[]}<[]()>][<()<>>{<>()}]>(([{}()]([][]))({[]{}}([]())>)])((({[[]{}]<{}[]>})<[<<>()>{[]{}}][{(
+(((((((<[<[[[(<>[]){<>}][[{}()][(){}]]](<[{}<>]{(){}}>[<<>{}><(){}>])]>]{{({{[{}<>][<><>]}}(
+<<(<<<({<[{{[(()<>)[()<>]]}}{<[[<><>][{}]](<<>[]>{{}<>})}<<<{}[]>[{}]>{<[]<>><<>{}>}>}]{<<<<<>[]>[()()]>[
+{{[<[{{[<<{[[<<>{}>[{}()]]][(<<><>>{{}<>}){([]<>)[()<>]}]}>{{[(([]()){<><>})<<[]()>{()[]}>]}{([({}[])[{}()]]
+({([{{{(((<[(({})[[]{}])(<{}[]>{{}[]})][<{()[]}(<>[])>[[{}[]]<{}[]>]]>([{{[]<>}{<>{}}}<<{}[
+<{<{{{((<<[<<[<>[]]>{[<>]<[][]>}>[<[{}{}][()()]><([]{})((){})>]]>><{{[{<{}{}>[()<>]}(((){})[<>{}])]
+{[((<<<[{<[({{[]()}([])}({{}<>}((){})))<<<[]<>>[()<>]>>]>}]({<<{<[[]<>](<><>)>{{[]<>}[()<>]}}>><{{<<{
+[({[[<(([[[(<([][])<<>{}>>((()())[[]<>]))]<{{<[]()>}[{<>}{{}[]}]}>]])[<<[<(<[]>)[[[]<>]<<>[]>]>{({[]()}<[]>)<
+[{[{({[{({[{{({}[]){()<>)}<[<>{}]{{}()}>}[{[()()][{}{}]}[[<>{}]<[]()>]]]{<{<[]<>>[(){}]}((<>{})[
+<{<[[<<{([{[<[()[]]<<><>>>({()()}(<>()))]{<({}<>)[()<>]><[{}{}]{[][]}>}}{<<{<>()}[[]<>]>{<()[]>[()
+{({<[[(([(<{[<<>[]>]}>[{{{{}()}{{}[]}}({<>{}}([]<>))}{{[[]{}][[][]]}}]){<<[[()()][(){}]][<{}[]>[()[]]]]{[[<
+[{<({([<[{{[({()})<({}<>)<{}()>>]}}{[[[{()[]}<<>[]>](<[]()>{[]<>}}][[(<>{}){<>{}}]{{[][]}[
+[<{([(([([(([<{}<>>]([[]<>]<[]>))(({<><>}<{}[]>){[<><>][<>{}]}))])][<<{[<[(){}](<>[]]>]}[[{[[]()]}(([]
+<({({{{({<{[[{[]()}[()[]]]](([{}{}](<>())){{<>()}{{}[]}})}[(<[{}{}]<<>{}>>({[][]}))<<{{}[]}(()<>)>>
+(<[<<[{({[<<[({}[])[()[]]]<[()[]]<<>{}>>>>][[((<<>[]><()>)(<[]()><<><>>))]]}([[{<<<><>>(())>{{()()}}}{
+{<(({[{([((<[[()][<>]]>[<(<>[]){()<>}>{[<>{}]{<>{}}}]){<([(){}][<>()])<({}<>)[[]{}]>>{(<[]<>><{
+[[({([<<[{<({({}<>)({}())}){{{<>{}}(<><>)}<{{}{}}(()<>)>}}<<<[(){}]<<>>>((<>[])[[]<>])><<{[]<>}[()()]>{{(){}
+{({<([<([(({[({}())[[]()]]<[<>]{{}()}>}{[[{}<>]{<>[]}]<{{}[]}{{}{}}>}))({<([()[]>[[]]){<<>(
+[[{[[{{[{{<(<<[]<>><<><>>>[{[]}({})])<(([]()){()[]})>><[[<(){}>(<>())]][{{<>()}[[]()]}{[<>()]}]>}<{{(<<>{}>
+[{<[{(<({{{<{<(){}>(()<>)}>({[[]()][{}[]]}[[{}[]][()<>]])}{<<[(){}]{{}{}}>[[()<>]<<>()>]><<<[][]]([]<>)
+<<<({<{[<{<[<(<>{}){{}()}><[<>{}]>]>[(<{[]{}}({}())>)[(([]()){()()})<<(){}>{<>[]}>]]}[{({{[]{}
+{[((({[<{(({[([]<>)(<>)](<[]{}><(){}>)>[<{{}<>}([]())><((){}){()[]}>])({((()())(<><>))({()[]}{{}<>})}{<{
+<([(({(<{<<[[<<>{}><[][]>]<[[]<>](<><>)>]{{((){}){<>{}}}[<{}()>([])]}>>}{{<<<(<><>){{}<>}>{{{}[]}}>[{
+{{<{(((({<{{[({}{})][<<>()>[()[]]]}}{[{<[]()>(<>{})}[[{}<>](()<>)]]<[[()[]]]([[]()]<<><>>)>}]})<(<<([<[]{
+(([((<[{(({[[[<>[]]{[]{}}](([]<>))]{{<[]{}][<>[]]}{<{}{}>({}())}}}<(({[]()}{[]{}}){(<>[])}){[<(){}
+{<(({{([{{{<((<><>)({}()))>([<<>()>({}())]{{<>[]}[<>{}]})>}}(({[<<{}<>><[]<>>>[<<>{}>{<>[]}]]({(()<>){<>[]
+<<<{{(((({[((<{}[]>[()<>])((<>[]))){[{[]{}}]{((){})([]())}}]}){([<<[{}()]<[]()>>[[<><>][{}
+[[{({[({[<<{[<()()><<>{}>]{[{}{}][[]()]}}><[{{<>[]}<()[]>}]>>]}<(({{{[<>()]<[][]>}[{[]<>}[[]{
+<{({({{{{[{(([[][]](<>()})<[<>{}]{<>()}>)<(({}())(()<>))>}]}[((<(<{}{}>)({<>{}}{<>()})>{(([][]))<(()[
+((<(([[<{{<[{<(){}>}{<()()><<><>)}][{{<>}}]>{([(()[])(<>[])]{({}{})(()<>)})<[({}()){{}[]}]>}}({
+<{((([{([(<([[<>[]]([])](([]())[()()])){{{[]()}[<>()]}}>)<{{<<<>{}><()()>>)}(({({}[])<()()>}
+<({[[({[[({<[<[][]>]<[[]<>]([]{})>>{[{{}{}}((){})]}}<[<<[]{}><{}()>>][<({}[]]{[]{}}>{(<>){[]
+<<[<{{[<[<[[[{{}[]}[[]()]]]<({{}<>}(()<>))<[()[]]<[][]>>>](([[<>{}]([]())][<()<>>[{}{}]])<<<[]{}>{{}{}}>>)
+{([{{<([([<[{({}())(<><>)}[({}}<<>()>]]{<<<><>><[][]>>{<()><{}<>>}}>(<{[(){}]<<><>>}[([][])([]())]>(<<(
+(([[[({{{{{[<<{}()>><<{}()>>]{<{(){}}{<><>}>[([]<>)<()[]>]}}{(<{[]{}}[[]<>]>)[([[]<>][[]<>])([()
+{[<<[{[[({[{{{[]}}<[{}[]]({}())>}([((){}){()<>}]{<<>{}>{<><>}})]{[<{()[]}{()<>}]{(<>[])<{}
+<({<[([[({<<{{{}{}}([]{})}[[{}]{<>}]>{{({}[])<()<>>}<[<>{}][[]{}]>}>[<({{}<>})<<{}[]>({}())>>]})]]<<[<[{{[()
+[(<{<{(({[{{<{()()}<[]{}>>{([]())[{}[]]}}{<({}{}){[][]}>{(<><>)[{}{}]}}}[([({}<>)<{}{}>]<[
+<[{(<{<{({[{((<>[]){[]})({{}<>})}]}[{[<{<>[]}<{}()>><[[]<>][[]<>]>]<[<[]()>([]<>)}(([][])(<><
+[{[({([<<[[<<<{}<>><[]{}>>]][<{<<>()>((){})}<[{}()]<<>{}>>>{(<(){}>({}()))(<()()>{()})}]]>[({[([[]{}]{()[]})
+{[({<[(<{(<[{<()()><()()>}(<{}()>{<>[]})]>([(<{}{}>(()<>)){[<>[]][{}()]})[{(()<>)({}[])}<(<>{})(<>(
+<[(({{([[(((<([]{}){()<>}>{[()<>]{[]<>}}){[<[]()><[]>][({}[])[<>()]]})[(<(<><>)(()[])>{{[]()}{[]{}}})[{<<>
+[({<({({(<{{{<(){}>[<><>]}(<[]{}>(()[]))}[[{{}[]}[[]()]]<[{}[]][()[]]>]}[<(<()[]>{{}})[[[]<>]]>
+<<[(<{<((<[<<<(){}><(){}>>({{}<>}([]()))><{{(){}}{()}}<<<>()><{}()>>>](<<(()())[[]]>(<[]()>([]<>))><(<
+{(({([[<{[{<(([][]))>{(((){})[[]<>])[(<>{}){{}[]}]}>[<({[]{}})[(()()){<>()}]>]][{[(((){})<()<>>){<<><>>}]<<<[
+({[{{<[(<[({<<[]<>>{[]}>(<[]()){()()})}){{{{()()}(<>())}<[()<>](()())>}(({[]<>}([]<>)){[{}[]]})}][{{{[[]<>]{
+(<([[{([{<{{<{()<>}[()()]>[([]())[()<>]]}}<([{(){}}{<>{}}]((<><>))){{{(){}}{{}<>}}}>>}({[(<{[]{}}[()<>]>{[[
+{{(({[{[{[[{[{<>{}}]<[()[]]<{}<>>>}{<(()[])([]{})>({{}{}}<(){}>)}]{<(<<>()>(()[])){<{}()><
+({<((<<<{{({[[<>]<[][]>]((()[])[<>()])}<([<><>]<<>()>)(([][]))>){(<<{}[]>[(){}]><([])({}()}>){{<[]<>>
+{[<[([(<<(<{[[[]{}]<[][]>][{<>}(()<>)]}<[{()[]}{[]<>}]>>[{[({}[])([]{})]((<>){<><>})}((([]<>}[<>[]]))])({(
+([{[[[{(((((<(()[])<()<>>>{<[]()>[{}<>]})(({()()}({}<>))<[[][]]<<>{}>>))<<({<>()}([]()))<<[]<>>[<>[]]>>[<{(
+[{{<({[<<{[<<(()())[[]]>{{[]<>}[[]<>]}>{[<<><>}]}](<{[<>[]][{}[]]}<{[]{}}[[]{}]>>)}><<({{(()())([
+({{{[(([<(((<{<>}(<>())>)[((<>)<[]{}>)[([]())[()[]]]})<(((<>[])[{}]){{[][]}[()()]})<[(<>{})({}())
+<[({[<[[{((({[[]<>][<>{}]})(<[{}[]]{[][]}><{()()}{<>{}}>)){(<({}())[<>()]><{[]()}{{}()}>)})}](
+<{(([<[{<<<{<<[]{}>{<>()}>}({<<>[]><[][]>}(<()<>>))>>{([(([]{}){[]{}})((()[])[[][]])][{<()>}<[(){
+{(<[({{(<{{<[({}{})<<>()>](([]<>)[{}])>[([{}{}]<()<>>)[[{}<>](()[])]]}[(({[]<>}){{{}[]}[[]{}]}){[<{}<>>([]<>
+{(<[{<[<<<{([<[]()>[<>[]]]{{<>{}}([]())})}<[[({}[]>([]())]]<([<>{}]{[]<>})>>>>[[<<<{<>{}}<()()>>([{}])>{<((
+[{<{(([[[{<[(((){})<{}[]>)<{<>{}}>]<<<()<>>{[]{}}><<{}()>>>>}]]<<<[[(<()[]>{[]{}})][<{(){}}[<>{}]><<{}>
diff --git a/src/10/input.test b/src/10/input.test
@@ -0,0 +1,10 @@
+[({(<(())[]>[[{[]{<()<>>
+[(()[<>])]({[<{<<[]>>(
+{([(<{}[<>[]}>{[]{[(<()>
+(((({<>}<{<{<>}{[]{[]{}
+[[<[([]))<([[{}[[()]]]
+[{[{({}]{}}([{[{{{}}([]
+{<[[]]>}<{[{[{[]{()[[[]
+[<(<(<(<{}))><([]([]()
+<{([([[(<>()){}]>(<<{{
+<{([{{}}[<[[[<>{}]]]>[]]
diff --git a/src/10/part1 b/src/10/part1
@@ -0,0 +1,87 @@
+--- 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
+[1m[37mAll of them?![0m 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 [1m[37mchunks[0m. 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 [1m[37mopen[0m and [1m[37mclose[0m 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 [1m[37mincomplete[0m, but others are [1m[37mcorrupted[0m. Find and discard the corrupted lines first.
+
+A corrupted line is one where a chunk [1m[37mcloses with the wrong character[0m - 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
+[1m[37mfirst illegal character[0m 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 = [1m[37m6[0m points), an illegal ] was found once
+([1m[37m57[0m points), an illegal } was found once ([1m[37m1197[0m points), and an illegal > was found once
+([1m[37m25137[0m points). So, the total syntax error score for this file is 6+57+1197+25137 =
+[1m[37m26397[0m points!
+
+Find the first illegal character in each corrupted line of the navigation subsystem. [1m[37mWhat is the
+total syntax error score for those errors?[0m
+
+
diff --git a/src/10/part2 b/src/10/part2
@@ -0,0 +1,81 @@
+--- Part Two ---
+
+Now, discard the corrupted lines. The remaining lines are [1m[37mincomplete[0m.
+
+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
+[1m[37mthe sequence of closing characters[0m 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 [1m[37malso[0m 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 [1m[37msorting[0m all of the scores and then
+taking the [1m[37mmiddle[0m score. (There will always be an odd number of scores to consider.) In this
+example, the middle score is [1m[37m288957[0m 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. [1m[37mWhat is the middle score?[0m
+
+
diff --git a/src/10/src/main.rs b/src/10/src/main.rs
@@ -0,0 +1,111 @@
+use std::fs;
+use std::env;
+
+#[macro_use]
+extern crate lazy_static;
+
+use std::collections::HashMap;
+use bimap::BiMap;
+
+lazy_static! {
+ static ref COMPLETION_POINTS: HashMap<char, usize> = {
+ let mut m = HashMap::new();
+ m.insert(')', 1);
+ m.insert(']', 2);
+ m.insert('}', 3);
+ m.insert('>', 4);
+ m
+ };
+ static ref CORRUPTION_POINTS: HashMap<char, usize> = {
+ let mut m = HashMap::new();
+ m.insert(')', 3);
+ m.insert(']', 57);
+ m.insert('}', 1197);
+ m.insert('>', 25137);
+ m
+ };
+ static ref MATCH: BiMap<char, char> = {
+ let mut m = BiMap::new();
+ m.insert('(', ')');
+ m.insert('[', ']');
+ m.insert('{', '}');
+ m.insert('<', '>');
+ m
+ };
+}
+
+const OPENING: [char; 4] = ['(', '[', '{', '<'];
+const CLOSING: [char; 4] = [')', ']', '}', '>'];
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ if args[1] == "1" {
+ part1();
+ } else if args[1] == "2" {
+ part2();
+ } else {
+ eprintln!("No such part\n");
+ }
+}
+
+fn part1() {
+ let content = fs::read_to_string("input").expect("no file");
+
+ let mut score: usize = 0;
+ for line in content.lines() {
+ let mut stack: Vec<char> = Vec::new();
+ for c in line.chars() {
+ if OPENING.contains(&c) {
+ stack.push(c);
+ } else {
+ assert!(CLOSING.contains(&c));
+ let first = stack.pop();
+ if first == None || MATCH.get_by_right(&c).unwrap() != &first.unwrap() {
+ score += CORRUPTION_POINTS.get(&c).unwrap();
+ break;
+ }
+ }
+ }
+ /* ignore incomplete for now */
+ }
+
+ println!("{}", score);
+}
+
+fn part2() {
+ let content = fs::read_to_string("input").expect("no file");
+
+ let mut scores: Vec<usize> = Vec::new();
+ for line in content.lines() {
+ let mut stack: Vec<char> = Vec::new();
+
+ let mut corrupt = false;
+ for c in line.chars() {
+ if OPENING.contains(&c) {
+ stack.push(c);
+ } else {
+ assert!(CLOSING.contains(&c));
+ let first = stack.pop();
+ if first == None || MATCH.get_by_right(&c).unwrap() != &first.unwrap() {
+ corrupt = true;
+ break;
+ }
+ }
+ }
+
+ if corrupt == false && stack.len() > 0 { /* incomplete */
+ let mut score: usize = 0;
+ while stack.len() > 0 {
+ let c = stack.pop().unwrap();
+ score *= 5;
+ score += COMPLETION_POINTS.get(MATCH.get_by_left(&c).unwrap()).unwrap();
+ }
+ scores.push(score);
+ }
+ }
+
+ scores.sort();
+
+ assert!(scores.len() % 2 == 1);
+ println!("{}", scores[scores.len() / 2]);
+}