|
| 1 | +/* eslint-env mocha */ |
| 2 | +const { expect } = require('chai') |
| 3 | +const { school, ageFish, spawn, efficientSchool, efficientSpawn } = 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 | + }) |
| 75 | + }) |
| 76 | + }) |
| 77 | + describe('Part 2', () => { |
| 78 | + beforeEach(() => { |
| 79 | + // ensure flushed state |
| 80 | + efficientSchool.state = [3, 4, 3, 1, 2] |
| 81 | + expect(efficientSchool.state).to.deep.equal([0, 1, 1, 2, 1, 0, 0, 0, 0]) |
| 82 | + }) |
| 83 | + describe('efficientSpawn()', () => { |
| 84 | + it('efficiently adds new fish to the school', () => { |
| 85 | + efficientSpawn(4) |
| 86 | + expect(efficientSchool.state).to.deep.equal([0, 1, 1, 2, 1, 0, 0, 0, 4]) |
| 87 | + }) |
| 88 | + }) |
| 89 | + describe('efficientAdvance', () => { |
| 90 | + it('advances one day following the same pattern without tracking unique position', () => { |
| 91 | + const sum = (x, y) => x + y |
| 92 | + efficientSchool.state = [3, 4, 3, 1, 2] |
| 93 | + |
| 94 | + efficientSchool.advance() |
| 95 | + expect(efficientSchool.state.reduce(sum)).to.equal([2, 3, 2, 0, 1].length) |
| 96 | + efficientSchool.advance() |
| 97 | + expect(efficientSchool.state.reduce(sum)).to.equal([1, 2, 1, 6, 0, 8].length) |
| 98 | + efficientSchool.advance() |
| 99 | + expect(efficientSchool.state.reduce(sum)).to.equal([0, 1, 0, 5, 6, 7, 8].length) |
| 100 | + efficientSchool.advance() |
| 101 | + expect(efficientSchool.state.reduce(sum)).to.equal([6, 0, 6, 4, 5, 6, 7, 8, 8].length) |
| 102 | + efficientSchool.advance() |
| 103 | + expect(efficientSchool.state.reduce(sum)).to.equal([5, 6, 5, 3, 4, 5, 6, 7, 7, 8].length) |
| 104 | + efficientSchool.advance() |
| 105 | + expect(efficientSchool.state.reduce(sum)).to.equal([4, 5, 4, 2, 3, 4, 5, 6, 6, 7].length) |
| 106 | + efficientSchool.advance() |
| 107 | + expect(efficientSchool.state.reduce(sum)).to.equal([3, 4, 3, 1, 2, 3, 4, 5, 5, 6].length) |
| 108 | + efficientSchool.advance() |
| 109 | + expect(efficientSchool.state.reduce(sum)).to.equal([2, 3, 2, 0, 1, 2, 3, 4, 4, 5].length) |
| 110 | + efficientSchool.advance() |
| 111 | + expect(efficientSchool.state.reduce(sum)).to.equal([1, 2, 1, 6, 0, 1, 2, 3, 3, 4, 8].length) |
| 112 | + efficientSchool.advance() |
| 113 | + expect(efficientSchool.state.reduce(sum)).to.equal([0, 1, 0, 5, 6, 0, 1, 2, 2, 3, 7, 8].length) |
| 114 | + efficientSchool.advance() |
| 115 | + expect(efficientSchool.state.reduce(sum)).to.equal([6, 0, 6, 4, 5, 6, 0, 1, 1, 2, 6, 7, 8, 8, 8].length) |
| 116 | + efficientSchool.advance() |
| 117 | + expect(efficientSchool.state.reduce(sum)).to.equal([5, 6, 5, 3, 4, 5, 6, 0, 0, 1, 5, 6, 7, 7, 7, 8, 8].length) |
| 118 | + efficientSchool.advance() |
| 119 | + expect(efficientSchool.state.reduce(sum)).to.equal([4, 5, 4, 2, 3, 4, 5, 6, 6, 0, 4, 5, 6, 6, 6, 7, 7, 8, 8].length) |
| 120 | + efficientSchool.advance() |
| 121 | + expect(efficientSchool.state.reduce(sum)).to.equal([3, 4, 3, 1, 2, 3, 4, 5, 5, 6, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8].length) |
| 122 | + efficientSchool.advance() |
| 123 | + expect(efficientSchool.state.reduce(sum)).to.equal([2, 3, 2, 0, 1, 2, 3, 4, 4, 5, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7].length) |
| 124 | + efficientSchool.advance() |
| 125 | + expect(efficientSchool.state.reduce(sum)).to.equal([1, 2, 1, 6, 0, 1, 2, 3, 3, 4, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 8].length) |
| 126 | + efficientSchool.advance() |
| 127 | + expect(efficientSchool.state.reduce(sum)).to.equal([0, 1, 0, 5, 6, 0, 1, 2, 2, 3, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 7, 8].length) |
| 128 | + efficientSchool.advance() |
| 129 | + expect(efficientSchool.state.reduce(sum)).to.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].length) |
| 130 | + }) |
| 131 | + it('advances efficiently for a large number of days', () => { |
| 132 | + efficientSchool.state = [3, 4, 3, 1, 2] |
| 133 | + for (let d = 1; d <= 256; d++) { |
| 134 | + efficientSchool.advance() |
| 135 | + } |
| 136 | + const sum = (x, y) => x + y |
| 137 | + efficientSchool.state.reduce(sum) |
| 138 | + }) |
| 139 | + }) |
| 140 | + }) |
| 141 | +}) |
0 commit comments