diff --git a/10-syntax-scoring/code.scm b/10-syntax-scoring/code.scm new file mode 100644 index 0000000..c30002a --- /dev/null +++ b/10-syntax-scoring/code.scm @@ -0,0 +1,107 @@ +; get list of lines from a file +(define (get-lines file) + (let loop [(lines '())] + (if (eof-object? (peek-char file)) + lines + (loop (cons (get-line file) lines))))) + +; check if character can close chunk +(define (closing? c) + (case c + (#\) #t) + (#\} #t) + (#\] #t) + (#\> #t) + (else #f))) + +; check if character can close chunk starting by o +(define (is-closed-by? o c) + (or (and (char=? o #\<) (char=? c #\>)) + (and (char=? o #\{) (char=? c #\})) + (and (char=? o #\() (char=? c #\))) + (and (char=? o #\[) (char=? c #\])))) + +; return character needed to close chunk started by o +(define (close o) + (case o + (#\( #\)) + (#\{ #\}) + (#\[ #\]) + (#\< #\>) + (else #f))) + +; if given line is corrupt, returns expected character +(define (corrupt-char? line) + (let loop [(i 0)] + (if (< i (string-length line)) + (let [(c (string-ref line i))] + (if (closing? c) + i + (let [(close-index (loop (+ i 1)))] + (if (number? close-index) + (let [(d (string-ref line close-index))] + (if (is-closed-by? c d) + (loop (+ close-index 1)) + d)) + close-index)))) + #t))) + +; compute score after syntax checking all given lines +(define (score-illegal-lines lines) + (fold-left + (lambda (score line) + (+ score + (case (corrupt-char? line) + (#\) 3) + (#\] 57) + (#\} 1197) + (#\> 25137) + (else 0)))) + 0 lines)) + +; returns #t if line is corrupt +(define (corrupt? line) + (char? (corrupt-char? line))) + +(define (not-corrupt? line) + (not (corrupt? line))) + +; returns list of characters needed to autocomplete the given line +(define (complete incomplete-line) + (let [(stack '())] + (string-for-each + (lambda (c) + (if (closing? c) + (set! stack (cdr stack)) + (set! stack (cons c stack)))) + incomplete-line) + (map close stack))) + +; returns auto complete score applied to incomplete lines of input +(define (score-autocomplete lines) + (define (score completion) + (fold-left + (lambda (s c) + (+ (* s 5) + (case c + (#\) 1) + (#\] 2) + (#\} 3) + (#\> 4)))) + 0 completion)) + (let [(scores (sort < + (map score + (map complete + (filter not-corrupt? lines)))))] + (list-ref scores (div (length scores) 2)))) + +(call-with-input-file + "input" + (lambda (file) + (let [(lines (get-lines file))] + (printf "part 1:~% Illegal lines score = ~a~%" + (score-illegal-lines lines)) + (printf "part 2:~% Completed lines score = ~a~%" + (score-autocomplete lines))))) + + diff --git a/10-syntax-scoring/input b/10-syntax-scoring/input new file mode 100644 index 0000000..3767963 --- /dev/null +++ b/10-syntax-scoring/input @@ -0,0 +1,94 @@ +<({<[(({(((({(<><>)[[][]]}<<()>{{}}>)(<{(){}}((){})>))<[((<><>){()()})[(<>{}){[]{}}]]>){{(({[]()}<[][]> +{<({[[<<{(<{(<{}()>([][])){<<>}[<>()]}}[<(<>()){()()}>[[(){}]({}())]]>{({{<>{}}[<><>]}<{()<>}{{}() +{{<<<[<({[{{<({}())(<>{})>(<()<>><()[]>)}<([<>{}](<>[]))<{{}<>]>>}<[[<<><>><[]()>][[[]{}]{{}}]][{(<>( +[[<<<[([[([<(({}[]){{}[]})><{([]<>)[(){}]}[{()[]}([]{})]>][({({}[])<[]{}>}{[{}()](<>())}){(([]{}){[][]})[ +{((({{<[(((<(<()><()()>)>[{<[]()>{<>{}}}{([][])<[]()>}]){(({[][]}{()})(({}<>)[<>{}]))({{()< +[[[(({[<<[([[[[]<>]{[]()}]([{}()]{{}{}}]][{[()()]{(){}}}(([]())<{}>)])][{[(([][]){[]{}})]<{(()< +{<[{[({<{[{[<[()<>]>({[]<>}{[]()})]}{[([<>{}]({}{})){([]{})}]{{<{}{}>}{<()<>>(<>{})}}}](([{{(){}}<{}{}> +<{({{[(({({<[[[][]]]{[<>()][{}()]}>((<{}<>>))})(<(<[{}[]]({}<>)><({}<>)>)[[{()<>}{<>{}}}[{[]<> +[<[[[{<[([<(<<<>{}><(){}>>(<[]()>)){<<{}<>>[()]>[<[]<>>([][])]}><<{[{}()][{}[]]}<({}{})>>({{{}{}}} +{[[{<(<[{[<(<<{}{}>{[]()}>){{(()<>)[[]<>]}}>[[[[<><>]<[]{}>]]]]}({{{{([]<>)[[]{}]}}{{(()[])[[]{}]}}}}((<(<< +<[([({<({(<{[[[][]][<>()]][<{}[]>]}[{(()())<{}{}>}<({}())(<>{})>]>{(<<[]{}>>{{{}<>}[[]<>]}){{([] +{<<[<(<{[[<[{[()[]](<><>)}{<[]{}>(()[])}]<{{[]{}}<{}<>>}([[]()]([])))>(([[<><>]]))]<[<{{[][ +(((<<([[([<<[(()[]]<()<>>]<(()[]){{}[]}>><<[{}{}](()())>{<()()>[{}()]}>>])(([[({(){}}<<><>>)[{{}[]}[{ +[<{([[<(<<[[([<>[]][<>()])(((){})([]()))](<{[]<>}({}())>[<<>[]>(()[])])]{[((<>())[{}()])(([])((){}) +(({<{<([[[(<(<[]()>{<><>}){[[]()]{{}<>}}>)]<([<{()[]}<<><>>>{{<>()}{[][]}}][<{[]<>}<{}()>>])[<{ +<<<<[([({{(<[<<>{})]<[[][]][{}{}]>>[<{{}()}[[]<>]><[[]<>]{[]()}>])}}<(<([(()())({}())]({<> +{<[{{(<((<{<[<()()>[{}<>]][([]())[{}{}]]><{[[]{}]{()()}}{([]<>)<()<>>}>}><{(<<<>{}>[[]]><({}[])({}()]>)}<{[ +(<{{<(([[({<(<{}><<>{}>)><{[(){}]}<{<>()}[[]<>]>>}{({<(){}}({}{})})})<<[[<(){}>{[]()}]<[{}{}]>] +<{((<{[{<{[((((){})(<>{}))[<{}[]>[()]])(<[()()]{()<>}>)]{{({()}<{}[]))}[<(()[])><[()[]]({}<>)> +(<(<({[{<{{{<[{}][[]<>]><{<><>}(<>[])>}}}>}<{<[({<[]{}>[{}()]}([()[]]{[]<>}))[[({}[])]{({}{})[{}[]]}]][<{{<>( +[({<<[{{{<(<<<{}{}>{[]}>({()[]}({}()))>{<[{}()][{}{}]>[[<>{}](<><>)]})>(<<[<{}<>>]{<[]{}>([ +<(({{[(({(<{{([]<>)[{}<>]}}{<<[][]>{<>{}}>({<>()}{<>()})}>{[[[[]<>]](<<>{}><()<>>)]})({<([< +<<[(<<([([({<[{}[]]<{}()>]{<[][]>[[][]]}}({<()()>{()[]}}({<>()}((){})))){{(<()[]>[[]])(<<>{}>)}{<{{}[ +{{(<<{([{[{(([{}{}]((){})))}{<[(()())({}())][{()<>}]>}][{<{({}())<[]()>}[[<><>]{<>()}]>}]}[((< +<[[{(([<<<{<([[][]][()[]}){{[]<>}(()[])}>([(<>[]){{}[]}]{({})<<>{}>})}[[<{<>[]}<[]()>>][{{()[]}}[{{}() +{{([{<((<{<[<<()[]>(<>())>{[<>()][[]<>]}]([({}[]][<>()]][(<>())<()<>>])>({<[[]<>]>[[()()][[][]]]}<[<[]() +[<<({<{[[({[<((){})[{}]><<[][]>{()[]}>][<({}{})>[[{}()]{{}<>}]]}{{<<[]()>([]())>{{<>()}{<>[]}} +[({[({{(<(<{<<<>[]><<>()>>({()[]}{()[]})]>){(([[()()](<>{})]{([][])<()()>})(({()[]}<{}()>)[ +{<(<{<{(({{[(<<>()>{<>[]})(({}())[[]()])]([({}())(<>{}}])}{{<{{}()}[[][]]>{{[]{}}<<>[]>}}}}{<[{< +[((<{{{([<<<[({}[])[()<>]]<{<><>}<<>[]>>>>>[(<{[{}]<[]()>}{[<>]<[][]>}>{{(()[])}(([][]){<>[]} +{<((<{(({{{<([[][]]{{}{}}){{[]{}}{[]<>}}>[{<{}()>([]<>)}(<[][]>{<>[]})]}<([[()[]]]{{()()}([][])})([{[][]}<{} +[{([(([<{([(<{[]{}}[()[]]>(([])[<><>]))])[[{(({}())<[]<>>)<({}())[()[]]]}([<()()>[<><>]](<[]<>><<>()>))]( +{{[[[(((([[{[([]())[()>]}(<<()<>>({}<>)>[{<>[]}[()<>]])]<<[{[]()}{[]{}}]>({[{}{}]([]{})}[{(){}}{{}[]}])>] +[({[<(<[{[{({<<>{}>{{}{}]}[(<>())[<>{}]])(((<>[])<{}[]>)[<()()>[{}{}]])}[[<<{}<>>{{}[]}>[(<>< +[{<((([{{{(<{[{}<>][[]<>]}]){[({{}<>})<<{}()>{{}{}}>]{<([]<>)<[]{}>>[<(){}>(<>[])]}}}(([{[<>]<[]()>}([<>{}][ +{(([<{[[<({[<<<>{})([]<>)>[{[]()}(<><>)]][<(()[])>{(<>{}){[][]}}]}<{[([]())<[]{}>]<{[]()}(() +<{[{[<<{[(([{(<>{})<[][]>}<([]<>)(<><>)>](<[<>[]][[]<>]>[[[][]]({}[])])))]{[[{({<>}[()<>])[<[]<>>{[]()}]}( +{(<(({{(<{<[<<<>{}>[<>[]]>([[]][[][]))]([(<>{})({})])><[[{{}[]}({}[])][{<><>}<{}>]](<([][]){[]}><{[][] +{[[(({{({<(<(({}<>){{}}){([])({}{})}>)>}<<[([{<>[]}[[]<>]])<({[]()}[{}<>])<[{}{}][[][]]>>][{< +({[{[{[<([{{[[()()](<>{})]((<>{})(()<>))}[({[]()}({}{}))[<<><>>{(){}}]]}<((([]){()<>}))>])><<< +[{<({([<(([{[{[]<>}][(()<>)<<>[]>]}]<(<({}{})(()())>[([][])[(){}]]){<<()[]>>}>))<[{<[[[]{}]([]())][{{}{}} +{[(((<<{[[(([<[]()>(<><>)])(<<<>{}>[<>{}]>{<<>><[]<>>}))[{(<<>()>[[]<>])(([]<>){<><>})}[((<>)[[][]])(([]{})[[ +{([<<{((({[[[(<>{})[()()]]]]<[([{}{}]<[]<>>){<<>[]><()[]>}]>}{<<{<()()>}>{{([]<>)[[]<>]}{<()[]>[[ +<<[(<(<[({<{<([]())(<>[])>[{{}<>}((){})]}>{({(<>())({}<>)})}}{<{<(<>[])><{[]{}}<{}()>>}[{(())(()[])}[({}())<[ +{{([{{<{{<[(<[[][]]{{}()}>)[<{[][]}<{}[]>}({{}()}{()()})]][{[[[]()]{()[]}]<{{}}([]())>}{(< +[<<{{<<<[[[({[{}()]}{<{}[]>(()())}){({[]<>}([]{}))<({}{})(<>())>}]{({<[]<>>([]<>}}{{[][]}[[ +(({[[[{<(<{[[([][]){<>[]}]([[]<>])]<{[{}()]<{}[]>}[({}<>)<{}()>]>}[[(<<>[]>[<>()]){<()<>>{{}{}} +{<{([[<<(<<{<[()<>][()()]>[[()[]]({})]}>>)>>]])<{({<<[[<([(){}]<[]()>)<<[][]>[<><>]>]]]>[({[{<()<>>< +{({([(([({{((<()()>([][])))}{{{<<>>}[[()<>](()())]}<{<<><>><{}[]>}>}})({<[{<{}{}>[<>()]}[{{}<>}[{}{}]]]({( +{{(<{<[[(<(<[(<><>){[]()}]>)(([<{}{}>[[]<>]][<<><>>(<>{})])<<[[][]]><<[]()>{<>}>>)><<{<({}{})[<><>]>}< +{[[[[{{(<<{<{{[]{}}<{}[]>}[<()[]>[<>[]]]>{([{}()])(<{}{}>{<>{}}]}}[<<{<>{}}<()()>>{[<>]}>{[(<>{})<()<>>] +((<[{<[({<({[(()())(<>[])]<[<><>]{[][]}>}([([])[{}()]]<{<>()}{{}<>}>))><([<([]{}){[]}>[{[]}[[][]]] +[<[<({[{{({<[(<><>)<[][]>](<<>{}>(<>()))>}(<<<{}{}>[{}<>]><<[]{}>[<><>]>>(((<>())<()>))))}}[{[(<[{()[] +[{<[<(<<{[<([<{}[]><<>()>][[[]()]<()[]>])>[(<[(){}][{}{}]>{[<>{}]<{}()]})]]({[(<<>>)<[{}<>]<[]{}>>]<<<(){}>< +[<{<{<<<(((([<()>{<><>}][(()())[{}()]])[[{{}()}<()()>][{()}]])<(<<[][]>><<{}()>[{}[]]>)[([[][]][<>[]] +({{<[{[{(<<[((<>[])<[]()>)[[{}{}]({}{})]]>([[(()<>)<<>{}>]{(()<>)[{}()]}]{(([]())([]()))[[[]<>][<>{}]]})> +({<<[<{{[[([{<()<>>}])[<{<()[]>}[{(){}]<{}[]>]>[[[[][]]](<[]<>>{<><>})]]]<[{[([]{})<()()>]}(<({}<>){< +<([<<{(<({{{<({})(<><>)>{{<>[]}<[][]>}}<([()[]]({}{}))>}})>{{({[[{{}<>}]{[(){}][(){}]}]([{{}{}}({}{})][[ +{[({<[<[([[<<({}{}){()[]}>{([]<>)}>{(({}<>)<[][]>)[{{}<>}(<>{})]}]])[({[(([]<>){<><>})(([]<>)<[ +<[[[{<<({<{([<()[]><[]()>])<[{{}()}<()[]>](([]<>){[]()})>}>{[[(<{}()){<>{}})[<[]()><()<>>]]{[{[][] +{[(<{<{{{[(((({}[]){(){}})(<(){}>{{}<>})){([[]<>]{[]<>})[[<>{}]{<>()}]}){(([<><>][{}[]])([<>] +[<({[[[[{<<{[{[]()}<[][]>](<{}<>>[{}{}])}{({{}()}((){}))([()<>]<<>()>)}>>[<([{()()}{[]()}]{[< +{<{{([{<([<[{<(){}>(()[])}<<(){}>{{}{}}>][{[(){}](<>())}[{<><>}<[]{})]]>({({[]()}[[][]])<{<>()}<[]() +[{{<[{<((([{{<[]{}>[[]{}]}{<<><>>[<>[]]}}](({<<>{}><[]>}<(<>)>)[((<>{}){<>[]})[{{}<>}<[]()>]] +([<<{([<[<<([([]{})[{}()]]<(<><>)<()<>>>)><([{{}<>}[(){}]]([{}<>](<>{}))){<<[]<>>{()<>}>[<()<>>(<>) +{{({({(<{({<{[()()]{[]{}}}[<{}[]>]>{[{<>[]}{{}()}](<<>{}>[{}<>])}}[{<[{}{}]<<>[])>([{}[]]{{}[]}) +<{((<([<[{([([<>{}]([]<>))]{{<{}[]>[[][]]}})([(<{}{}>{()<>})[[[]()][{}{}]]}[{{{}()}<<>()>} +[{<[<<({({<[{<<>[]><<>{}>}<{<><>}<{}()>>][([[]()]{<>{}})]>{(<[{}[]]([]<>)>}<<[{}[]][{}<>]>{{{}()}{<>[] +[{<<([([[{<((({}<>)[{}()])[{[]()}(<><>)])<[<()<>)(<>())]>>([((<>()))[[{}]([][])]]<([<>()]<()()>)>)}(([<{ +(<(([{<{(<([[[<>[]]{[][]}][((){})]])([((()())({}{}))(<<><>>)]<([[]<>]((){}>)({[]{}}{<>()})>)>)({{{{[ +{<<{{(<{[<{{<({}[])<{}[]>><([]())<{}<>>>}<([[]{}]<()<>>)>}>{<(([<>[]]([]()))<{{}{}}(<>[])>){[([]() +{{(({<{[{[[[([{}<>](()))]{{{{}{}}{<>{}}}[[{}{}]([]<>)]}][([(<><>)[[][]]])<<(()())(()<>)>[([]()){() +(<[{<<[<<[(<{{<>{}}{[]<>}}[{[][]}[()[]]]>[<(<>())((){})>{({}{}){[]<>}}])]]>((([(<[<>{}]{{}<>}>{( +(<<{{<[{[(<<<[{}{}]([][])>[{()<>}[{}]]>{({()[]})(<()<>>(()))}>)}}][[<([({<{}>[<>[]]}){({()[]}(()[])){ +<(<([<<({[{(((<>[])<<><>>){{<>{}>}){{[()[]]<{}{}>}{({}{}){<>()}}}}[(<<<>{}>[{}{}]>(<()[]>[<><>]) +[{[<<{[<(([[({<>{}}(<>))<<()()>[<>{}]>][{{[]{}}}<<<>()>({})>]]><{([(<><>)]<<(){}>{{}{}}>){{{{}[]}<<><>>}[[() +[[[[<{(({{(<<<{}><[]{}>>((()[])[{}()])><<{[]<>}{<>[]}>[(<>()){{}<>}]>)(({(<>())({}[])}){[<(){}><[]{}>][[ +<{[[<{<[<<[{([()()]{()()})[{[]()){{}{}}]}][{({<>{}})<[()()]{[]()}>}<[[(){}][{}[]]]{{<>[]}}>]><(([(()()) +{<<(<(([<<{[{<[][]>}{([]())[()<>]}]{[[<>]<[][]>](([]{})(()[]))})[<<[{}<>]{<>{}}>[([]<>)[{}[]]]><( +[([({([([{<({<<>{}>[{}]})<[({}{})({}{})][{{}()}(<>{})]>><{{([]{})([][])}[[{}[]]<<><>>]}<((<><>)[() +([[[[{{{{{{{<<(){}>{<><>}}{[{}[]]({}[])}}<({{}[]}[<>]){<<>{}>{()[]}}>}{{{(()[])}{{{}}}}{[([]()) +(<{(({<<<{(<[<[][]>]<<{}<>>{{}{}}>><[{[]<>][<>[]]][[<><>]<[]()>]>)[(<([]{}){[]{}}>({{}{}}) +<((({[(<<{({(([][])){[[]<>]}}<(({}{})({}{}))(<[]()>[()()])>)}>({(<[([]())[[]<>>]([[]{}]<[]<>>)><{{()[]} +<{(<<({[(({{({<>[]}(<>{}))<<()[]>{<><>}>}<<<()[]>[(){}]>>})<{({(<>[]){<>[]}}[[<><>]])<[(())(<>[]) +[([<[{[[{({{({[]<>}{[]()})([{}{}](()<>))}{(<[]<>><<>[]>)}})}<<([<[<>()]<[][]>>([[][]]{[]{}})](<<() +<<<(<({[{[{{(<{}>[{}{}])(([][])[(){}])}{([{}<>](<>))}}]}[<<{<((){}){[]{}}>({{}<>}{[][]})}<{{()()}<<><>>}>>{(( +<<<{{{((<[<<{<[]{}>}><[({}{})[[]<>]]>>[<([<>()](()))<(<><>)(()())>>[{<()<>>{()()}}]]]({(({[]{}}({}[])))<({{ +[<{[{[[{{{[{({<>[]}<[][]>)[{(){}}{{}()}]}<[[()()][{}()]](({}<>)[()()])>]<({<{}<>>({})}([()<>])){[{()< +<{{{{([(([{{{<{}[]>(()[])}{({}[])({}[])}}}])<{({<({}<>]<<>{}>>[<()<>>({}())]}[<<[]()>[<>()]>(<()<>>{<>[]})]) +((([({[<[[([([<>[]]<[]<>>)(<()<>>)]{[{<>)[()()]][([]()){[]<>}]})]][{((<[<>[]]{<>()}>[<()<>>[{ +<[<{[[<[<<{{(<[]{}>){[()]({}{})}}(<[()[]]{[]()}>[<()[]>])}{{({[]<>>([]{})){{()<>}{<>[]}}}(<(< +<[<<<[{<[<[[{(()<>)[()<>]}]({{()<>}({}())}[[{}()]])][{([<>{}]){({}[])([]{})}}]>[[[<(<>{})<(){}>>]}]] +<<[[[{[<[(<<<{<><>}(()[])>{{()()}[()[]]}>>)[<{[<[]()>({}{})]{{{}[]}[[]]}}{{{[]<>}{()()}}}>[[[[(){}]({}<>)]{ +<[<((<<<{<[({[[][]]<{}{}>})({{<>{}}[()<>]}(({}{})[[]()]))]({{(<><>)<<>()>}{[[]{}]}}({(()())[{}()