-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from amclin/feature/2019-day-02
Feature/2019 day 02
- Loading branch information
Showing
6 changed files
with
195 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,2,6,19,23,1,23,5,27,1,27,13,31,2,6,31,35,1,5,35,39,1,39,10,43,2,6,43,47,1,47,5,51,1,51,9,55,2,55,6,59,1,59,10,63,2,63,9,67,1,67,5,71,1,71,5,75,2,75,6,79,1,5,79,83,1,10,83,87,2,13,87,91,1,10,91,95,2,13,95,99,1,99,9,103,1,5,103,107,1,107,10,111,1,111,5,115,1,115,6,119,1,119,10,123,1,123,10,127,2,127,13,131,1,13,131,135,1,135,10,139,2,139,6,143,1,143,9,147,2,147,6,151,1,5,151,155,1,9,155,159,2,159,6,163,1,163,2,167,1,10,167,0,99,2,14,0,0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const add = ({ posIn1, posIn2, posOut, data }) => { | ||
console.debug(`Adding ${data[Number(posIn1)]} to ${data[Number(posIn2)]}`) | ||
data[posOut] = data[Number(posIn1)] + data[Number(posIn2)] | ||
return true | ||
} | ||
|
||
const multiply = ({ posIn1, posIn2, posOut, data }) => { | ||
console.debug(`Multiplying ${data[Number(posIn1)]} with ${data[Number(posIn2)]}`) | ||
data[posOut] = data[Number(posIn1)] * data[Number(posIn2)] | ||
return true | ||
} | ||
|
||
const terminate = ({ instructionPointer }) => { | ||
console.log(`Reached terminator at instructionPointer ${instructionPointer}. Stopping.`) | ||
return false | ||
} | ||
|
||
const step = ({ instructionPointer, data }) => { | ||
console.debug(`Step: ${instructionPointer}`) | ||
const opCodesMap = { | ||
1: add, | ||
2: multiply, | ||
99: terminate | ||
} | ||
const instruction = data.slice(instructionPointer, instructionPointer + 4) | ||
const opcode = instruction[0] | ||
|
||
// Run the correct opcode for the specified step | ||
return opCodesMap[opcode]({ | ||
posIn1: instruction[1], | ||
posIn2: instruction[2], | ||
posOut: instruction[3], | ||
data, | ||
instructionPointer | ||
}) | ||
} | ||
|
||
const runProgram = ({ data }) => { | ||
let instructionPointer = 0 | ||
let running = true | ||
|
||
// Convert to BigInts because operations will exceed 53bit integers | ||
// TODO: Standard chokes on this ES2020 feature. Remove eslint-disable | ||
// once fixed. | ||
// See https://github.com/standard/standard/issues/1436 | ||
// eslint-disable-next-line no-undef | ||
data.forEach((key, idx) => { data[idx] = BigInt(key) }) | ||
|
||
while (running === true && instructionPointer <= data.length) { | ||
const instructionLength = 4 | ||
running = step({ instructionPointer, data }) | ||
instructionPointer += instructionLength | ||
} | ||
} | ||
|
||
module.exports = { | ||
step, | ||
runProgram | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* eslint-env mocha */ | ||
const expect = require('chai').expect | ||
const { step, runProgram } = require('./intcodeParser') | ||
|
||
describe('--- 2019 Day 2: 1202 Program Alarm ---', () => { | ||
describe('Part 1', () => { | ||
describe('intcodeParser', () => { | ||
describe('step()', () => { | ||
it('can add', () => { | ||
const oppcode = 1 | ||
const data = [oppcode, 5, 6, 3, 99, 2, 3] | ||
step({ instructionPointer: 0, data }) | ||
expect(data[3]).equals(5) | ||
}) | ||
it('can multiply', () => { | ||
const oppcode = 2 | ||
const data = [oppcode, 5, 6, 3, 99, 2, 3] | ||
step({ instructionPointer: 0, data }) | ||
expect(data[3]).equals(6) | ||
}) | ||
it('can terminate', () => { | ||
const oppcode = 99 | ||
const data = [oppcode, 5, 6, 3, 99, 2, 3] | ||
step({ instructionPointer: 0, data }) | ||
expect(data[3]).equals(3) | ||
}) | ||
}) | ||
}) | ||
describe('runProgram()', () => { | ||
it('runs through sequential steps of an intCode program', () => { | ||
const testInputs = [ | ||
[1, 0, 0, 0, 99], | ||
[2, 3, 0, 3, 99], | ||
[2, 4, 4, 5, 99, 0], | ||
[1, 1, 1, 4, 99, 5, 6, 0, 99] | ||
] | ||
const testOutputs = [ | ||
[2, 0, 0, 0, 99], | ||
[2, 3, 0, 6, 99], | ||
[2, 4, 4, 5, 99, 9801], | ||
[30, 1, 1, 4, 2, 5, 6, 0, 99] | ||
] | ||
// Convert outputs to BigInts | ||
testOutputs.forEach((out, idx) => { | ||
out.forEach((value, idx2) => { | ||
// TODO: Standard chokes on this ES2020 feature. Remove eslint-disable | ||
// once fixed. | ||
// See https://github.com/standard/standard/issues/1436 | ||
// eslint-disable-next-line no-undef | ||
testOutputs[idx][idx2] = BigInt(value) | ||
}) | ||
}) | ||
|
||
testInputs.forEach((data, idx) => { | ||
runProgram({ data }) | ||
expect(data).to.deep.equal(testOutputs[idx]) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
const fs = require('fs') | ||
const path = require('path') | ||
const filePath = path.join(__dirname, 'input.txt') | ||
const { runProgram } = require('./intcodeParser') | ||
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() | ||
// Manipulate input per puzzle instructions for Part 1 | ||
data[1] = 12 | ||
data[2] = 2 | ||
runProgram({ data }) | ||
return data[0] | ||
} | ||
|
||
const part2 = ({ target, maxNoun, maxVerb }) => { | ||
// Helper for running the program with specified noun and verb inputs | ||
const tryProgram = ({ | ||
noun, | ||
verb | ||
}) => { | ||
const data = resetInput() | ||
data[1] = noun | ||
data[2] = verb | ||
runProgram({ data }) | ||
console.debug(`Running with noun:${noun} and verb:${verb} produces ${data[0]}`) | ||
return Number(data[0]) | ||
} | ||
|
||
// Manipulate and loop through attempts for Part 2 | ||
let noun = -1 | ||
while (noun <= maxNoun) { | ||
let verb = -1 | ||
noun++ | ||
while (verb <= maxVerb) { | ||
verb++ | ||
const output = tryProgram({ | ||
noun, | ||
verb | ||
}) | ||
// Break the search loop on success | ||
if (output === target) { | ||
return 100 * noun + verb | ||
} | ||
} | ||
} | ||
} | ||
|
||
const answer1 = part1() | ||
const answer2 = part2({ target: 19690720, maxNoun: 99, maxVerb: 99 }) | ||
|
||
console.log('-- Part 1 --') | ||
console.log(`Answer: ${answer1}`) | ||
|
||
console.log('-- Part 2 --') | ||
console.log(`Answer: ${answer2}`) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
require('./2019/day-01/part-1/solution') | ||
require('./2019/day-02/solution') |