Files
advent-of-code-2019/day-02/computer.nim
Marcel Fries c8d7b67888 Day 4 Part 1
2019-12-04 13:49:33 +01:00

69 lines
2.0 KiB
Nim

import sequtils, strutils
type
Program* = seq[int]
Input* = object
noun*: int
verb*: int
Computer* = ref object
source: Program # Original program code without modifications
program*: Program # The computers program in memory
ic*: int # The instruction counter
StopExecution = object of Exception
## This will be raised when the ending opcode is reached
proc set(cp: Computer, address, value: int): void =
cp.program[address] = value
proc get(cp: Computer, address: int): int =
cp.program[address]
proc add(cp: Computer, param1, param2, param3: int): void =
cp.set(param3, (cp.get(param1) + cp.get(param2)))
proc mul(cp: Computer, param1, param2, param3: int): void =
cp.set(param3, (cp.get(param1) * cp.get(param2)))
proc newComputer*(sourceFile: string): Computer =
var file = readFile("input.txt");
file.stripLineEnd
let source = map(split(file, ','), parseInt)
result = Computer(source: source, ic: 0)
proc reset*(cp: Computer, input: Input): void =
## Reset instruction pointer, program code and input values
cp.program = cp.source
cp.ic = 0
cp.set(1, input.noun)
cp.set(2, input.verb)
proc process(cp: Computer): void =
let opCode = cp.get(cp.ic)
if opCode == 99: # End Execution
raise newException(StopExecution, "Program ended")
if opCode == 1: # Addition
cp.add(cp.get(cp.ic+1), cp.get(cp.ic+2), cp.get(cp.ic+3))
if opCode == 2: # Multiplication
cp.mul(cp.get(cp.ic+1), cp.get(cp.ic+2), cp.get(cp.ic+3))
cp.ic += 4
proc run*(cp: Computer): int =
## Runs the program loaded in memory until complete
try:
while true:
cp.process
except StopExecution:
return cp.get(0)
return -1 # Something went wrong
proc findInputFor*(cp: Computer, target: int): Input =
## Finds fitting inputs to produce the desired output
## Stops at the first match
for noun in 0 .. 99:
for verb in 0 .. 99:
let input = Input(noun: noun, verb: verb)
cp.reset(input)
var output = cp.run
if output == target:
return input