Skip to content

Commit fa113b6

Browse files
Merge pull request #206 from amclin/feat/2021-day-08
Feat/2021 day 08
2 parents 556767c + caa74ac commit fa113b6

File tree

8 files changed

+819
-3
lines changed

8 files changed

+819
-3
lines changed

2021/day-08/display.js

Lines changed: 469 additions & 0 deletions
Large diffs are not rendered by default.

2021/day-08/display.test.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/* eslint-env mocha */
2+
const { expect } = require('chai')
3+
const { descrambleSignal, decodeSignal, parseEntry } = require('./display')
4+
5+
const testSingle = 'acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf'
6+
7+
const testMultiple = `be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
8+
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
9+
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
10+
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
11+
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
12+
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
13+
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
14+
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
15+
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
16+
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce`.split('\n')
17+
18+
describe('--- Day 8: Seven Segment Search ---', () => {
19+
describe('Part 1', () => {
20+
describe('descrambleSignal()', () => {
21+
const testData = testSingle.split('|')[0].trim()
22+
const { segmentCodes, charCodes } = descrambleSignal(testData)
23+
24+
it('takes scambled string of 10 codes and identifies the letters matching each seven-digit-display segment', () => {
25+
expect(segmentCodes.length).to.equal(7)
26+
expect(segmentCodes.filter((code) => !['a', 'b', 'c', 'd', 'e', 'f', 'g'].includes(code)).length).to.equal(0)
27+
})
28+
29+
it('produces a list of character codes for each number that can be displayed', () => {
30+
// There should be exactly 10 numbers
31+
expect(charCodes.length).to.equal(10)
32+
// lengths of each code is predictable as each number has a specific count of segments
33+
const expectedLengths = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
34+
expect(charCodes.map(code => code.length)).to.deep.equal(expectedLengths)
35+
})
36+
})
37+
describe('decodeSignal()', () => {
38+
const testData = testMultiple[0].split('|').map((a) => a.trim())
39+
const { charCodes } = descrambleSignal(testData[0])
40+
41+
it('decodes a display pattern using the provided map of display codes', () => {
42+
const result = decodeSignal(charCodes, testData[1])
43+
expect(result[0]).to.equal(8)
44+
expect(result[3]).to.equal(4)
45+
})
46+
it('throws an error if a digit doesn`t have a matching code', () => {
47+
expect(
48+
() => decodeSignal(
49+
[['a']],
50+
'dcb'
51+
)
52+
).to.throw(
53+
'No match found for dcb when cleaned up to b,c,d'
54+
)
55+
})
56+
it('throws an error if a digit has multiple matches (meaning a bad codes map)', () => {
57+
expect(
58+
() => decodeSignal(
59+
[['a'], ['d', 'c', 'b'], ['b', 'c', 'd']],
60+
'dcb'
61+
)
62+
).to.throw(
63+
'Too many matches for dcb when cleaned up to b,c,d. This most likely indicates a bad list of character codes.'
64+
)
65+
})
66+
})
67+
})
68+
describe('Part 2', () => {
69+
describe('parseEntry()', () => {
70+
it('parses a set of scrambled codes and signal to produce a number for display', () => {
71+
expect(
72+
parseEntry(
73+
testSingle.split('|').map((x) => x.trim())
74+
)
75+
).to.equal(5353)
76+
77+
const testData = testMultiple.map(
78+
(entry) => entry.split('|')
79+
.map((x) => x.trim())
80+
).map(parseEntry)
81+
82+
expect(testData.reduce((a, b) => a + b)).to.equal(61229)
83+
})
84+
})
85+
})
86+
})

2021/day-08/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-08/input.txt

Lines changed: 200 additions & 0 deletions
Large diffs are not rendered by default.

2021/day-08/solution.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
const filePath = path.join(__dirname, 'input.txt')
4+
const { linesToArray } = require('../../2018/inputParser')
5+
const { descrambleSignal, decodeSignal, parseEntry } = require('./display')
6+
7+
fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => {
8+
if (err) throw err
9+
10+
initData = linesToArray(initData.trim())
11+
12+
const resetInput = () => {
13+
// Deep copy to ensure we aren't mutating the original data
14+
return JSON.parse(JSON.stringify(
15+
initData.map(
16+
(line) => line.split('|')
17+
.map((e) => e.trim())
18+
)
19+
))
20+
}
21+
22+
const part1 = () => {
23+
const data = resetInput()
24+
25+
return data.map((entry) => {
26+
const { charCodes } = descrambleSignal(entry[0])
27+
return decodeSignal(charCodes, entry[1])
28+
}).reduce((total, signal) => {
29+
const search = [1, 4, 7, 8]
30+
31+
// Find how many of our desired numbers are in the signal
32+
total += signal.filter((digit) => search.includes(digit)).length
33+
34+
return total
35+
}, 0)
36+
}
37+
38+
const part2 = () => {
39+
const data = resetInput()
40+
41+
return data.map(parseEntry)
42+
.reduce((a, b) => a + b)
43+
}
44+
const answers = []
45+
answers.push(part1())
46+
answers.push(part2())
47+
48+
answers.forEach((ans, idx) => {
49+
console.info(`-- Part ${idx + 1} --`)
50+
console.info(`Answer: ${ans}`)
51+
})
52+
})

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
![](https://img.shields.io/badge/stars%20⭐-14-yellow)
1010
![](https://img.shields.io/badge/days%20completed-7-red)
1111

12-
## Start a boilerplate for a new day
12+
## Run the currently configured default day
13+
`npm start`
14+
15+
### Run in debug mode for extended logging
16+
`DEBUG=1 npm start`
17+
## Generate a boilerplate for a new day
1318
`npm run new`
1419
### Special Instructions
1520
Run by modifying `index.js` to point to the puzzle you want to execute.

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
require('./2021/day-07/solution')
1+
require('./2021/day-08/solution')

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"posttest": "nyc report --reporter=html --reporter=text-lcov > coverage.lcov",
1111
"lint": "standard",
1212
"report-coverage": "codecov",
13-
"new": "npx plop --plopfile ./plop-templates/plopfile.js"
13+
"new": "npx plop --plopfile ./plop-templates/plopfile.js",
14+
"start": "node ./index.js"
1415
},
1516
"repository": {
1617
"type": "git",

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