From 75b7a367fe860501b28bb9c125fdafd81423e211 Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Tue, 14 Dec 2021 00:32:20 -0700 Subject: [PATCH] day10 solution --- data/day10-test.txt | 10 +++++ data/day10.txt | 98 ++++++++++++++++++++++++++++++++++++++++ src/day10.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 + 4 files changed, 216 insertions(+) create mode 100644 data/day10-test.txt create mode 100644 data/day10.txt create mode 100644 src/day10.rs diff --git a/data/day10-test.txt b/data/day10-test.txt new file mode 100644 index 0000000..b1518d9 --- /dev/null +++ b/data/day10-test.txt @@ -0,0 +1,10 @@ +[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]] diff --git a/data/day10.txt b/data/day10.txt new file mode 100644 index 0000000..6b0ede5 --- /dev/null +++ b/data/day10.txt @@ -0,0 +1,98 @@ +{<{[<((<[<({<{(){}}(()())>[<<><>>((){})]}(<<{}{}>(<><>)>))(<[(<>{}){()()}]{{{}[]}(()())}>[ +((<{[<([<<{[<(()())([]())>)<<<{}{}>{[][]}>{<<>>(()[])}>}<(((()[])[{}<>])[<[]{}>{{}[]}])[[({}{}) +({(<[([((<(<[(<>{}){()[]}]<[[]<>]<(){}]>><{(<>())[<>{}]}{(<>[])(<>{})}>)([(<(){}>[(){}]){{()[]}{<>{}}}][<<[] +{{{[(([{{{[{[(()())[<>[]]]{([]{}){()<>}}}]{{{((){})[[][]]}[[{}{}]<[]()>]}(<(<>()){{}{}>>([{}() +[<{{{[[(<[(([<{}[]>{()()}][[<>{}]]))]([<<{{}[]}>>([(<>[])<(){}>][[{}{}](()())])]{[{[<><>]}((<>{})[ +{<[<[[<<(<<<<(<>[])(<>[])>{([]())}>[{{[]()}}<({}())[<>()]>]>{[((<>{})[[]<>])([()<>]{<>()})](((<>() +([({({[{(([<[<[]>]>]<<({[]()}<[]<>>)[[()[]]{[]{}}]>>))((<<{<<><>>}{(<>{})<[]()>}>([[<>{}]<<>{}> +{(<([{{{{(((({{}[]}))){[(({}<>))({<><>}<[][]])][<<[]{}>[{}{}]>{<[]>{[]{}}}]})({[{([]<>)([]<>)} +{([{{{(([<[[[<(){}>{()[]}][([]<>)<[]{}>]]<{(<>())[[]()]}[{(){}}[()<>]]>]([({[]{}}{()[])){{<>()}{()[]}}])>[<[ +[([{<{(<({<{[[<>{}][<>[]]]<{{}<>}<{}{}>>}[({()[]])[[<>()]({}<>)]]>{<([{}<>]<[]<>>)[{[]()}{{}[]}]>[[{[][] +{{<(<{(<[<(((<[]<>><{}[]>))({(<>{}){[][]}}([[]()]({}<>))>)>[((((()<>)<<>[]>){(<>{}){<>{}}})(<({}( +{{[{<{<([{[<{[{}{}]{(){}}}{{[]<>}<()[]>}>]<[({[][]}<{}<>>)(<{}{}><[]()>)]<[{<>{}}(()())]([[]{}]<[]<>>)>>>[{[{ +<(([<<{{<(([(({}{})[[]{}])[<{}>(<>{})]]<([{}{}]{()[]})>))({(<(()<>)<<><>>>(([]<>)))}<<<[() +<<<(({{([{({({()()}<<>[]>)<{()[]}[<>()>>}){[<[<>{}][<><>]>[{()[]}[<><>]]]<<[<>[]]{<>()}>>}}[(<[[(){}](() +<<[[{{([(([([[<>{}][(){}]])]{({{()}(<>{})}{{{}<>}{<><>}})(([<><>])({{}[]}<<><>>))})([{({()<>}<[][]>)}])) +[(<<<<<{[<({[{{}[]}<()<>>]<[{}[]][[]<>]>})>[<<{(()())({}<>)}{({}())(<>[]]}><<<{}<>>([]<>)><[ +<<({({{([(<([[{}()]<[]{}>]<<<>()>>)><{(<{}<>><{}()>)<{(){}}[<>]>}{([[]{}][[]<>])<({}()){{}[ +{<{([[[[[{<<[[{}{}]([]<>)]{{{}()}[<><>]}><[<()()>[{}{}]](((){})<()>>>>}]<{({{([]()){{}<>}}<{<>{}}({}{} +{[{[[<[((<(<<{<>}{()[]}>><{<<>[]>[()[]]}{{()()}[()[]]}>)(({[[]](<>[])}{({}())<{}()>})([[{}[]]<[]()>][{ +[{[(({[{{([[[<()()>{{}{}}]{([]<>){<><>}}]](<<<(){}>(()())>{[[]]{<>{}}>>))<[<((<>{}){(){}}){[{}<>]}>([[<>< +<{<(<([(<[({<<[]()>[[]{}]>(<{}<>>)}(<[{}[]][{}[]]>{<{}[]>[(){}]}))[<(<[]<>>{{}<>}]([[][]]<()<>>)>{({{}<>}[<>[ +{({({{<({[{[{<<>()>[[]{}]}](([{}<>]{()()})[([]()){[]()}})}[[((()())[()<>])(<<>{}><{}>)]]]<([{([] +(<[([{({<([<(([]<>)<()[]>){{<>{}}[()()]}>])(([({[]()}<{}{}>)][<{{}[]}({})>[[<><>][<><>]]])<[({()[]}[[]{ +{{{<{{[[{[[<({[]()}{()[]})<[<>()][()()]>>(({{}{}}))][({[(){}](()[]]}){{<<>()>({})}{<{}[]>[{}<>]}}]]{[< +{<([((<{<<<{(({}{})<<>[]>)(((){}){[]})}{({[]<>}[[]{}])<[{}[]][()()]>}}[{([<>()][<>{}]){(<> +{([([(({[<[[[(())(<>[])]{[()()][<>]}]]>([{[(<><>)(<>())]<(()<>)[<><>]>}({{<>{}}({})}([{}][ +([[[({[{{<{{{[{}()]{(){}}}[{()}({}[])]}[{[[]<>>(()[])}<{[][]}{[]}>]}>}}]}{[<[[[[(({}{}){{}[]} +<[{<([<({((([[<>{}]([]())]<[()[]]<()<>>>){<<{}{}>[<><>]>[((){}){{}<>}]}))}({[({[()())(<>[])}{({}())}){([()[] +{([[{[<<[[<{([<>()][{}{}])<([]{})(()[])>}{{{()()}{[][]}}<[[]{}]<<>{}>>}>(({<()()>({}())}[{<>[]}({}<>)])([[< +({[<{{[<{{(((([]<>){<>()})([()<>]([]{})))){{<{()()}[{}<>]>}({<{}[]>}{([]<>)<{}[]>})}}<<([{{}()}[{}[]]]<{( +<({{([{[({<([({}())[()[]]]{([]{})})(([[]{}]{{}[]})([{}()><()<>>))>(<(({}{})<{}{}>)[{<><>}{[] +[{[{<{([[[<[[{[][]}(<>{})]{{[]<>}[{}{}]}]><{({{}()}<[]()})}>]{{(<[[][]]{[]()}>{(()())(<>[])})( +(<{(<[[<{[[<<([]<>)<{}{}>>({{}[]}({}()))>]({([[]<>]([]())){[<>{}]<{}()>}}[{({}())[(){}]}(({}{})[[]] +<[<<([{[{<{{<[[][]]<<>[]>>({<>{}}[<><>])}([[{}<>]<()()>][<[][]>(()[])])}[({[()()][[]()]}[{{}()}<[]<>>])]>{< +<(([[{(([[([[{{}()}{[]}]]<((<><>}({}[]))((()())[()[]])>)[{{<[]<>>((){})}}<(<(){}>{{}[]})({()}{{}<>})>]]<[(<{ +[{<(((<(<({(({{}()}{<><>})[{[][]}{(){}}])({{[]{}}[<>{}]>)})>((([<(<><>){{}<>}><[<>{}]>]([[<>[]][{}{} +[<{{({([({({{{()<>}([][])>}((({}<>)(()[]))<(<>()){{}<>}>)){[([()()](<>[]))]{({[]}[[]{}])([[]<> +{({[<{(<<([[[<{}{}>[{}{}]](<<>>(()))]{[([]<>)<{}{}>]<[<><>]>}]<[[{{}<>}<<>{}>][([]<>)<(){} +([{{{[[(<<[<[[<>]{[]}]((<>{})({}[]))>({{()[]}<<><>>}{{<>{}}({})})]{{{{[][]}<{}()>}}<[[<><>][{}<>]]< +[<{<{<[{{[([(([]<>))[{<>()}<{}{}>]]{[<<>{}>[(){}]){<[][]>[<><>]}})](([<([]{})[{}()]>(({}())(<>{}))] +[<[<{(<(([{<{([]{}){[][]}}><{[{}[]]([]<>)}[[()[]]<()()>]>}][{(<[(){}]{()<>}><<[]()>[[]()]>){[[<>[]](()[]) +<(<<<([[<([[({[]<>}<[]()>){{<>[]}[{}{}]}]([[[][]]<[]()>])]<{{(<><>){<>[]}}}{(<[][])(()[]))[([]{})[[ +(([{<{{([<<{({[]{}}[()[]])[<()()><()[]>]}[(<()>[()()])[[<>[]]]]>>{{{{<[]()>[()<>]}}{{<()[]>[()[]]}<[[][]] +(<<[([[{{({<[([][])<{}()]][<()()>(()())]>})}<([[{(()<>)<[]()>}((()[])[<>{}])]]([<{(){}}({}<>)>][< +[<<((<[<<{(((({}()))({<>{}}([]<>))){{<()<>><{}[]>}{(()())}}){({([]<>)<<>{}>})}}<{{<[()][<><>]>{{[] +<{[<[((([{<{{{<>[]}[[]()]}([<><>])}>((<<<>()>({}<>)><[{}[]]<()[]>>)[{{[][]}{()<>}}[{()<>}(()[])]])}(([<{{ +{<{<[(({([<[<[[][])([]{})>[{(){}}[[]<>]]][(<{}<>>{()<>}){[<><>]{{}[]}}]>([[<[][]>{[]<>}]({[][]}(()()))]{ +(<{{{[{<{(<[({{}[]})]><<{(()<>)[{}{}]}{<()()>}>>)[[(({()<>}(<>{})))([<(){}>(()<>)]{((){})([][])})] +<<[(<([<(({[{({}{})}<{()<>}{<>{}}>][([[]()](()<>))]}[[({{}()}<[]{}>)[<[]()>[()()]]]((<{}{} +<<{[{[<{{{([<<<>{}>{()[]}>({{}[]}<<>{}>)][[<()[]>[{}[]]]({()<>}(()()))])[<<<<>()>{[]{}}>><{{[]{}}<()<>>}(<<>[ +[{{<({[([({{{(()())[<><>]}{[()()][(){}]}}}{[([<>[]])[{[]()}((){})]]([<[]{}>(()<>)]{[<>]})})(< +<<<{{(({<{<[<<<>{}>>(<<>[]>{()()})]<([()<>])>>[(<({}[]){{}[]}>{[{}{}][[]()]})[<[<>[]]<()[]>>(< +[([<<<(<[[[[[([]{}){{}()}}<<[]()>{[]}>][([<>[]]({}))[(()<>){()()}]]]]]>{[([[<([]())<{}<>>>({<>()} +[([{{[[(({[<{[{}[]]{[][]]}<{<>()}[<>[]]>>(<{<>()}<[]()>>)]}))<<<<<{{()[]}{{}[]}}[<<>{}>]><{[{}<>]{( +[{{{<((([{([{[[]()][<>()]}([[]()]{{}()})]{([{}{}](<>{}))({()<>}(<>{}))})<[({(){}}[()<>])}>}( +{<<{{({[[[[[{[()]({})}<[<><>]{{}}}][[{()<>}({}{})][<<>[]>{<><>}]]]({<(<>)<<><>>>({<>()}<<> +<[[[[({([[{<[{{}()}]{(()<>)<[]()>}>{[{<>{}}(()[])][{()[]}<()()>]}}]]<{[(({<>{}}{<>()})<[[]()]<<>{}>>)<((()[]) +({{{<{[({[[[<{()<>}<<>[]>>{[[]<>][<>()]}]([(()<>)[[]()]]({{}[]}(()[]))]]][{{{<<>>({}<>)}<<<>{} +[{[((<{<([[{<<()[]>[[][]]>}<{({})}[<{}[]>[[][]}]>]]<<{(([]<>)[[]()])}<{<{}()>{[]}}{[()[]]({})}>> +[{([[{[({<[<(<<>{}>({}[]))([{}<>]{(){}})}({<[][]>}{[()()]<{}[]>})]<<[<(){}>[<>{}]][<<>{}>({}{ +[<([{<<[((([<[<>()]({}())><([]{})<{}[]>>]))[{[[[[]()]]]}{{[{[]()}([][])]{<[][]>{{}()}}}}])<(({{(<>()){ +{{[[<{{(({{{(<{}<>>{()[]})[<[]()>]}[{<[]{}>[()[]]}]}<[{[[]<>][[][]]}<<(){}>((){})>][([()<>]<<>>)< +<<{[(([{<((({([][]){[]<>}}{({}())}))({[<<>{}><<>>]}{<[<>{}](()())><<{}[]>{()<>}>)))({[<(<>[ +<[<((<<[[<[((([]<>)<(){}>)[<(){}>])({<{}{}>{<><>}}<(()())<[]{}>>)]{{({(){}}(()[]))}<({<><>}({}()))>} +[<{(<([{[({[{({}{})<{}()>}[{[]<>}({}<>)]]})[<[([{}[]][()[]])((<>()){{}<>})][[[(){}][[][]]][< +<(({([[(<[[{(<<><>><{}()>)<(()()){()[]}>}({[()<>][{}[]]}([<>{}]<<><>>)}]]{{[<[<>[]]>({<><>}([]{}))][(([][])< +{[[[[<<[{(({{{[]()}[{}[]]}}{[[()()][{}{}]]}){[{{{}()}}[[[][]]<()()>]]}){[{((()<>)[{}<>]){<<>()>[()()]}}(([{}< +[[<<<{<({[<([[()<>]]({()<>})){[{{}[]}]}>][({[<()<>>({}[])]}((<<><>>[<>])[({}())<{}{}>]))]})>}>[{{(({{[ +{{[[{{(([[[[({[]()}<{}()>)<(()[])<<>[]>>]]<(<{[][]}<{}()>>(({})[[][]]))>]<<{({()[]}[(){}]]({ +({{((<([<({<(<[]<>><<>[]>){[{}<>]}>(<[{}{}]>)}[<{{<>{}}{[]()}}[<<><>>[[][]]]>[[<()()><(){}>]{< +[[[(({{<(<{<[{()[]}]({<>{}})>[<<<>()>{{}{}}>{({}<>)<<>()>}]}<({{()()}}<(()()){<><>}>){<((){})(<>() +{<{{(<{{<[[({<<>>}<[(){}]({}())>)[<{()<>}[{}()]>[({}[])<()()>]]]]{<[({<>{}}{[][]})]{[(<>{})({}())]} +[<[<{<<({[[(((<>())[{}<>]))<(({}[])(()[])){{{}{}}[[]<>]}>]<[(<{}{}]{{}{}})<(()<>)>][[{<>{}}<[ +[({<(<[([<({([<>()]{[][]}>{<<>[]>[[]()]}}[{<()<>>([]<>)}])<<<[[]()](())>><[<<>[]>{{}()}]{<() +{{[{(<<{[{({[<[]()>{{}<>}]([()<>]{{}[]})}<<<[]()>[[]<>]><[<>{}][()()]>>)}<{<[{[]()}{<>{}}]>{({[][]}<[] +[[{[<<<[{[[<({<>()}((){})){{<>[]}<(){}>}>[<(()<>)({}<>)>{<[]()>(<>)}]]]{<<{[<>[]]>>(<<{}()>(<>())>( +{({{[([<{{{<((<><>)<()()>][<{}[]>{<>[]}]><({<>()}(()<>))({{}[]}<()[]>)>}([({{}[]})({{}()}[<>[]])])} +{<[[({{((<[{[{<>()}(<>())]<({}[])<<>{}>>}([(()())<<>[]>]((<>[]){{}{}}))]{({<()()>(()<>)}[{[][]}([]())])<<[() +([{((({<<<{<{{<><>}(()<>)}>}>)[{{[[[[][]]]][<(<>{}){[]}>([{}()][[][]])]}<{([()()][<>()])(<[]()> +<(((<(({<<[{<(()())>[[[][]]<[]{}>]}[{{<>()}(<><>)}(({}())({}()))]]>((<({{}[]}(<>())){({}[]) +<<{[(<([<(<{{[<>{}]}(<<>()>({}{}))}><({<<>()>(<><>)}<<[][]>[[]()]>)(([<>()){{}()})<[[][]]{<>{} +<<[[([{{{{[<{[(){}]<[]()>}>[[([])<[]<>>>[({}{})([][])]]]}<<({<()[]><{}<>>}<{()<>}(<><>)>)>(([ +{[[[{{[{{((<{[{}[]](()[])}<(<>{})(<><>)>>){(<<<>{}>>)(([()[]]<[]{}})[({}[])(()())])})}}]}{[{{({({([] +([{[{((([[{{([[][]][{}[]])[{[]<>}<<>[]>]}}]][<[{[(<>{})[[]<>]][{[]<>}[(){}]]}]{<[[{}[]]{{}[]}]><(({} +{(<(<{<<([<<<[{}{}]<{}{}>>><[{<><>}{{}<>}]([[]<>]{{}()})>>])>>{{[{{{<<<>()>[{}()]>{<[]()>[<>{}]}}}}<(<[( +{<[{<<({[({(([[]<>](<><>)))[[[{}()]<()[]>]<{<>{}}[()<>]>]})([<([(){}]{<>[]})<<<>()><(){}>>><([<>[]>([][]))(<< +[[[[<<(<({(<[{(){}}[()[]]][[{}[]]{[]{}}]>([{[][]}([]{})][{{}[]}<[]()>]))[{[{()()}({})]({(){}}[<>[] +{<{(<[<(<<<{<[()<>]>{{()[]}}}<<([]<>)[()<>]>>>[{[<<><>>[{}<>]][<<><>>{(){}}]}[{[[]()]{<>()}} +<[[<{<<[{{[[(([][])[[][]])<({}<>){{}[]}>]](<<({}[])[[][]]>((<><>))>[([()[]]((){}))])}}{[([((<>()) +{(<{[[((<<<{<{<>{}}([]{})><{()}>}[{(()<>)[[][]]}{<{}{}><{}{}>}]]<[[<{}()>]<([]{})>]{{[<>()]{{}{ +<{<{<{[{(((<(<[]{}>)([{}{}]({}{}))>([{[]<>}[[]{}]]<([]()){[]<>}>))<[(<[]{}>[()[]])]>)<{{[{{ +{{<([<{[(([(({[]<>}{()[]})<(()){(){}}>)[{({}<>)<[]<>>}<{{}()}<<><>>>>][{<({}<>)[()()]><<()<>>> +[[[<([<<[[[{<<[][]>{()()}>[[(){}][<><>]]}{[{<>[]}[[]{}]]}]{<<({}<>)[[]]>[(<>[])]><<[()[]]<[]>>[{[]<>}({}{})]> +{{{[{(<<{({{<{<>[]}>[{<><>}[()[]]]}[({()()})([<><>]<<>[]>)]}({[{{}[]}{{}[]}]}[(<[]()>[<>[]])({<><>}[(){}])] +(<<[{[{[({<[{{(){}}<(){}>}{{()[]}[<>{}]}]{{(<>{})<{}>}{((){})}}>[{([<>()](<>{}))<{{}[]}[[]{}]>}{(<[][ +(<[[{<<{({<([<<>()>[<>()]]{{()<>}[<>[]]))>({<<<>()><()<>>>}({{[]<>}{{}()}}{<(){}><<>{}>}))})}<([<({[[]]{{}< +([((<[((([{<((()<>))[([])]>({(()<>)([]{})}([{}<>](()<>)))}{<[[[]()]([]{})]>}]({([{[]{}}][{(){}}{(){} +(({{<[<{<{([<([]<>){()}><([]<>)<[][]>>]<<[()<>][[]<>]><{()()}>>)[(<[[]{}](<>())>{{{}()}{[]()}} diff --git a/src/day10.rs b/src/day10.rs new file mode 100644 index 0000000..cd8805b --- /dev/null +++ b/src/day10.rs @@ -0,0 +1,106 @@ +use anyhow::Result; +use itertools::Itertools; + +fn matching(c: char) -> char { + match c { + ')' => '(', + ']' => '[', + '}' => '{', + '>' => '<', + '(' => ')', + '[' => ']', + '{' => '}', + '<' => '>', + _ => unreachable!(), + } +} + +enum Response { + Illegal(char), + Incomplete(String), + Ok, +} + +fn check_line(s: &str) -> Response { + let mut stack = Vec::new(); + for c in s.trim().chars() { + if ['(', '[', '{', '<'].contains(&c) { + stack.push(c) + } else if matching(c) != stack.pop().unwrap() { + return Response::Illegal(c); + } + } + + if !stack.is_empty() { + Response::Incomplete(stack.iter().rev().map(|c| matching(*c)).collect()) + } else { + Response::Ok + } +} + +fn sum_illegal_chars(s: &str) -> usize { + s.lines() + .map(|l| match check_line(l) { + Response::Illegal(')') => 3, + Response::Illegal(']') => 57, + Response::Illegal('}') => 1197, + Response::Illegal('>') => 25137, + Response::Incomplete(_) => 0, + Response::Ok => 0, + _ => unreachable!(), + }) + .sum() +} + +fn score_incomplete_lines(s: &str) -> usize { + let mut scores = s + .lines() + .filter_map(|l| match check_line(l) { + Response::Illegal(_) => None, + Response::Incomplete(s) => { + let mut score = 0; + s.chars().for_each(|c| { + score *= 5; + score += match c { + ')' => 1, + ']' => 2, + '}' => 3, + '>' => 4, + _ => unreachable!(), + } + }); + Some(score) + } + Response::Ok => None, + }) + .collect_vec(); + + // select the N/2'th element + let median_index = scores.len() / 2; + scores.select_nth_unstable(median_index); + scores[median_index] +} + +pub(crate) fn run() -> Result<(usize, usize)> { + let input = include_str!("../data/day10.txt"); + Ok((sum_illegal_chars(input), score_incomplete_lines(input))) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_example() { + let input = include_str!("../data/day10-test.txt"); + assert_eq!(sum_illegal_chars(input), 26397); + assert_eq!(score_incomplete_lines(input), 288957); + } + + #[test] + fn test_my_data() { + let input = include_str!("../data/day10.txt"); + assert_eq!(sum_illegal_chars(input), 390993); + assert_eq!(score_incomplete_lines(input), 2391385187); + } +} diff --git a/src/main.rs b/src/main.rs index d789396..19dbc2a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod day06; mod day07; mod day08; mod day09; +mod day10; mod utils; // used to generate more runs when profiling @@ -30,6 +31,7 @@ fn main() -> Result<()> { day07::run, day08::run, day09::run, + day10::run, ] .iter() .enumerate()