Skip to content

Commit ac5fe27

Browse files
Merge pull request #201 from amclin/feat/2021-day-03
feat(2021-day-03)
2 parents 2726f09 + e7aa119 commit ac5fe27

File tree

6 files changed

+1203
-1
lines changed

6 files changed

+1203
-1
lines changed

2021/day-03/engineDiagnostics.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Find the most common bit at a position
3+
* @param [str] data
4+
* @param int position
5+
*/
6+
const getMostCommon = (data, position) => {
7+
const offs = data.filter((reading) => {
8+
return reading[position] === '0'
9+
}).length
10+
// there can only be 2 values, so easy to check which has more as being above 50%
11+
return (offs > data.length / 2) ? '0' : '1'
12+
}
13+
14+
/**
15+
* Find the least common bit at a position
16+
* @param [str] data
17+
* @param int position
18+
*/
19+
const getLeastCommon = (data, position) => {
20+
return (getMostCommon(data, position) === '0') ? '1' : '0'
21+
}
22+
23+
/**
24+
* Calc the gamma value of the data set
25+
* @param [str] data
26+
*/
27+
const getGamma = (data) => {
28+
let gamma = ''
29+
for (let x = 0; x < data[0].length; x++) {
30+
gamma += getMostCommon(data, x)
31+
}
32+
return gamma
33+
}
34+
35+
const getEpsilon = (data) => {
36+
let epsilon = ''
37+
for (let x = 0; x < data[0].length; x++) {
38+
epsilon += getLeastCommon(data, x)
39+
}
40+
return epsilon
41+
}
42+
43+
const getO2 = (data) => {
44+
return getAir(data, getMostCommon)
45+
}
46+
47+
const getCO2 = (data) => {
48+
return getAir(data, getLeastCommon)
49+
}
50+
51+
const getAir = (data, filterMethod) => {
52+
let dataset = data
53+
// Loop through each digit, find the most common bit for that digit, and filter
54+
// out any readings that don't share that digit
55+
//
56+
// TODO: Probably faster with bitmap math, but .... ehh... runs fast enough
57+
for (let x = 0; x < data[0].length; x++) {
58+
if (dataset.length > 1) {
59+
const bit = filterMethod(dataset, x)
60+
dataset = dataset.filter((reading) => {
61+
return reading[x] === bit
62+
})
63+
}
64+
}
65+
66+
if (dataset.length > 1) {
67+
throw new Error(`Found too many results ${dataset}`)
68+
}
69+
70+
return dataset[0]
71+
}
72+
73+
const calcPowerConsumption = (gamma, epsilon) => {
74+
return parseInt(gamma, 2) * parseInt(epsilon, 2)
75+
}
76+
77+
module.exports = {
78+
getGamma,
79+
getEpsilon,
80+
getMostCommon,
81+
getLeastCommon,
82+
getO2,
83+
getCO2,
84+
calcPowerConsumption,
85+
calcLifeSupport: calcPowerConsumption
86+
}

2021/day-03/engineDiagnostics.test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* eslint-env mocha */
2+
const { expect } = require('chai')
3+
const { getMostCommon, getLeastCommon, getEpsilon, getGamma, getO2, getCO2, calcPowerConsumption, calcLifeSupport } = require('./engineDiagnostics')
4+
5+
const testData = [
6+
'00100',
7+
'11110',
8+
'10110',
9+
'10111',
10+
'10101',
11+
'01111',
12+
'00111',
13+
'11100',
14+
'10000',
15+
'11001',
16+
'00010',
17+
'01010'
18+
]
19+
20+
describe('--- Day 3: Binary Diagnostic ---', () => {
21+
describe('Part 1', () => {
22+
describe('getMostCommon()', () => {
23+
it('finds the most common bit at a position', () => {
24+
expect(getMostCommon(testData, 0)).to.equal('1')
25+
expect(getMostCommon(testData, 1)).to.equal('0')
26+
expect(getMostCommon(testData, 2)).to.equal('1')
27+
expect(getMostCommon(testData, 3)).to.equal('1')
28+
expect(getMostCommon(testData, 4)).to.equal('0')
29+
})
30+
})
31+
describe('getLeastCommon()', () => {
32+
it('finds the least common bit at a position', () => {
33+
expect(getLeastCommon(testData, 0)).to.equal('0')
34+
expect(getLeastCommon(testData, 1)).to.equal('1')
35+
expect(getLeastCommon(testData, 2)).to.equal('0')
36+
expect(getLeastCommon(testData, 3)).to.equal('0')
37+
expect(getLeastCommon(testData, 4)).to.equal('1')
38+
})
39+
})
40+
describe('getGamma()', () => {
41+
it('finds the gamma rate from the provided data using the most common bits in each position', () => {
42+
expect(getGamma(testData)).to.equal('10110')
43+
})
44+
})
45+
describe('getEpsilon()', () => {
46+
it('finds the epsilon rate from the provided data using the least common bits in each position', () => {
47+
expect(getEpsilon(testData)).to.equal('01001')
48+
})
49+
})
50+
describe('calcPowerConsumption', () => {
51+
it('calculates the power consumption by multiplying the gamma and epsilon rates as decimals', () => {
52+
expect(calcPowerConsumption('10110', '01001')).to.equal(198)
53+
})
54+
})
55+
})
56+
describe('Part 2', () => {
57+
describe('getO2()', () => {
58+
it('calculates the oxygen generator rating from the provided data', () => {
59+
expect(getO2(testData)).to.equal('10111')
60+
})
61+
})
62+
describe('getCO2()', () => {
63+
it('calculates the carbon dioxide scrubber rating from the provided data', () => {
64+
expect(getCO2(testData)).to.equal('01010')
65+
})
66+
})
67+
describe('calcLifeSupport', () => {
68+
it('calculates the life support rating by multiplying the O2 and C02 rates rates as decimals', () => {
69+
expect(calcLifeSupport('10110', '01001')).to.equal(198)
70+
})
71+
})
72+
})
73+
})

2021/day-03/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')

0 commit comments

Comments
 (0)