Skip to content

Commit 135dbf9

Browse files
Merge pull request #208 from amclin/feat/2021-day-10
Feat/2021 day 10
2 parents df3d9fd + de9a7bf commit 135dbf9

File tree

10 files changed

+414
-7
lines changed

10 files changed

+414
-7
lines changed

2021/day-08/display.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@ gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
1818
describe('--- Day 8: Seven Segment Search ---', () => {
1919
describe('Part 1', () => {
2020
describe('descrambleSignal()', () => {
21-
const testData = testSingle.split('|')[0].trim()
22-
const { segmentCodes, charCodes } = descrambleSignal(testData)
23-
2421
it('takes scambled string of 10 codes and identifies the letters matching each seven-digit-display segment', () => {
22+
const testData = testSingle.split('|')[0].trim()
23+
const { segmentCodes } = descrambleSignal(testData)
2524
expect(segmentCodes.length).to.equal(7)
2625
expect(segmentCodes.filter((code) => !['a', 'b', 'c', 'd', 'e', 'f', 'g'].includes(code)).length).to.equal(0)
2726
})
2827

2928
it('produces a list of character codes for each number that can be displayed', () => {
29+
const testData = testSingle.split('|')[0].trim()
30+
const { charCodes } = descrambleSignal(testData)
3031
// There should be exactly 10 numbers
3132
expect(charCodes.length).to.equal(10)
3233
// lengths of each code is predictable as each number has a specific count of segments
@@ -35,10 +36,9 @@ describe('--- Day 8: Seven Segment Search ---', () => {
3536
})
3637
})
3738
describe('decodeSignal()', () => {
38-
const testData = testMultiple[0].split('|').map((a) => a.trim())
39-
const { charCodes } = descrambleSignal(testData[0])
40-
4139
it('decodes a display pattern using the provided map of display codes', () => {
40+
const testData = testMultiple[0].split('|').map((a) => a.trim())
41+
const { charCodes } = descrambleSignal(testData[0])
4242
const result = decodeSignal(charCodes, testData[1])
4343
expect(result[0]).to.equal(8)
4444
expect(result[3]).to.equal(4)

2021/day-10/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// eslint-disable-next-line no-unused-vars
2+
const console = require('../helpers')
3+
require('./solution')

2021/day-10/input.txt

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
[[<[<{[<{{<[{(()[])[[]()]}[((){})<[]{}>]}<<{[]{}}<(){}>><([]<>)>>>[[[<<>>[<><>]][<<>>(<><>)]][{
2+
((<[(<<(<{<((<()<>>{()()}){<<>><()[]>})([{<>{}}(()[])]{(<><>>})>(<((()())<[][]>)>([(<>{})({}())][<
3+
<<<(<<[[((({<([]<>)[[]]>{<{}>{(){}}}}{[<[][]><<>[]>]({<><>}{()<>})})[<<({}())(()<>)>[([]{})<[]()>]>({[[]
4+
<(<<<[((([{({((){})<<>{}>}[<(){}>[<>()]])[[<{}[]>({}{}]](<<>[]><[]<>>)]}](<[({[][]}<()<>>)<[
5+
{<<<{[({{(<<(<<>[]><[]()>){<[][]>{<>{}}}>((({}())([]<>))[<{}{}>({}())])>(<<<()[]>><<<>{}>(()<
6+
{<{<<[[(<<[{<<{}[]>>([<>()]{{}{}})}]<(<{<>()}{{}()}>{({}[])<<>()>})>>>){[{[{<[[]{}][<><>]>}{(<{}(
7+
(((([(({((<[<(<>{})[{}{}]>](<[()<>]{<><>}>)><<[<[]{}>((){})]<[()[]]>>{[{<>()}((){})]({()[]}(()[]))}>))}(
8+
<<[(({({(<{{((<>[])[[]<>])([<>]{()()})}<<{<>[]}><<{}()>>>}>)(<(<{<()[]><(){}>}{{(){}}[{}<>]}>{
9+
(([[{<[<<{[<{<()[]>{<>[]}}{<{}{}>{[]<>}}>[{<{}{}>(<>[])}]]{<<({}[])>(<[]<>>[{}])>({{<>()}(<
10+
(<{{(<<{[([<<{()[]}>{({}<>){<>[]}]>((<[]{}><{}{}>))]([{(()<>)(<>[])}]<<((){})<<>{}>>[(()[])
11+
{{[[<<{<{{{([{()[]}[{}()]]{(<>{}){<><>}}){<[[][]][()[]]>}}<{{<[][]>[{}[]]>(<<>{}><{}{}>)}>}}<<{[{([](
12+
{[<({{{[<{<{[([][])]{({}())<[][]>}}((<(){}>{()<>})<<<>{}>>)>}(((<{<>{}}<{}()>>)[((()()))[<<>{}>(
13+
{{{[{{[(([{{[[{}<>]([]<>)]([(){}][[]()])}[{{[]<>}[{}()]}(<<><>>]]}][[([[[]<>]<<>{}>][{[]{}
14+
<<{{{[{{[<({<<[]<>><{}<>>>}[[{()<>}{[]<>}]({(){}}{{}()})])[[(<<>[]>[[]])[{{}{}}[[]()]]]<((
15+
({{[{{{{<[[({[{}{}]{[]<>}}<<()<>>(()<>)>)<{{(){}]<()()>}{{(){}}[<><>]}>]<<({{}{}}<(){}>)([{}
16+
{([[[<<([[{{[<()<>>(()<>))({<>[]}(<>{}))}{(<{}()>{()[]})}}([[{{}[]}<[]>]<([]<>){<>}>])]<{[[([]{})]{(<><>)[[]<
17+
([<<([<[[({((({}[]){[]{}}){({}[])({}<>)})>)[(<{{{}{}}[(){}]}(([][])<{}<>>)><[[<><>]{<>{}}]{{{}[]}{[][]}}>)<[[
18+
{[<<{[<{[<{[[({}[])({}<>)]<<{}{}>{{}()}}]{[[<>{}]<[]{}>]}}(([(<><>){[][]}]([<>()]<()[]>))<[<()<>>(<><>)
19+
(<[<[(({{<{<<[{}()]>(([]())<<>[]>)>}[{<[[]{}]([]<>)><{<><>}[()<>]>}{{{(){}}{[]{}}}}]>}}){{<{([<([]())({}())
20+
<<{({{<[<[{([{{}<>}{<><>}]([(){}](()[]))){[{()[]}<<>()>]({()()}({}()))}}]<[<<(())(()[])>>{(<{}<>>{
21+
{{{(<<[(<[([[[()<>]<()[]>]]{[[[]{}]{<>{}}]((<><>)({}{}))})]([(<{<>()}{[]{}}><<{}{}><<>[]>>)[<<()[]>((){
22+
[{(<<{[<<([{[<[][]>][{()()}({}())]}]([{([]{})<{}<>>}(<()>[{}])]{<([]<>)<{}{}>>(({}<>)<<><>>)}))>([[((<<>{}
23+
[[(<({{(({{(<[{}<>]([]{})>{[<>[]]([][])})[(<[]<>><{}()>)[<{}()>(())]]}<[<[[]{}]<{}{}>>{<()()>({}<>)}]<
24+
([(<({(<{{(((<[]<>>{<>()})<{[]{}>([]{})>)[<[()<>]({}[])>[(<>{})(<>[])]]){<((<>{}){()[]})><{<[]<>><<><>>
25+
({{<({(<<({[[{<><>}]<<<><>>({}[])>]([<[]<>>[{}()]]{{<>{}}({}[])}}}<{({[]<>}({}{}))[(<>())(<>())]}((([]{}){[][
26+
(((({[(<([<[(<<>>[[][]])<{<><>}[{}<>]>]{({<>()}(<><>))(({}<>))}>])<([[<<()<>>{[][]}>]<[[[][
27+
[<<(([({((<<{({}())}[(()()){[]<>}]>>){({<[{}{}]<<>()>>{<{}()>}})})})])[[<((<[{([<>()][{}[]])((()[])
28+
{{{<{[[(<[{{<<{}()>[{}<>]>{({}{})<()>}}(<[(){}]>(<(){}>[[]]))}(<<[[]{}}({})><[<>[]]{<><>}>><[<[]<>>{<><>}](((
29+
{<[[<[{{<((<[<<>()><[]{}>][<{}()><{}{}>]>)[[[[[][]]<()[]}][([]{})(()())]]])>[[((<{[]<>}<()>><[{}[]](<><>)>
30+
<{([{[{[{([({<{}[]>([]<>)}[[[][]]<()()>])[<[{}()]>{<<><>>(()<>)}]]){({(<[]<>>([]<>))[(<>){
31+
[{{<(({<{[{<{({})(<>[])}({<><>}{[]()})>(({[]<>}(<>{}))[{()()}{{}<>}])}{<{{<>()}<[]{})}(<()><(
32+
{(<[{[[{{<(([{{}{}}<()[]>]<[<><>]>)([(<><>)])){<<{[]{}}[[][]]>{[[]<>]{<>{}}}>[<<[][]><<>()>><<{}<>>[<>()>>]}>
33+
<[{{(<<{{{[[{<[]<>>(()<>)}<{()<>}{<>[]}>]<[<()()>]{<<>>([]())}>]{([<<>{}>({}<>)])[({{}}{[]<>})[
34+
<<[[<<[(<{{{[{()[]}([]())][[[]]((){})]}}(([{[][]}[()()]]<<()>[{}[]]>))}>)<{({{<[[][]]{()()}><<{}{}
35+
{[<(([([{({([({}()){<><>}][((){})([]())])[<<()<>>(<>())>{[[]()}(()[])}]}<{{<(){}>{()[]}}((<><>){{}<>})}((
36+
{(({([[{{((([<()()>([][])]<<{}[]>[<>]>)(<{<><>}[{}{}]>[[<>{}]]))[{<<[][]>[()]><[{}{}]>}{<([]<>)([]<>)>}]
37+
(({[[<<<{[{([(<>[])<()[]>])(<([])({}{})>)}[{(<<>{}>({}<>))}<<[<>[]>[(){}]>(<{}{}>)>]]{([[<<>()>
38+
[{[[{([({[{(({()[]}[[]<>])<[[]<>]([])>)([{{}{}}[{}[]]]<{{}<>}>)][<(<<>[]>{<><>})<(()<>){[][]}>>[[{[]{}}([]())
39+
([[{({([({<<(<[]<>>)[{()[]}<<>()>]><<{<>()}<<>[]>>[[<>{}]<<><>>]>)<<<<<>[]><<><>>>[[[]]]>[{
40+
[{{([(<[[<{((([]{})[()()])[<[]{}>[<>()]])<[{()()}(<>{})]({[]}[<>{}])>}((<{[]()}>)({<{}{}>[
41+
[[[{{[[[<<(<(({}())[<>{}])<{{}<>}(()())>>[[((){})][[[]{}]{()}]])>>{[(<([{}{}]({}<>))([{}()]<<>[]])>({<
42+
{<{({(({{{[{<(<>{})>{<{}<>>(<><>)}}<(<[]()>[[][]])<[{}()]>>]<{{<()[]>{{}()}}{<{}[]>{{}{}}}}{{<()<>><<>
43+
[{[<{[<<({(<{{<>()}({}<>)}<(<>[])[()()]>>{{{<>()}{()[]}}})<{<({}()){<>{}}>({<>[]}({}())]}>}(
44+
[[{<([((({([{{()[]}<[]{}>}({<>[]}[<><>])]{{<[]<>>[<><>]}[{()()}[<>[]]]})}[{[<{()()}(<>))<({}){()<>}>]([
45+
(<(<{[{<({[{{{[]()}({}{})}{<{}[]><<>{}>}}]})>}<{[[(<[<[]{}>([]())](<{}>[()()])>)][(([{[]<>
46+
<<<<{<{<<[<({<[]>({}<>)})<[{[][]}[[]()]][[{}<>]<{}[]>])>([(([][])[[]()])<[{}[]]{[]{}}>](<[{}()]{{}()}
47+
({[[([([<{[[({()[]}[<>[]])[<[][]><<>{}>>][(({}{})(<>[])){(<>[])}]]<{{{{}()}[<>[]]}<[[]<>]([]())>}>}{<{({
48+
((<{<{{[((<<<(()<>)<[]{}>>[<[][]>[(){}]]>>)){([[[[<>]({}<>)]{{{}<>}([]{})}]<[<<>()>(()())][{[]{}}{[]<>}]>]
49+
{<<{{[({[<{{(<{}[]><<>[]>)([[]()])}<[{{}{}}{<><>}]<({})<{}()>>>}<[([{}<>][<>{}])](<<{}[]><<
50+
{[{[[<<[(({[(((){}){<>[]})]([[<>[]]][<<>{}>[<><>]])})({<[({}[])<{}[]>]>}<(<(()<>)[[]{}]][[()()][<><
51+
((<<[({<{[[({<[]()>([]())}[<[]{}>(()<>)])]<<{[{}[]][<>()]}><<{<>[]}[()<>]>[<[]{}>{[]()}]>>][(({[<>
52+
{{<[{<([({{([<<><>>{{}()}][<[][]>{[]()}])[<[[]]{[]<>}>]}(({<()[]>[{}()]}<[[]<>]{<>()}>))})])<{[{<[<[{}{}]
53+
[(({({[[<{(<{{<>[]}[()<>]}((<>{})<<>[]>)>{[<(){}>{{}<>}]])[<{(<>[]){{}[]}}([()()][<>[]])>((({}())
54+
{(([<{([[{([<<{}()><[][]>>[(<>()){()[]}]]<[<()()>[{}]]([{}<>][{}[]])>){<{[[]<>]<<>{}>}{([]{})}>[([
55+
<{[{({([(<<{<[()<>]<(){}>>(<()>{[][]})})>{[([<{}{}>[<>()]])[{([]()){<>{}}}<<{}<>>>]]})])([<(([{<(){}>[{
56+
<<<(([<[{[[<{({}()>{[]()}}>]]([<[[()][{}[]]]<[()()]{(){}}>><<({}[])(()<>)>{(()[])}>]{[(<[]()>)[{[]{}}
57+
(({(([[<{(<{[(<>[]]]}<(({}{}))([[][]]([][]))>><[{(()())[()<>]}<{(){}}>]>)((<{{()[]}{<>()}}<([
58+
[[[{<[{<[<[[{(<>{})<[]()>}{(()[])[<>()]}][<({}()>[<><>]>{<[]{}><[][]>}]]><<{[{(){}}{{}{}}][<<><
59+
((([<<((<[{(([<>[]]([]{}))([<>]{<>()})}([[(){}][[]()]][(<><>){{}()}])}{[<[()<>]({}<>)>[<{}{}>]][<(<>())<[]
60+
{<<{([(((([{<[()]{(){}}>{{{}[]}}}[{(()[]){()<>}}{<<>>[<>{}]}]]<[{(<>())(()[])}]>){[[<({}{})[()[]]>{[{}(
61+
([{(({([([(<<{<>[]}<{}<>>>[[[]{}]<[]{}>]>((([]<>)<<>[]>)[[(){}]]))[<{{<>{}}}[(<>}{()()}]><{<<>{}><
62+
{(<[<{({([{{([[][]]>({()()}[[][]])}[<(()())([]())><(<><>)([]{})>]}[(({{}{}}{{}<>})([<><>]<()[]>))]
63+
((<(<<{{{{<{{(()<>)({}{})}{{<>[]}<()[]>}}<<<[][]>(()[])>[[()[]][[]()]]>>[[{{[]{}}[[][]]}][<[()[]]{[]<>}>
64+
(((<(<<<{{<{<{{}{}}(()<>)>[((){})[()[]]]}{[[<>[]]{{}()}][{()[]}({}{})]}>}}>{[{<<{[{}()]}<[[]()]
65+
({(([[<{[{<(([[]()](<><>))[<{}[]){{}()}])(<[()[]]<[]()>>[<{}<>>[()<>]])>[<[[()()]<<>[]>][([]())([]{})]>{{<<>(
66+
[[(([((([<[[<{{}<>}({}[])>[([]<>)[()[]]]]<[(()())({}<>)](([]<>)<[]()>)>]>[{{{(()<>)}<{[]()}
67+
(<(({[<<{((<[[[]()]{{}<>}]<<{}()>({}[])>>)<{{({}){()()}}<{[][]}>}>){[(<<[]<>>[{}{}]>{{(){}}{[
68+
{<(<(<<{<(<{{[{}[]]([]{})}([{}[]](<>))}[([<>()]{[]{}})<({}<>){<><>}>]>[{<[[][]]>}[<[<><>](()())>(([
69+
{(<(<{<(<<{{{<(){}>}({[][]}{{}{}})}}<(<<<>()>[(){}]>(<{}()>{{}}))>>[{{[{[]{}}(()[])]}[((<>())<<
70+
([((([[{([{<<((){})>{{<>}{[]()}}>{[((){})<()[]>]<{[]{}}[(){}]>}}{((<{}()><{}>)){{<{}[]>[[]
71+
{{{(<<{((([[{(<>{})({}())}[<[]()>({}{})]]<<[{}]>{[[]()]{()[]}}>]{({<()[]>((){})})<{<[]<>>{{}{}
72+
(<<[[([{{(<<({{}}[{}{}])<([]{}){<>()}>>>(({<()()>({}[])}<<{}()>[(){}]>)))[{([{<>[]}([]())]([()()][<>{}])){
73+
<(<(<<<([[[(<{{}[]}{{}[]}>[[<>()]{()[]}])]<{({{}()}{{}<>})<({}[])([]<>)>}{(({}[])(<>{}))((()<>)<[]()>)}>](<
74+
<<{(([<([[[[<{<>()}({}[])>{((){})[{}()]}]}[<{<<>[]><[]<>>}<[{}<>]{{}()}>>{{(()())[()[]]}{<()<>
75+
(({<<[{([{<(([{}[]][(){}])[<[]()>(()<>)]}>}<[(<{{}()}{{}<>}><[[]()][[]()]>)]<(<(<>())>({<>[]})){[{(){}}<{}{}>
76+
({[[{[{{<(([[[{}{}]<(){}>]((()[])(()[]))]({([]<>)({}{})}{<<>{}>{<>}}))<{(<[]{}>(()()))[[()[]](<><>)
77+
([{[{{<{{(<[((<>){[]()})(({}())[<><>])]>({[(<><>}{{}[]}]{(()[])[()]}}{([[]{}](<><>))<<{}[]>(<>())>}))
78+
<[(([[[<{[[(({()[]}<<>[]>){{<><>}<(){}>})<([()]{<>[]}){{<>{}}}>]]<[{{([]())({}{}>}<{[][]}<<>{}>
79+
({(<{<([[<{[<{[]()}[{}<>>>[[(){}][[]{}]]][{[()<>][<><>]}{<()()>}]}<({{(){}}<()()>}{[<><>](<>())})[(
80+
([({<[<[{({<<[<>{})[<><>]>{{[]{}}}>[[{()<>}([]{})](({}<>)<<>>)]}<{<<<>>{()[]}>}<{<[]()>}>>)(<<<{
81+
({<{[[({[([{[{[]{}}{[]<>}](((){})({}()))}]([<{<>{}}{()<>}>{({}{})(()())}])}]<{({{<()[]>{()}}
82+
({[[{[((<[[[{<<>[]>(<>[])}]]{<({{}[]}){[{}{}]<<>()>}>[([<>()]{{}()})(<()()><<>[]>)]}]>(<([{<[]{}>(()())}<{[
83+
[<<<{<({({{<{[<><>]{{}<>}}{<(){}>}>}})})[<<[{[{({}{})<<>>}[{[]}(()())]]{{([]())([]())}{({}[])[<>
84+
<<<[[((<{{<(((<>[])(()))<<<>()><<>{}>>)<[{<>[]}{(){}}]{[{}]({}())}>>}}[[((({()}{[][]}){<{}[]>}
85+
(<[<({[[{[<<[(<>[])]([[]<>]<[]{}>)>({(<>[])([]())}<[{}<>)<<>{}>>)>[{<[[][]]><[{}<>]<[]()>>}<<[
86+
{[({<<<<(<([{{[][]}}]{<{<>()}<<>()>>[({}())<[]{}>]})>)>>><<<{{((([{}[]]<<><>>)[[[][]]({}[])])<{<{}{}>(
87+
[[[({((({<([({[][]}{[]})<({}[]}[{}{}]>][([[]()]([]()))<<()<>>>])<[<<()[]><()[]>>]>>([<<{[]()}{[][]}><
88+
[{{<<<({<({(<<<><>>>{(<>[])[<><>]})<(<<>{}>(()()))[{{}()}{(){}}]}}[(<{[]()}<[]<>>>({<>{}}[{}
89+
([<<{<[{([<[<{<>{}}<[]{}>><([][]>>][{([][])[()()]}<<[]<>>>]>][{<({<>()}<[][]>)[[[]<>]{()<>}
90+
({<<[<(<<<(<((()<>)<{}<>>)>)<<([<>{}][<>[]])<<()()>({}[])>>([(()())(()<>)]{{{}<>}<[]{}>})>>>>[
91+
<{[{<[[<[(<{({<><>}{[]<>}){<[]{}><()>}}({({})[[]{}]})>{(<{[]<>}{<><>}>([{}[]]{<><>}))(<<{}()>[
92+
<{{<[[({{{<({<[]()>[{}[]]}<{<><>}{()<>}>)[<<[]{}>{{}<>}>[<<>[]>((){})]]>}}(<[[(([][])[{}<>]){(()<>)[()[]]}]((
93+
[{[{<[(({{({<{{}{}}<()()>>(<[]<>>{<>[]})}(<<()[]>{()<>}>))<<<[{}{}]<<>[]>>>[[{[]{}}]((()<>){<>
94+
{[[<{({[<(<((<{}[]>){[{}[]]})[{[{}{}]({}())}]>(<{{()<>}(<><>)}[(<><>)<[]{}]]><{<()[]>([][])

2021/day-10/linting.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const pairs = {
2+
'(': ')',
3+
'[': ']',
4+
'{': '}',
5+
'<': '>'
6+
}
7+
8+
const lintLine = (line) => {
9+
let expected = ''
10+
let pos = 0
11+
while (pos < line.length) {
12+
const char = line[pos]
13+
14+
// if opening bracket, add mate to the start of expected list
15+
if (pairs[char]) {
16+
expected += pairs[char]
17+
} else { // if closing bracket
18+
// if expected closing, clear from the expected list
19+
if (expected[expected.length - 1] === char) {
20+
expected = expected.slice(0, -1)
21+
} else { // otherwise, found an error to report
22+
return {
23+
char: pos,
24+
expected: expected[expected.length - 1],
25+
found: char
26+
}
27+
}
28+
}
29+
30+
pos++
31+
}
32+
33+
// if we run out of characters in the line, that means it is
34+
// incomplete, and we need to provide an autocomplete suggestion
35+
if (expected.length > 0) {
36+
// Reversing the 'expected' string gives us the autocomplete suggestion
37+
return {
38+
suggestion: [...expected].reverse().join('')
39+
}
40+
}
41+
}
42+
43+
const lintAll = (instructions) => {
44+
const errors = instructions.map(lintLine) // lint each line
45+
.map((error, idx) => {
46+
return { ...error, line: idx }
47+
}).filter((report) => !!(report.char) || !!(report.suggestion)) // remove lines without errors
48+
49+
console.log(`Linting found ${errors.length} errors in ${instructions.length} lines.`)
50+
// console.debug(instructions)
51+
// console.debug(errors)
52+
53+
return errors
54+
}
55+
56+
module.exports = {
57+
lintLine,
58+
lintAll
59+
}

2021/day-10/linting.test.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/* eslint-env mocha */
2+
const { expect } = require('chai')
3+
const { lintLine, lintAll } = require('./linting')
4+
5+
const badChunks = [
6+
'(]',
7+
'{()()()>',
8+
'(((()))}',
9+
'<([]){()}[{}])'
10+
]
11+
12+
const testData = `[({(<(())[]>[[{[]{<()<>>
13+
[(()[<>])]({[<{<<[]>>(
14+
{([(<{}[<>[]}>{[]{[(<()>
15+
(((({<>}<{<{<>}{[]{[]{}
16+
[[<[([]))<([[{}[[()]]]
17+
[{[{({}]{}}([{[{{{}}([]
18+
{<[[]]>}<{[{[{[]{()[[[]
19+
[<(<(<(<{}))><([]([]()
20+
<{([([[(<>()){}]>(<<{{
21+
<{([{{}}[<[[[<>{}]]]>[]]`
22+
23+
const autocomplete = {
24+
'[({(<(())[]>[[{[]{<()<>>': '}}]])})]',
25+
'[(()[<>])]({[<{<<[]>>(': ')}>]})',
26+
'(((({<>}<{<{<>}{[]{[]{}': '}}>}>))))',
27+
'{<[[]]>}<{[{[{[]{()[[[]': ']]}}]}]}>',
28+
'<{([{{}}[<[[[<>{}]]]>[]]': '])}>'
29+
}
30+
31+
describe('--- Day 10: Syntax Scoring ---', () => {
32+
describe('Part 1', () => {
33+
describe('lintLine()', () => {
34+
it('finds instnces of closing brackets that mismatch the opening brackets', () => {
35+
expect(lintLine(badChunks[0])).to.deep.equal(
36+
{
37+
char: 1,
38+
expected: ')',
39+
found: ']'
40+
}
41+
)
42+
expect(lintLine(badChunks[1])).to.deep.equal(
43+
{
44+
char: 7,
45+
expected: '}',
46+
found: '>'
47+
}
48+
)
49+
expect(lintLine(badChunks[2])).to.deep.equal(
50+
{
51+
char: 7,
52+
expected: ')',
53+
found: '}'
54+
}
55+
)
56+
expect(lintLine(badChunks[3])).to.deep.equal(
57+
{
58+
char: 13,
59+
expected: '>',
60+
found: ')'
61+
}
62+
)
63+
})
64+
})
65+
describe('lintAll', () => {
66+
it('finds all lines with linting errors', () => {
67+
const errors = lintAll(testData.split('\n'))
68+
.filter((err) => (err.char))
69+
70+
expect(errors.length).to.equal(5)
71+
expect(errors[0]).to.deep.equal({
72+
line: 2,
73+
char: 12,
74+
expected: ']',
75+
found: '}'
76+
})
77+
expect(errors[1]).to.deep.equal({
78+
line: 4,
79+
char: 8,
80+
expected: ']',
81+
found: ')'
82+
})
83+
expect(errors[2]).to.deep.equal({
84+
line: 5,
85+
char: 7,
86+
expected: ')',
87+
found: ']'
88+
})
89+
expect(errors[3]).to.deep.equal({
90+
line: 7,
91+
char: 10,
92+
expected: '>',
93+
found: ')'
94+
})
95+
expect(errors[4]).to.deep.equal({
96+
line: 8,
97+
char: 16,
98+
expected: ']',
99+
found: '>'
100+
})
101+
})
102+
it('provides autocomplete suggestions for incomplete lines', () => {
103+
const data = testData.split('\n')
104+
const errors = lintAll(data)
105+
.filter((err) => !!err.suggestion)
106+
107+
expect(errors.length).to.equal(5)
108+
errors.forEach((err) => {
109+
expect(err.suggestion).to.equal(
110+
autocomplete[data[err.line]]
111+
)
112+
})
113+
})
114+
it('skips lines without errors', () => {
115+
const errors = lintAll([
116+
'[]',
117+
'[()]'
118+
])
119+
expect(errors.length).to.equal(0)
120+
})
121+
})
122+
})
123+
})

2021/day-10/scoring.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
const findMiddleScore = (scores) => {
3+
// According to specs, there's always an odd number of items in the list,
4+
// so we're safe to divide by 2 and round down to get the desired index
5+
return scores.sort((a, b) => a - b)[
6+
Math.floor(scores.length / 2)
7+
]
8+
}
9+
10+
// How many points each character is worth in autocomplete scoring
11+
const pointValues = {
12+
')': 1,
13+
']': 2,
14+
'}': 3,
15+
'>': 4
16+
}
17+
18+
const scoreAutocomplete = (suggestion) => {
19+
return [...suggestion].reduce((score, char) => {
20+
return (score * 5) + pointValues[char]
21+
}, 0)
22+
}
23+
24+
module.exports = {
25+
findMiddleScore,
26+
scoreAutocomplete
27+
}

2021/day-10/scoring.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* eslint-env mocha */
2+
const { expect } = require('chai')
3+
const { findMiddleScore, scoreAutocomplete } = require('./scoring')
4+
5+
const scoreData = [
6+
288957,
7+
5566,
8+
1480781,
9+
995444,
10+
294
11+
]
12+
13+
const autocompleteSuggestions = [
14+
'}}]])})]',
15+
')}>]})',
16+
'}}>}>))))',
17+
']]}}]}]}>',
18+
'])}>'
19+
]
20+
21+
describe('--- Day 10: Syntax Scoring ---', () => {
22+
describe('Part 2', () => {
23+
describe('scoreAutocomplete()', () => {
24+
it('takes a single autocomplete suggestion and scores it', () => {
25+
autocompleteSuggestions.forEach((suggestion, idx) => {
26+
expect(scoreAutocomplete(suggestion)).to.equal(scoreData[idx])
27+
})
28+
})
29+
})
30+
describe('findMiddleScore()', () => {
31+
it('takes a list of scores and returns the middle entry after sorting', () => {
32+
expect(findMiddleScore(scoreData)).to.equal(288957)
33+
})
34+
})
35+
})
36+
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy