Skip to content

Commit b2eac5d

Browse files
feat(2021-day-06): count how many laternfish exist after 80 days
solves part 1
1 parent 6272342 commit b2eac5d

File tree

6 files changed

+166
-1
lines changed

6 files changed

+166
-1
lines changed

2021/day-06/fish.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
let _fishes = []
3+
const NewFishAge = 8 // age of newly spawned fish
4+
const FishSpawnAge = 0 // age when the fish spawns
5+
const ResetFishAge = 6 // age of the original fish after spawning
6+
7+
const ageFish = (age) => {
8+
if (age > NewFishAge) { throw new Error('Fish is too young') }
9+
if (age < FishSpawnAge) { throw new Error('Fish is too old') }
10+
if (age === FishSpawnAge) { return ResetFishAge }
11+
return age - 1
12+
}
13+
14+
const spawn = (qty) => {
15+
console.debug(`spawning ${qty} fish`)
16+
const newFishes = [...new Array(qty)].map(() => NewFishAge)
17+
_fishes.push(...newFishes)
18+
}
19+
20+
const school = {
21+
get state () {
22+
return _fishes
23+
},
24+
set state (state) {
25+
_fishes = state
26+
},
27+
28+
advance: () => {
29+
// Calculate how many will spawn
30+
const toSpawn = _fishes.filter((x) => x === FishSpawnAge).length
31+
// Iterate each fish
32+
_fishes = _fishes.map(ageFish)
33+
// Spawn the new fish
34+
spawn(toSpawn)
35+
}
36+
}
37+
38+
module.exports = {
39+
school,
40+
ageFish,
41+
spawn
42+
}

2021/day-06/fish.test.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* eslint-env mocha */
2+
const { expect } = require('chai')
3+
const { school, ageFish, spawn } = require('./fish')
4+
5+
describe('--- Day 6: Lanternfish ---', () => {
6+
describe('Part 1', () => {
7+
beforeEach(() => {
8+
// ensure flushed state
9+
school.state = [3, 4, 3, 1, 2]
10+
expect(school.state).to.deep.equal([3, 4, 3, 1, 2])
11+
})
12+
describe('spawn()', () => {
13+
it('adds new fish to the end of the list', () => {
14+
spawn(4)
15+
expect(school.state).to.deep.equal([3, 4, 3, 1, 2, 8, 8, 8, 8])
16+
})
17+
})
18+
describe('ageFish()', () => {
19+
it('ages a particular fish', () => {
20+
expect(ageFish(6)).to.equal(5)
21+
expect(ageFish(5)).to.equal(4)
22+
expect(ageFish(4)).to.equal(3)
23+
expect(ageFish(3)).to.equal(2)
24+
expect(ageFish(2)).to.equal(1)
25+
expect(ageFish(1)).to.equal(0)
26+
expect(ageFish(0)).to.equal(6)
27+
expect(ageFish(8)).to.equal(7)
28+
expect(ageFish(7)).to.equal(6)
29+
})
30+
it('throws an error if the fish is out of range', () => {
31+
expect(() => { ageFish(9) }).to.throw('Fish is too young')
32+
expect(() => { ageFish(-1) }).to.throw('Fish is too old')
33+
})
34+
})
35+
describe('advance()', () => {
36+
it('advances one day', () => {
37+
school.state = [3, 4, 3, 1, 2]
38+
school.advance()
39+
expect(school.state).to.deep.equal([2, 3, 2, 0, 1])
40+
school.advance()
41+
expect(school.state).to.deep.equal([1, 2, 1, 6, 0, 8])
42+
school.advance()
43+
expect(school.state).to.deep.equal([0, 1, 0, 5, 6, 7, 8])
44+
school.advance()
45+
expect(school.state).to.deep.equal([6, 0, 6, 4, 5, 6, 7, 8, 8])
46+
school.advance()
47+
expect(school.state).to.deep.equal([5, 6, 5, 3, 4, 5, 6, 7, 7, 8])
48+
school.advance()
49+
expect(school.state).to.deep.equal([4, 5, 4, 2, 3, 4, 5, 6, 6, 7])
50+
school.advance()
51+
expect(school.state).to.deep.equal([3, 4, 3, 1, 2, 3, 4, 5, 5, 6])
52+
school.advance()
53+
expect(school.state).to.deep.equal([2, 3, 2, 0, 1, 2, 3, 4, 4, 5])
54+
school.advance()
55+
expect(school.state).to.deep.equal([1, 2, 1, 6, 0, 1, 2, 3, 3, 4, 8])
56+
school.advance()
57+
expect(school.state).to.deep.equal([0, 1, 0, 5, 6, 0, 1, 2, 2, 3, 7, 8])
58+
school.advance()
59+
expect(school.state).to.deep.equal([6, 0, 6, 4, 5, 6, 0, 1, 1, 2, 6, 7, 8, 8, 8])
60+
school.advance()
61+
expect(school.state).to.deep.equal([5, 6, 5, 3, 4, 5, 6, 0, 0, 1, 5, 6, 7, 7, 7, 8, 8])
62+
school.advance()
63+
expect(school.state).to.deep.equal([4, 5, 4, 2, 3, 4, 5, 6, 6, 0, 4, 5, 6, 6, 6, 7, 7, 8, 8])
64+
school.advance()
65+
expect(school.state).to.deep.equal([3, 4, 3, 1, 2, 3, 4, 5, 5, 6, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8])
66+
school.advance()
67+
expect(school.state).to.deep.equal([2, 3, 2, 0, 1, 2, 3, 4, 4, 5, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7])
68+
school.advance()
69+
expect(school.state).to.deep.equal([1, 2, 1, 6, 0, 1, 2, 3, 3, 4, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 8])
70+
school.advance()
71+
expect(school.state).to.deep.equal([0, 1, 0, 5, 6, 0, 1, 2, 2, 3, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 7, 8])
72+
school.advance()
73+
expect(school.state).to.deep.equal([6, 0, 6, 4, 5, 6, 0, 1, 1, 2, 6, 0, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 8, 8, 8])
74+
school.advance()
75+
})
76+
})
77+
})
78+
})

2021/day-06/index.js

+3
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-06/input.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1,1,3,5,1,3,2,1,5,3,1,4,4,4,1,1,1,3,1,4,3,1,2,2,2,4,1,1,5,5,4,3,1,1,1,1,1,1,3,4,1,2,2,5,1,3,5,1,3,2,5,2,2,4,1,1,1,4,3,3,3,1,1,1,1,3,1,3,3,4,4,1,1,5,4,2,2,5,4,5,2,5,1,4,2,1,5,5,5,4,3,1,1,4,1,1,3,1,3,4,1,1,2,4,2,1,1,2,3,1,1,1,4,1,3,5,5,5,5,1,2,2,1,3,1,2,5,1,4,4,5,5,4,1,1,3,3,1,5,1,1,4,1,3,3,2,4,2,4,1,5,5,1,2,5,1,5,4,3,1,1,1,5,4,1,1,4,1,2,3,1,3,5,1,1,1,2,4,5,5,5,4,1,4,1,4,1,1,1,1,1,5,2,1,1,1,1,2,3,1,4,5,5,2,4,1,5,1,3,1,4,1,1,1,4,2,3,2,3,1,5,2,1,1,4,2,1,1,5,1,4,1,1,5,5,4,3,5,1,4,3,4,4,5,1,1,1,2,1,1,2,1,1,3,2,4,5,3,5,1,2,2,2,5,1,2,5,3,5,1,1,4,5,2,1,4,1,5,2,1,1,2,5,4,1,3,5,3,1,1,3,1,4,4,2,2,4,3,1,1

2021/day-06/solution.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
const filePath = path.join(__dirname, 'input.txt')
4+
const { parseData } = require('../../2018/inputParser')
5+
const { school } = require('./fish')
6+
7+
fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => {
8+
if (err) throw err
9+
10+
initData = parseData(initData.trim())
11+
12+
const resetInput = () => {
13+
// Deep copy to ensure we aren't mutating the original data
14+
return JSON.parse(JSON.stringify(initData))
15+
}
16+
17+
const part1 = () => {
18+
const data = resetInput()
19+
school.state = data
20+
// Advance the designated time
21+
for (let x = 0; x < 80; x++) {
22+
school.advance()
23+
}
24+
// Count how many fish we have
25+
return school.state.length
26+
}
27+
28+
const part2 = () => {
29+
const data = resetInput()
30+
console.debug(data)
31+
return 'No answer yet'
32+
}
33+
const answers = []
34+
answers.push(part1())
35+
answers.push(part2())
36+
37+
answers.forEach((ans, idx) => {
38+
console.info(`-- Part ${idx + 1} --`)
39+
console.info(`Answer: ${ans}`)
40+
})
41+
})

index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
require('./2021/day-05/solution')
1+
require('./2021/day-06/solution')

0 commit comments

Comments
 (0)