From d72ca1168b4885021a1e21789265aefaefa045ee Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 11:00:50 -0800 Subject: [PATCH 01/11] feat(2020-day-08): stub in structure --- 2020/day-08/index.js | 3 +++ 2020/day-08/input.txt | 0 2020/day-08/solution.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 2020/day-08/index.js create mode 100644 2020/day-08/input.txt create mode 100644 2020/day-08/solution.js diff --git a/2020/day-08/index.js b/2020/day-08/index.js new file mode 100644 index 0000000..af7e035 --- /dev/null +++ b/2020/day-08/index.js @@ -0,0 +1,3 @@ +// eslint-disable-next-line no-unused-vars +const console = require('../helpers') +require('./solution') diff --git a/2020/day-08/input.txt b/2020/day-08/input.txt new file mode 100644 index 0000000..e69de29 diff --git a/2020/day-08/solution.js b/2020/day-08/solution.js new file mode 100644 index 0000000..779f7ea --- /dev/null +++ b/2020/day-08/solution.js @@ -0,0 +1,35 @@ +const fs = require('fs') +const path = require('path') +const filePath = path.join(__dirname, 'input.txt') +const { inputToArray } = require('../../2018/inputParser') + +fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { + if (err) throw err + + initData = inputToArray(initData.trim()) + + const resetInput = () => { + // Deep copy to ensure we aren't mutating the original data + return JSON.parse(JSON.stringify(initData)) + } + + const part1 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + + const part2 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + const answers = [] + answers.push(part1()) + answers.push(part2()) + + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) +}) From a5b4653c75ec1bb46a0135b192c3ec02d05b2ee2 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 11:14:36 -0800 Subject: [PATCH 02/11] test(2020-day-08): design solution using stub tests --- 2020/day-08/runProgram.js | 6 +++++ 2020/day-08/runProgram.test.js | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 2020/day-08/runProgram.js create mode 100644 2020/day-08/runProgram.test.js diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js new file mode 100644 index 0000000..0b7e180 --- /dev/null +++ b/2020/day-08/runProgram.js @@ -0,0 +1,6 @@ +module.exports = { + run: console.log('run'), + executeStep: console.log('executeStep'), + logStep: console.log('logStep'), + displayLog: console.log('displayLog') +} diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js new file mode 100644 index 0000000..bd85e54 --- /dev/null +++ b/2020/day-08/runProgram.test.js @@ -0,0 +1,48 @@ +/* eslint-env mocha */ +const { expect } = require('chai') +const { run, executeStep, logStep, displayLog } = require('./runProgram') + +xdescribe('--- Day 8: Handheld Halting ---', () => { + describe('Part 1', () => { + describe('run()', () => { + it('executes the steps of a given program', () => { + run() + expect(false).to.equal(true) + }) + }) + describe('executeStep()', () => { + it('executes a specified command', () => { + executeStep() + expect(false).to.equal(true) + }) + it('steps to the next sequential command', () => { + logStep() + expect(false).to.equal(true) + }) + it('can execute a `nop` command which does nothing', () => { + executeStep('nop') + expect(false).to.equal(true) + }) + it('can execute a `acc` command which increments the accumulator', () => { + executeStep('acc') + expect(false).to.equal(true) + }) + it('can execute a `jmp` command which jumps to a different command in the instruction set', () => { + executeStep('jmp') + expect(false).to.equal(true) + }) + }) + describe('logStep()', () => { + it('records the step in the execution log', () => { + logStep() + expect(false).to.equal(true) + }) + }) + describe('displayLog()', () => { + it('renders the output of the execution log', () => { + displayLog() + expect(false).to.equal(true) + }) + }) + }) +}) From 15d8048d4b683244fd4c290f4b21ab8e82b4076d Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 12:37:01 -0800 Subject: [PATCH 03/11] feat(2020-day-08): format the program's log output Helps for unit testing for validating against the sample data --- 2020/day-08/runProgram.js | 50 +++++++++++++++++++++++++++++++++- 2020/day-08/runProgram.test.js | 26 ++++++++++++++---- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index 0b7e180..cf945d6 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -1,6 +1,54 @@ +const log = [] +log[0] = [1] +log[1] = [2, 8] +log[2] = [3] +log[3] = [6] +log[4] = [7] +log[6] = [4] +log[7] = [5] + +const program = [ + 'nop +0', + 'acc +1', + 'jmp +4', + 'acc +3', + 'jmp -3', + 'acc -99', + 'acc +1', + 'jmp -4', + 'acc +6' +] + +const formatLogRow = (command, idx, program) => { + let countStr + if (!log[idx]) { + countStr = '' + } + if (log[idx] && log[idx].length === 1) { + countStr = `${log[idx][0]}` + } + if (log[idx] && log[idx].length > 1) { + countStr = `${log[idx].join(', ')}(!)` + } + + return `${command.padEnd(8, ' ')}| ${countStr}` +} + +const displayLog = () => { + const formattedLog = program.map(formatLogRow) + .reduce((res, row) => { + res += '\n' + res += row + return res + }, '') + + console.debug(formattedLog) + return formattedLog +} + module.exports = { run: console.log('run'), executeStep: console.log('executeStep'), logStep: console.log('logStep'), - displayLog: console.log('displayLog') + displayLog } diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js index bd85e54..fd41e11 100644 --- a/2020/day-08/runProgram.test.js +++ b/2020/day-08/runProgram.test.js @@ -2,15 +2,26 @@ const { expect } = require('chai') const { run, executeStep, logStep, displayLog } = require('./runProgram') -xdescribe('--- Day 8: Handheld Halting ---', () => { +const exampleLog = ` +nop +0 | 1 +acc +1 | 2, 8(!) +jmp +4 | 3 +acc +3 | 6 +jmp -3 | 7 +acc -99 | +acc +1 | 4 +jmp -4 | 5 +acc +6 | ` + +describe('--- Day 8: Handheld Halting ---', () => { describe('Part 1', () => { - describe('run()', () => { + xdescribe('run()', () => { it('executes the steps of a given program', () => { run() expect(false).to.equal(true) }) }) - describe('executeStep()', () => { + xdescribe('executeStep()', () => { it('executes a specified command', () => { executeStep() expect(false).to.equal(true) @@ -32,7 +43,7 @@ xdescribe('--- Day 8: Handheld Halting ---', () => { expect(false).to.equal(true) }) }) - describe('logStep()', () => { + xdescribe('logStep()', () => { it('records the step in the execution log', () => { logStep() expect(false).to.equal(true) @@ -40,8 +51,11 @@ xdescribe('--- Day 8: Handheld Halting ---', () => { }) describe('displayLog()', () => { it('renders the output of the execution log', () => { - displayLog() - expect(false).to.equal(true) + expect( + displayLog() + ).to.equal( + exampleLog + ) }) }) }) From c570b51e8f96bafc90844ed64bafc23e244559a2 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 13:02:27 -0800 Subject: [PATCH 04/11] refactor(2020-day-08): restructure runtime debugging output --- 2020/day-08/runProgram.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index cf945d6..4154798 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -30,11 +30,14 @@ const formatLogRow = (command, idx, program) => { if (log[idx] && log[idx].length > 1) { countStr = `${log[idx].join(', ')}(!)` } - - return `${command.padEnd(8, ' ')}| ${countStr}` + const row = `${command.padEnd(8, ' ')}| ${countStr}` + console.debug(row) + return row } const displayLog = () => { + console.debug(`${program.length} steps in program.`) + console.debug('-----------------------------------') const formattedLog = program.map(formatLogRow) .reduce((res, row) => { res += '\n' @@ -42,7 +45,6 @@ const displayLog = () => { return res }, '') - console.debug(formattedLog) return formattedLog } From a09406e481b2755458dc5b1ebf1238fdf131cfb9 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 14:30:24 -0800 Subject: [PATCH 05/11] feat(2020-day-08): record program events to logs --- 2020/day-08/runProgram.js | 19 ++++++++++++++++++- 2020/day-08/runProgram.test.js | 10 +++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index 4154798..cc30a8b 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -48,9 +48,26 @@ const displayLog = () => { return formattedLog } +const logStep = ({ instKey, stepKey }) => { + console.debug(`step ${instKey} called instruction ${instKey}`) + if ( + log[instKey] && + typeof log[instKey] === 'object' && + log[instKey].length > 0 + ) { + // Record another entry on a command already executed once + log[instKey].push(stepKey) + return log[instKey] + } else { + // Record the first entry on a command + log[instKey] = [stepKey] + } + return log[instKey] +} + module.exports = { run: console.log('run'), executeStep: console.log('executeStep'), - logStep: console.log('logStep'), + logStep, displayLog } diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js index fd41e11..a3161f0 100644 --- a/2020/day-08/runProgram.test.js +++ b/2020/day-08/runProgram.test.js @@ -43,10 +43,14 @@ describe('--- Day 8: Handheld Halting ---', () => { expect(false).to.equal(true) }) }) - xdescribe('logStep()', () => { + describe('logStep()', () => { it('records the step in the execution log', () => { - logStep() - expect(false).to.equal(true) + const result = logStep({ instKey: 500, stepKey: 17 }) + expect(result).to.deep.equal([17]) + }) + it('tracks the state over multiple logging events', () => { + const result = logStep({ instKey: 500, stepKey: 24 }) + expect(result).to.deep.equal([17, 24]) }) }) describe('displayLog()', () => { From 86d0d4441593ea91ffe390df3711000eb443e1fe Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 14:49:46 -0800 Subject: [PATCH 06/11] refactor(2020-day-08): rename program steps to events --- 2020/day-08/runProgram.js | 10 +++++----- 2020/day-08/runProgram.test.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index cc30a8b..21b4d2c 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -48,19 +48,19 @@ const displayLog = () => { return formattedLog } -const logStep = ({ instKey, stepKey }) => { - console.debug(`step ${instKey} called instruction ${instKey}`) +const logEvent = ({ instKey, evKey }) => { + console.debug(`event ${evKey} called instruction ${instKey}`) if ( log[instKey] && typeof log[instKey] === 'object' && log[instKey].length > 0 ) { // Record another entry on a command already executed once - log[instKey].push(stepKey) + log[instKey].push(evKey) return log[instKey] } else { // Record the first entry on a command - log[instKey] = [stepKey] + log[instKey] = [evKey] } return log[instKey] } @@ -68,6 +68,6 @@ const logStep = ({ instKey, stepKey }) => { module.exports = { run: console.log('run'), executeStep: console.log('executeStep'), - logStep, + logEvent, displayLog } diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js index a3161f0..e7e8e4e 100644 --- a/2020/day-08/runProgram.test.js +++ b/2020/day-08/runProgram.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const { expect } = require('chai') -const { run, executeStep, logStep, displayLog } = require('./runProgram') +const { run, executeStep, logEvent, displayLog } = require('./runProgram') const exampleLog = ` nop +0 | 1 @@ -27,7 +27,7 @@ describe('--- Day 8: Handheld Halting ---', () => { expect(false).to.equal(true) }) it('steps to the next sequential command', () => { - logStep() + logEvent() expect(false).to.equal(true) }) it('can execute a `nop` command which does nothing', () => { @@ -43,13 +43,13 @@ describe('--- Day 8: Handheld Halting ---', () => { expect(false).to.equal(true) }) }) - describe('logStep()', () => { + describe('logEvent()', () => { it('records the step in the execution log', () => { - const result = logStep({ instKey: 500, stepKey: 17 }) + const result = logEvent({ instKey: 500, evKey: 17 }) expect(result).to.deep.equal([17]) }) it('tracks the state over multiple logging events', () => { - const result = logStep({ instKey: 500, stepKey: 24 }) + const result = logEvent({ instKey: 500, evKey: 24 }) expect(result).to.deep.equal([17, 24]) }) }) From 7f9cb68e3f7b851c5393f3deec04d8304c3b2ae5 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 15:21:45 -0800 Subject: [PATCH 07/11] feat(2020-day-08): command parser to convert strings into usable commands --- 2020/day-08/runProgram.js | 7 +++++ 2020/day-08/runProgram.test.js | 56 +++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index 21b4d2c..99c085e 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -19,6 +19,12 @@ const program = [ 'acc +6' ] +const parseCommand = (inst) => { + console.debug('Parsing ', inst) + const [cmd, arg] = inst.split(' ') + return { cmd, arg } +} + const formatLogRow = (command, idx, program) => { let countStr if (!log[idx]) { @@ -68,6 +74,7 @@ const logEvent = ({ instKey, evKey }) => { module.exports = { run: console.log('run'), executeStep: console.log('executeStep'), + parseCommand, logEvent, displayLog } diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js index e7e8e4e..23c708f 100644 --- a/2020/day-08/runProgram.test.js +++ b/2020/day-08/runProgram.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const { expect } = require('chai') -const { run, executeStep, logEvent, displayLog } = require('./runProgram') +const { run, parseCommand, logEvent, displayLog } = require('./runProgram') const exampleLog = ` nop +0 | 1 @@ -21,26 +21,40 @@ describe('--- Day 8: Handheld Halting ---', () => { expect(false).to.equal(true) }) }) - xdescribe('executeStep()', () => { - it('executes a specified command', () => { - executeStep() - expect(false).to.equal(true) - }) - it('steps to the next sequential command', () => { - logEvent() - expect(false).to.equal(true) - }) - it('can execute a `nop` command which does nothing', () => { - executeStep('nop') - expect(false).to.equal(true) - }) - it('can execute a `acc` command which increments the accumulator', () => { - executeStep('acc') - expect(false).to.equal(true) - }) - it('can execute a `jmp` command which jumps to a different command in the instruction set', () => { - executeStep('jmp') - expect(false).to.equal(true) + // xdescribe('execInstruction()', () => { + // it('executes a specified command', () => { + // execInstruction() + // expect(false).to.equal(true) + // }) + // it('steps to the next sequential command', () => { + // logEvent() + // expect(false).to.equal(true) + // }) + // it('can execute a `nop` command which does nothing', () => { + // execInstruction('nop') + // expect(false).to.equal(true) + // }) + // it('can execute a `acc` command which increments the accumulator', () => { + // execInstruction('acc') + // expect(false).to.equal(true) + // }) + // it('can execute a `jmp` command which jumps to a different command in the instruction set', () => { + // execInstruction('jmp') + // expect(false).to.equal(true) + // }) + // }) + describe('parseCommand()', () => { + it('parses an instruction string into a structured command object', () => { + const instructions = [ + 'jmp +4', + 'acc +3', + 'jmp -3', + 'acc -99' + ] + instructions.forEach((inst) => { + const { cmd, arg } = parseCommand(inst) + expect(`${cmd} ${arg}`).to.equal(inst) + }) }) }) describe('logEvent()', () => { From b9deb2ca4a6fdc9944c7f4b548fa27f5db617845 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Wed, 9 Dec 2020 16:07:09 -0800 Subject: [PATCH 08/11] feat(2020-day-08): execute commands from the language --- 2020/day-08/runProgram.js | 43 ++++++++++++++++++++++++++- 2020/day-08/runProgram.test.js | 54 +++++++++++++++++++--------------- 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index 99c085e..c4ba73d 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -19,12 +19,51 @@ const program = [ 'acc +6' ] +let accumulator = 0 +let position = 1 + +/** + * API of commands this language supports + */ +const api = { + nop: (a, b) => { + console.debug(`doing a nop ${b}`) + return a + 1 + }, + acc: (a, b) => { + console.debug(`adding ${b} to accumulator`) + accumulator += api[b.substr(0, 1)]( + 0, + Number(b.substr((1))) + ) + return a + 1 + }, + jmp: (a, b) => { + console.debug(`jumping from ${a} ${b} `) + return a + api[b.substr(0, 1)]( + 0, + Number(b.substr((1))) + ) + }, + '+': (x, y) => x + y, + '-': (x, y) => x - y +} + const parseCommand = (inst) => { console.debug('Parsing ', inst) const [cmd, arg] = inst.split(' ') return { cmd, arg } } +const execInstruction = (inst, instKey = 0, evKey = 0) => { + const { cmd, arg } = parseCommand(inst) + // Run the command + // Support jumping by passing back next + position = api[cmd](instKey, arg) + logEvent({ instKey, evKey }) + return position +} + const formatLogRow = (command, idx, program) => { let countStr if (!log[idx]) { @@ -73,7 +112,9 @@ const logEvent = ({ instKey, evKey }) => { module.exports = { run: console.log('run'), - executeStep: console.log('executeStep'), + getAccumulator: () => accumulator, + getPosition: () => position, + execInstruction, parseCommand, logEvent, displayLog diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js index 23c708f..e80db41 100644 --- a/2020/day-08/runProgram.test.js +++ b/2020/day-08/runProgram.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const { expect } = require('chai') -const { run, parseCommand, logEvent, displayLog } = require('./runProgram') +const { run, getPosition, getAccumulator, execInstruction, parseCommand, logEvent, displayLog } = require('./runProgram') const exampleLog = ` nop +0 | 1 @@ -21,28 +21,36 @@ describe('--- Day 8: Handheld Halting ---', () => { expect(false).to.equal(true) }) }) - // xdescribe('execInstruction()', () => { - // it('executes a specified command', () => { - // execInstruction() - // expect(false).to.equal(true) - // }) - // it('steps to the next sequential command', () => { - // logEvent() - // expect(false).to.equal(true) - // }) - // it('can execute a `nop` command which does nothing', () => { - // execInstruction('nop') - // expect(false).to.equal(true) - // }) - // it('can execute a `acc` command which increments the accumulator', () => { - // execInstruction('acc') - // expect(false).to.equal(true) - // }) - // it('can execute a `jmp` command which jumps to a different command in the instruction set', () => { - // execInstruction('jmp') - // expect(false).to.equal(true) - // }) - // }) + describe('execInstruction()', () => { + it('executes a specified command', () => { + expect(getPosition()).to.equal(1) + expect(execInstruction('acc +3', 300, 600)).to.equal(301) + expect(getAccumulator()).to.equal(3) + expect(getPosition()).to.equal(301) + }) + xit('steps to the next sequential command', () => { + // logEvent() + // expect(false).to.equal(true) + }) + it('can execute a `nop` command which does nothing', () => { + const acc = getAccumulator() + expect(execInstruction('nop +3', 999, 600)).to.equal(1000) + expect(getPosition()).to.equal(1000) + expect(getAccumulator()).to.equal(acc) + }) + it('can execute a `acc` command which increments the accumulator', () => { + const acc = getAccumulator() + expect(execInstruction('acc +100', 1234, 600)).to.equal(1235) + expect(getPosition()).to.equal(1235) + expect(getAccumulator()).to.equal(acc + 100) + }) + it('can execute a `jmp` command which jumps to a different command in the instruction set', () => { + const acc = getAccumulator() + expect(execInstruction('jmp -23', 400, 600)).to.equal(377) + expect(getPosition()).to.equal(377) + expect(getAccumulator()).to.equal(acc) + }) + }) describe('parseCommand()', () => { it('parses an instruction string into a structured command object', () => { const instructions = [ From 4cc6c1c2272fe55c86b76f673dee27edb9183f06 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Thu, 10 Dec 2020 17:31:59 -0800 Subject: [PATCH 09/11] feat(2020-day-08): run an entire brogram, breaking on infinite loop --- 2020/day-08/runProgram.js | 25 ++++++++++++++++++++++--- 2020/day-08/runProgram.test.js | 26 ++++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index c4ba73d..1806e2b 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -1,4 +1,4 @@ -const log = [] +let log = [] log[0] = [1] log[1] = [2, 8] log[2] = [3] @@ -7,7 +7,7 @@ log[4] = [7] log[6] = [4] log[7] = [5] -const program = [ +let program = [ 'nop +0', 'acc +1', 'jmp +4', @@ -21,6 +21,7 @@ const program = [ let accumulator = 0 let position = 1 +let breaker = false /** * API of commands this language supports @@ -61,9 +62,27 @@ const execInstruction = (inst, instKey = 0, evKey = 0) => { // Support jumping by passing back next position = api[cmd](instKey, arg) logEvent({ instKey, evKey }) + // break out when reaching an infinite loop + if (log[instKey].length > 1) { + breaker = true + } return position } +const run = (insts) => { + program = insts + accumulator = 0 + position = 0 + log = [] + let evKey = 0 + + // eslint-disable-next-line no-unmodified-loop-condition + while (breaker === false) { + evKey++ + execInstruction(program[position], position, evKey) + } +} + const formatLogRow = (command, idx, program) => { let countStr if (!log[idx]) { @@ -111,7 +130,7 @@ const logEvent = ({ instKey, evKey }) => { } module.exports = { - run: console.log('run'), + run, getAccumulator: () => accumulator, getPosition: () => position, execInstruction, diff --git a/2020/day-08/runProgram.test.js b/2020/day-08/runProgram.test.js index e80db41..79ed830 100644 --- a/2020/day-08/runProgram.test.js +++ b/2020/day-08/runProgram.test.js @@ -2,6 +2,17 @@ const { expect } = require('chai') const { run, getPosition, getAccumulator, execInstruction, parseCommand, logEvent, displayLog } = require('./runProgram') +const exampleProgram = [ + 'nop +0', + 'acc +1', + 'jmp +4', + 'acc +3', + 'jmp -3', + 'acc -99', + 'acc +1', + 'jmp -4', + 'acc +6' +] const exampleLog = ` nop +0 | 1 acc +1 | 2, 8(!) @@ -15,12 +26,6 @@ acc +6 | ` describe('--- Day 8: Handheld Halting ---', () => { describe('Part 1', () => { - xdescribe('run()', () => { - it('executes the steps of a given program', () => { - run() - expect(false).to.equal(true) - }) - }) describe('execInstruction()', () => { it('executes a specified command', () => { expect(getPosition()).to.equal(1) @@ -84,5 +89,14 @@ describe('--- Day 8: Handheld Halting ---', () => { ) }) }) + describe('run()', () => { + it('executes the steps of a given program', () => { + run(exampleProgram) + // stops at infinite loop + expect(getPosition()).to.equal(2) + expect(getAccumulator()).to.equal(6) + expect(displayLog()).to.equal(exampleLog) + }) + }) }) }) From 7bdd8b985838e2070858d306e0a87544536c285f Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Thu, 10 Dec 2020 18:06:34 -0800 Subject: [PATCH 10/11] fix(2020-day-08): accumulator should return without error command applied If error command changes accumulator, then that needs to be reversed before outputting the accumulator --- 2020/day-08/runProgram.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/2020/day-08/runProgram.js b/2020/day-08/runProgram.js index 1806e2b..32437f7 100644 --- a/2020/day-08/runProgram.js +++ b/2020/day-08/runProgram.js @@ -65,6 +65,16 @@ const execInstruction = (inst, instKey = 0, evKey = 0) => { // break out when reaching an infinite loop if (log[instKey].length > 1) { breaker = true + console.error(`execuetd an error on ${instKey}`, inst, accumulator) + // step back the accumulator + if (cmd === 'acc') { + if (arg.includes('+')) { + api[cmd](0, arg.replace('+', '-')) + } + if (arg.includes('-')) { + api[cmd](0, arg.replace('+-', '+')) + } + } } return position } From 12967ca2f46696fb9a92b426497203acbf6826df Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Thu, 10 Dec 2020 18:07:25 -0800 Subject: [PATCH 11/11] feat(2020-day-08): solution for day 08 part 1 --- 2020/day-08/input.txt | 649 ++++++++++++++++++++++++++++++++++++++++ 2020/day-08/solution.js | 9 +- 2 files changed, 655 insertions(+), 3 deletions(-) diff --git a/2020/day-08/input.txt b/2020/day-08/input.txt index e69de29..98cec52 100644 --- a/2020/day-08/input.txt +++ b/2020/day-08/input.txt @@ -0,0 +1,649 @@ +acc +7 +acc +23 +acc +41 +jmp +173 +acc -17 +acc +42 +acc +31 +jmp +349 +jmp +1 +jmp +252 +nop +574 +jmp +298 +acc +45 +acc +7 +jmp +338 +nop +5 +nop +528 +jmp +547 +jmp +313 +jmp +387 +acc +43 +acc +48 +acc +38 +jmp +45 +jmp +438 +acc +15 +acc +21 +acc +25 +acc +25 +jmp +168 +jmp -5 +acc +49 +acc +43 +jmp +99 +acc -8 +acc +16 +acc -7 +jmp +513 +jmp +484 +jmp +270 +nop +422 +acc -4 +nop +242 +jmp +1 +jmp +11 +nop +122 +nop +263 +acc +2 +jmp +474 +jmp +501 +nop +38 +acc -7 +acc +0 +nop +85 +jmp +496 +acc +11 +acc -13 +acc +40 +acc +29 +jmp +519 +jmp +409 +acc +41 +jmp +1 +acc -17 +jmp +16 +nop +485 +acc -7 +jmp +58 +acc +16 +acc +1 +jmp +123 +jmp +157 +acc +43 +jmp +422 +jmp +1 +acc -19 +acc +48 +jmp +80 +jmp +500 +jmp -59 +acc +34 +acc +11 +jmp +75 +nop +467 +acc -16 +acc +9 +acc +32 +jmp -69 +acc -13 +jmp +422 +jmp +96 +acc -10 +acc -19 +jmp -68 +acc +31 +nop +102 +acc +25 +jmp +140 +acc +34 +acc +45 +acc -9 +acc -17 +jmp -34 +nop +262 +jmp +236 +acc +0 +acc +32 +jmp +269 +acc +16 +jmp +1 +jmp +382 +jmp -39 +acc +45 +nop +166 +nop +408 +acc +10 +jmp +379 +jmp +1 +acc +44 +jmp +249 +nop +334 +acc +36 +nop +442 +acc +5 +jmp +440 +acc +0 +acc +44 +jmp +432 +acc +48 +acc +4 +acc +50 +jmp +355 +acc +31 +jmp +1 +acc +46 +nop -74 +jmp +33 +jmp +91 +nop +463 +acc +41 +nop -2 +jmp +132 +acc +41 +acc +43 +acc +28 +jmp -65 +acc -17 +acc +33 +jmp +183 +acc +11 +jmp +181 +jmp +450 +acc -18 +acc -2 +acc +44 +nop +416 +jmp +108 +acc -18 +acc +12 +acc -1 +acc -19 +jmp +321 +acc +50 +acc -17 +jmp +1 +nop +161 +jmp -41 +jmp +52 +jmp +84 +acc +11 +acc +19 +acc +40 +jmp +293 +acc +29 +jmp +1 +jmp +311 +nop +91 +acc +1 +acc +0 +acc +16 +jmp -42 +acc +0 +acc -16 +acc +41 +nop +348 +jmp -39 +nop -114 +nop +320 +acc +46 +acc -1 +jmp +55 +nop +278 +jmp -94 +acc +47 +jmp +365 +acc +44 +jmp -58 +jmp +1 +jmp +114 +acc -13 +acc -5 +acc +12 +jmp +183 +nop +237 +acc +26 +acc +49 +acc +1 +jmp -189 +acc +7 +acc +2 +jmp -190 +acc -17 +acc +18 +acc -1 +jmp -47 +nop -39 +acc -18 +nop +354 +jmp +264 +acc +46 +jmp +179 +acc +22 +acc +24 +jmp +309 +acc +45 +acc -9 +jmp -206 +jmp +34 +nop +254 +acc +9 +acc +32 +jmp +391 +acc +9 +acc +20 +acc +7 +acc +48 +jmp -85 +acc +27 +acc -3 +jmp +146 +acc -12 +acc +37 +acc +23 +jmp +1 +jmp +48 +acc +46 +jmp +99 +acc -12 +acc -2 +acc +49 +jmp +1 +jmp +293 +jmp +1 +acc +38 +jmp +13 +jmp -215 +jmp -145 +acc +7 +nop +73 +nop +189 +jmp +167 +jmp +332 +acc +29 +jmp -146 +jmp +198 +acc +10 +jmp +342 +acc +31 +jmp -136 +acc +16 +acc +33 +acc +26 +jmp -48 +acc +14 +jmp +91 +acc -15 +nop +274 +acc -2 +jmp -75 +acc +14 +acc +21 +acc +4 +jmp +332 +jmp -243 +acc +25 +acc -5 +jmp +250 +acc -17 +acc +32 +acc +28 +acc +34 +jmp -80 +acc +23 +acc +30 +acc +10 +nop -98 +jmp -205 +acc -16 +acc -15 +acc +49 +acc +15 +jmp +11 +nop +97 +acc -2 +acc +31 +jmp +1 +jmp -130 +acc +25 +jmp +129 +nop -231 +jmp +274 +jmp -280 +acc +0 +acc -14 +acc +8 +nop -224 +jmp +328 +acc +6 +acc +29 +acc +9 +jmp -229 +acc +8 +jmp -284 +acc +4 +acc +0 +jmp -200 +acc +18 +acc +33 +jmp -76 +acc -2 +jmp +139 +nop -70 +acc -6 +acc +9 +jmp -25 +nop +21 +acc +37 +acc +15 +acc +45 +jmp +130 +acc +45 +acc -5 +jmp -86 +acc -15 +jmp +55 +nop -305 +acc +24 +jmp -275 +jmp +1 +acc +31 +acc -19 +jmp -148 +acc +27 +jmp +279 +acc +11 +jmp +253 +acc +17 +nop -1 +acc -15 +jmp -57 +acc +12 +acc +10 +acc -7 +acc +18 +jmp -100 +acc +39 +jmp -180 +jmp +155 +acc -14 +acc -10 +acc -14 +nop -202 +jmp -267 +acc +11 +acc +0 +jmp -130 +acc +19 +acc -18 +jmp +166 +jmp +61 +jmp +13 +acc -2 +jmp +1 +acc +19 +jmp -160 +acc +23 +jmp +1 +acc +37 +acc +40 +jmp +86 +acc +17 +acc -18 +jmp -195 +acc +11 +nop -149 +acc -13 +jmp +41 +acc -16 +jmp -30 +acc +34 +acc +13 +acc +38 +jmp +46 +acc -13 +acc +34 +jmp -273 +acc -9 +acc -8 +acc +23 +acc +8 +jmp +82 +acc +3 +acc +43 +nop +137 +jmp -46 +acc -15 +acc +41 +acc +25 +acc +3 +jmp -208 +acc +0 +jmp -169 +acc +20 +acc +12 +jmp -221 +acc -14 +jmp +96 +acc +47 +acc +25 +acc +7 +jmp +141 +acc -19 +jmp -294 +acc +28 +jmp -94 +acc +35 +jmp +33 +jmp -349 +acc -17 +jmp +193 +jmp +1 +acc -16 +jmp -169 +jmp +1 +nop -258 +acc +44 +nop -13 +jmp -330 +jmp +189 +acc +20 +acc +31 +nop +35 +acc +42 +jmp +64 +acc +9 +nop -406 +acc -14 +jmp +1 +jmp +74 +acc +34 +acc +0 +jmp -285 +jmp -422 +nop -338 +jmp +47 +nop -445 +jmp -145 +jmp +1 +jmp -116 +acc +41 +acc +44 +acc +34 +jmp -146 +acc +44 +jmp -434 +acc +44 +acc +34 +jmp -185 +acc -17 +nop -187 +nop -5 +jmp -96 +nop -20 +jmp -199 +acc +33 +jmp -229 +nop +50 +jmp -263 +acc -5 +acc -4 +acc +16 +jmp -340 +jmp -77 +nop -71 +jmp -168 +acc -18 +nop -447 +nop -479 +jmp -118 +acc +49 +nop -35 +jmp -264 +acc +21 +jmp -76 +acc +25 +acc +46 +jmp -339 +jmp -382 +nop -54 +nop -169 +jmp -208 +acc -8 +jmp -395 +acc -8 +acc +45 +nop -312 +jmp +92 +jmp -31 +acc +45 +acc +42 +nop -259 +jmp -169 +nop -255 +nop -69 +acc +47 +acc +35 +jmp -428 +acc +15 +acc +47 +acc +50 +acc +13 +jmp -491 +jmp -386 +acc +32 +acc +36 +jmp -73 +acc +22 +acc +0 +acc +35 +jmp -531 +acc +21 +nop -365 +acc +16 +jmp +89 +acc +50 +jmp -467 +acc +42 +nop -167 +acc +39 +jmp -481 +acc -13 +acc +49 +acc +8 +acc -11 +jmp -47 +acc +22 +acc +23 +nop +14 +jmp +56 +jmp -57 +acc +0 +acc +45 +acc -12 +jmp -339 +acc +41 +jmp -286 +acc +24 +acc -14 +acc +7 +nop -481 +jmp -539 +acc +14 +jmp -511 +acc +1 +acc -14 +jmp +1 +acc -12 +jmp -123 +acc -17 +acc +11 +jmp -16 +nop -148 +acc -14 +jmp -485 +nop -258 +nop -123 +acc +22 +jmp -359 +nop -527 +nop -443 +acc +43 +jmp +1 +jmp -406 +acc +39 +acc +13 +acc +3 +acc -5 +jmp -585 +acc +41 +acc +26 +jmp -83 +acc +30 +acc +8 +acc +36 +jmp -150 +acc +36 +acc +43 +jmp -305 +acc +10 +acc +33 +jmp -188 +nop -285 +acc -4 +jmp -385 +acc -1 +jmp +1 +nop -23 +jmp -471 +acc +24 +acc +16 +acc +29 +jmp -114 +nop -471 +acc +4 +nop -360 +nop -294 +jmp -220 +acc -18 +acc +21 +acc +10 +acc +0 +jmp -166 +jmp -192 +acc +37 +acc +24 +nop -198 +jmp -425 +acc -19 +acc +43 +jmp -608 +acc +17 +acc +32 +acc +0 +jmp -424 +acc +50 +acc +46 +nop -555 +acc -16 +jmp +1 \ No newline at end of file diff --git a/2020/day-08/solution.js b/2020/day-08/solution.js index 779f7ea..e222dc5 100644 --- a/2020/day-08/solution.js +++ b/2020/day-08/solution.js @@ -1,12 +1,13 @@ const fs = require('fs') const path = require('path') const filePath = path.join(__dirname, 'input.txt') -const { inputToArray } = require('../../2018/inputParser') +const { linesToArray } = require('../../2018/inputParser') +const { run, getAccumulator, displayLog } = require('./runProgram') fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { if (err) throw err - initData = inputToArray(initData.trim()) + initData = linesToArray(initData.trim()) const resetInput = () => { // Deep copy to ensure we aren't mutating the original data @@ -16,7 +17,9 @@ fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { const part1 = () => { const data = resetInput() console.debug(data) - return 'No answer yet' + run(data) + console.info(displayLog()) + return getAccumulator() } const part2 = () => {