Skip to content

Commit 84894e9

Browse files
feat(2021-day-08): count occurrences of numbers 1,4,7,8 in scrambled signals
solves part 1
1 parent 17cc8f7 commit 84894e9

File tree

4 files changed

+95
-7
lines changed

4 files changed

+95
-7
lines changed

2021/day-08/display.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,36 @@
2828
// })
2929
// }
3030

31+
/**
32+
* Using a map of character codes, decode a signal
33+
* @param {array} charCodes
34+
* @param {string} signal
35+
*/
36+
const decodeSignal = (charCodes, signal) => {
37+
console.debug('2021-day-08 decodeSignal()')
38+
39+
const digits = signal.split(' ')
40+
.map(
41+
(code) => {
42+
const clean = code.split('').sort() // cleanup format to match expected map of codes
43+
const matches = charCodes.filter((c) => {
44+
// sort here on the charCode is just in case non-alphabatized data is provided
45+
return (JSON.stringify(c.sort()) === JSON.stringify(clean))
46+
})
47+
if (matches.length < 1) {
48+
throw new Error(`No match found for ${code} when cleaned up to ${clean}`)
49+
}
50+
if (matches.length > 1) {
51+
throw new Error(`Too many matches for ${code} when cleaned up to ${clean}. This most likely indicates a bad list of character codes.`)
52+
}
53+
54+
// The key in charCodes for the match is the decoded number we want
55+
return charCodes.indexOf(matches[0])
56+
}
57+
)
58+
59+
return digits
60+
}
3161

3262
/**
3363
* Takes a string of scrambled codes and deduces which codes correspond
@@ -454,5 +484,6 @@ const descrambleSignal = (data) => {
454484
}
455485

456486
module.exports = {
487+
decodeSignal,
457488
descrambleSignal
458489
}

2021/day-08/display.test.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
/* eslint-env mocha */
22
const { expect } = require('chai')
3-
const { descrambleSignal } = require('./display')
3+
const { descrambleSignal, decodeSignal } = require('./display')
44

55
const testSingle = 'acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf'
66

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+
718
console.debug(
819
testSingle.split('|')[0].trim()
920
.split(' ').map(
@@ -31,5 +42,35 @@ describe('--- Day 8: Seven Segment Search ---', () => {
3142
expect(charCodes.map(code => code.length)).to.deep.equal(expectedLengths)
3243
})
3344
})
45+
describe('decodeSignal()', () => {
46+
const testData = testMultiple[0].split('|').map((a) => a.trim())
47+
const { charCodes } = descrambleSignal(testData[0])
48+
49+
it('decodes a display pattern using the provided map of display codes', () => {
50+
const result = decodeSignal(charCodes, testData[1])
51+
expect(result[0]).to.equal(8)
52+
expect(result[3]).to.equal(4)
53+
})
54+
it('throws an error if a digit doesn`t have a matching code', () => {
55+
expect(
56+
() => decodeSignal(
57+
[['a']],
58+
'dcb'
59+
)
60+
).to.throw(
61+
'No match found for dcb when cleaned up to b,c,d'
62+
)
63+
})
64+
it('throws an error if a digit has multiple matches (meaning a bad codes map)', () => {
65+
expect(
66+
() => decodeSignal(
67+
[['a'], ['d', 'c', 'b'], ['b', 'c', 'd']],
68+
'dcb'
69+
)
70+
).to.throw(
71+
'Too many matches for dcb when cleaned up to b,c,d. This most likely indicates a bad list of character codes.'
72+
)
73+
})
74+
})
3475
})
3576
})

2021/day-08/solution.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
11
const fs = require('fs')
22
const path = require('path')
33
const filePath = path.join(__dirname, 'input.txt')
4-
const { inputToArray } = require('../../2018/inputParser')
4+
const { linesToArray } = require('../../2018/inputParser')
5+
const { descrambleSignal, decodeSignal } = require('./display')
56

67
fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => {
78
if (err) throw err
89

9-
initData = inputToArray(initData.trim())
10+
initData = linesToArray(initData.trim())
1011

1112
const resetInput = () => {
1213
// Deep copy to ensure we aren't mutating the original data
13-
return JSON.parse(JSON.stringify(initData))
14+
return JSON.parse(JSON.stringify(
15+
initData.map(
16+
(line) => line.split('|')
17+
.map((e) => e.trim())
18+
)
19+
))
1420
}
1521

1622
const part1 = () => {
1723
const data = resetInput()
18-
console.debug(data)
19-
return 'No answer yet'
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)
2036
}
2137

2238
const part2 = () => {

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')

0 commit comments

Comments
 (0)