 # Advent of Code 2019 Solution Megathread - Day 2: 1202 Program Alarm Jon Bristow Updated on ・2 min read

Day 2 is in the books! And surprisingly, we're into pseudo-interpreter territory already!

### Day 2 - The Problem

We need to slingshot ourselves around the moon, but the computer that calculates our trajectory has sadly exploded. Given our current data and the specs for that machine, we need to build ourselves a new IntCode interpreter.

It's surprising to me to see a psuedo-assembly converter so early in the Advent of Code, but this one turned out to be vaguely straightforward. Most of my personal problems stemmed from input validation. (If you're a newbie, let me assure you that input validation is almost always something that will slow you down. This goes triply for anyone learning a new language!)

Part 2 luckily doesn't require a whole lot of extra logic, but it has a bit of "optimization" and "compartmentalization" to keep tabs on.

### Ongoing Meta

If you were part of Ryan Palo's leaderboard last year, you're still a member of that!

I'll edit in any leaderboards that people want to post, along with any description for the kinds of people you want to have on it. (My leaderboard is being used as my office's leaderboard.) And if I get something wrong, please call me out or message me and I’ll fix it ASAP.

There's no limit to the number of leaderboards you can join, so there's no problem belonging to a "Beginner" and a language specific one if you want.

#### Neat Statistics

I'm planning on adding some statistics, but other than "what languages did we see yesterday" does anyone have any ideas?

### Discussion  Ali Spittel

I struggled with reading comprehension tonight 🤦🏼‍♀️

``````def calculate(num1, num2, nums):
nums = num1
nums = num2
idx = 0
while nums[idx] != 99:
num = nums[idx]
val1 = nums[nums[idx + 1]]
val2 = nums[nums[idx + 2]]
idx3 = nums[idx + 3]
if num == 1:
nums[idx3] = val1 + val2
elif num == 2:
nums[idx3] = val1 * val2
idx += 4
return nums

with open("input.txt") as _file:
for line in _file:
input_values = [int(num) for num in line.split(",")]
# part 1
print(calculate(12, 2, input_values[:]))

# part 2
GOAL = 19690720
for i in range(100):
for j in range(100):
if calculate(i, j, input_values[:]) == GOAL:
print(100 * i + j)
break
`````` Jojo Narte

My solution in JS.

``````const operations = {
1: (inputArray, pos1, pos2, resultPos) => inputArray[inputArray[resultPos]] = inputArray[inputArray[pos1]] + inputArray[inputArray[pos2]],
2: (inputArray, pos1, pos2, resultPos) => inputArray[inputArray[resultPos]] = inputArray[inputArray[pos1]] * inputArray[inputArray[pos2]],
};

const part1Solution = (inputArray, index = 0) => {
const operation = inputArray[index];
if (operation === 99) {
return inputArray;
}

if (operation === 1 || operation === 2) {
operations[operation](inputArray, index + 1, index + 2, index + 3)
} else {
throw new Error('Something went wrong!');
}

return part1Solution(inputArray, index + 4);
};

const part2Solution = (inputArray, targetValue) => {
for (let i = 0; i <= 99; i ++) {
for (let j = 0; j <= 99; j++) {
const newArr = [...inputArray];
newArr = i;
newArr = j;
const currentResult = part1Solution(newArr);
console.log('CURRENT VALUE', currentResult);

if (currentResult === targetValue) {
return 100 * i + j;
}
}
}

};
`````` Neil Gall

In past Advent of Codes I've belligerently tried to write these machine simulators in Haskell or pure functional Kotlin or something else completely inappropriate. Maybe it's a sign of maturity that this year I've done it in C.

It's been a while since I've written C. The purity and simplicity is refreshing.

``````#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef unsigned int opcode;

struct program {
size_t size;
opcode base[];
};

size_t program_size(size_t n) {
return sizeof(size_t) + sizeof(opcode) * n;
}

size_t size = 100;
struct program *program = (struct program *)malloc(program_size(size));
size_t pos = 0;
opcode cur = 0;
FILE *f = fopen(filename, "rt");
for (;;) {
int c = fgetc(f);
if (c == EOF || c == ',') {
if (pos == size) {
size *= 2;
program = (struct program *)realloc(program, program_size(size));
}
program->base[pos++] = cur;
cur = 0;
} else if ('0' <= c && c <= '9') {
cur = (cur * 10) + (c - '0');
}
if (c == EOF) break;
}
fclose(f);
program->size = pos;
return program;
}

struct program *copy_program(struct program *program) {
size_t size = program_size(program->size);
struct program *copy = (struct program *)malloc(size);
memcpy(copy, program, size);
return copy;
}

int read_program(struct program *program, size_t pos, opcode *x) {
if (pos >= program->size) {
return 1;
}
*x = program->base[pos];
return 0;
}

int write_program(struct program *program, size_t pos, opcode value) {
if (pos >= program->size) {
return 1;
}
program->base[pos] = value;
return 0;
}

void print_program(struct program *program) {
printf("%u", program->base);
for (int i = 1; i < program->size; ++i) {
printf(",%u", program->base[i]);
}
printf("\n");
}

int run_program(struct program *program, int debug) {
size_t pc = 0;
opcode i;
while (read_program(program, pc, &i) == 0 && i != 99) {
opcode x, y, z;
if (read_program(program, pc+1, &x) != 0) return 1;
if (read_program(program, x,    &x) != 0) return 1;
if (read_program(program, pc+2, &y) != 0) return 1;
if (read_program(program, y,    &y) != 0) return 1;
if (read_program(program, pc+3, &z) != 0) return 1;
if (debug) printf("pc=%u i=%u x=%u y=%u z=%u\n", pc, i, x, y, z);
switch (i) {
case 1:
if (write_program(program, z, x + y) != 0) return 1;
break;
case 2:
if (write_program(program, z, x * y) != 0) return 1;
break;
default:
return 1;
}
if (debug) print_program(program);
pc += 4;
}
return 0;
}

void modify_program(struct program *program) {
program->base = 12;
program->base = 2;
}

void part1(struct program *original) {
printf("Part 1\n");
struct program *program = copy_program(original);
modify_program(program);
run_program(program, 0);
print_program(program);
free(program);
}

void part2(struct program *original) {
opcode noun = 0;
opcode verb = 0;
int result = 0;
while (noun < 100 && verb < 100) {
struct program *program = copy_program(original);
write_program(program, 1, noun);
write_program(program, 2, verb);
int result = run_program(program, 0) == 0 && program->base == 19690720;
free(program);

if (result) {
break;
}

if (++noun > 99) {
noun = 0;
++verb;
}
}
printf("Part 2\nnoun = %u\nverb = %u\nresult = %u\n", noun, verb, 100*noun+verb);
}

static struct program test_program = {
.size = 12,
.base = { 1,9,10,3,2,3,11,0,99,30,40,50 }
};

int main(int argc, char **argv) {
struct program *program = (argc < 2) ? load_program("input.txt") : &test_program;
part1(program);
part2(program);

if (program != &test_program) {
free(program);
}
return 0;
}
`````` Supriya Srivatsa

Some Kotlin code :)

``````fun main() {
val input = readDayInputAsString(2).split(",").map { it.toInt() }
val noun = 12
val verb = 2

println(solvePart1(input, noun, verb))  //5434663
println(solvePart2(input, noun, verb))  //4559
}

private fun solvePart1(programInput: List<Int>, noun: Int, verb: Int) : Int {
val input = programInput.toMutableList()
input = noun
input = verb
for(i in input.indices step 4) {
when(input[i]) {
99 -> return input
1 -> input[input[i+3]] = input[input[i+1]] + input[input[i+2]]
2 -> input[input[i+3]] = input[input[i+1]] * input[input[i+2]]
}
}
return input
}

private fun solvePart2(programInput: List<Int>, noun: Int, verb: Int) : Int {
for(i in 0..99) {
for(j in 0..99) {
if(solvePart1(programInput, i, j) == 19690720)
return 100 * i + j
}
}
return 100 * noun + verb
}
`````` Paweł Świątkowski

I can't believe no one has posted a solution in Janet yet! Oh wait, no, I totally believe it. It was also my first attempt in this language. I've been looking at it for some time already but only today I decided to give it a shot. It basically feels like a imperativ-ish LISP.

``````(def input "1,0,0,the rest of your input...")

(defn run-prog [noun verb]
(def codes (map (fn [x] (scan-number x)) (string/split "," input)))
(put codes 1 noun)
(put codes 2 verb)

(var curpos 0)
(var curinstr (get codes curpos))
(while (not (= curinstr 99))
(def elem1 (get codes (+ curpos 1)))
(def elem2 (get codes (+ curpos 2)))
(def elem3 (get codes (+ curpos 3)))

(if (= curinstr 1)
(put codes elem3 (+ (get codes elem1) (get codes elem2))))

(if (= curinstr 2)
(put codes elem3 (* (get codes elem1) (get codes elem2))))

(set curpos (+ curpos 4))
(set curinstr (get codes curpos)))
(get codes 0))

(print (string/format "%d" (run-prog 12 2)))

(loop [noun :range [0 99]]
(loop [verb :range [0 99]]
(def res (run-prog noun verb))
(if (= res 19690720)
(print (string/format "%d" (+ (* 100 noun) verb))))))
`````` Linda Thompson

JavaScript checking in! I think it'll be interesting, seeing how we re-use this in future challenges. It did take me reading the end of part 2 a number of times before I understood what I was looking for! :)

I also feel like there should be a better way to process the second part...I saw folks on the subreddit talking about just changing the noun value until it's as high as can be while still below the desired output, then changing the verb, but it seems maybe there's unforeseen issues with that? I don't know, everyone I've seen so far is just nesting for loops so I'm not that worried about it. :)

``````// copy of initial input, so we can reset properly
let inputCopy = [...input];

// noun - input for address 1; verb - input for address 2
let noun = 12;
let verb = 2;

// for part 2 - desired output to match - output is final value at address 0 when program is done
const desiredOutput = 19690720;
// opcode 1 - get values at position 1&2 right after code, add together, store in position 3
// opcode 2 - get values at position 1&2 right after code, multiply, store in position 3
// opcode 99 - stop program
function intCode (op, a, b, c) {
let valA = inputCopy[a];
let valB = inputCopy[b];

if (op === 1) {
inputCopy[c] = valA + valB;
} else if (op === 2) {
inputCopy[c] = valA * valB;
}
}

// run through memory input, following instructions until 99 is hit
function runProgram() {
for (let i = 0; i < inputCopy.length; i += 4) {
if (inputCopy[i] === 99) {
break;
}
intCode(inputCopy[i], inputCopy[i+1], inputCopy[i+2], inputCopy[i+3]);
}
}

// for part 1 - insert noun & verb provided
inputCopy = noun;
inputCopy = verb;

runProgram();
console.log(`Part 1: position 0 value is \${inputCopy}`);

// part 2 - test different values for noun & verb, insert into memory, run program - when desired output is matched, log noun & verb used & end cycle

for (let n = 0; n < 100; n++) {
noun = n;
let found = false;
for (let v = 0; v < 100; v++) {
verb = v;

// reset copy to initial input, then replace noun & verb
inputCopy = [...input];
inputCopy = noun;
inputCopy = verb;

runProgram();
let currentOutput = inputCopy;

if (currentOutput === desiredOutput) {
found = true;
break;
}
}
if (found) {
break;
}
}

console.log(`desired noun and verb are \${noun} & \${verb}; output value is \${inputCopy}`);
console.log(`Part 2 - computed value is \${100 * noun + verb}`);
`````` Jakub Charvat

Here's my Python solution - nothing special or well optimised, but it works:

``````def puzzle_one():
with open('inputs/day_2.txt') as file:
input = list(map(lambda a: int(a), file.read().split(',')))

opcode, index = int(input), 0
while opcode != 99:
if opcode == 1:
sum = input[input[index + 1]] + input[input[index + 2]]
input[input[index + 3]] = sum
elif opcode == 2:
product = input[input[index + 1]] * input[input[index + 2]]
input[input[index + 3]] = product
elif opcode != 99:
print('Something went wrong')

index += 4
opcode = input[index]

print(f'Puzzle 1 - {input}')

def puzzle_two():

goal = 19690720

with open('inputs/day_2.txt') as file:
input = list(map(lambda a: int(a), file.read().split(',')))

found = False
for noun in range(100):
for verb in range(100):
memory = input[:]
memory = noun
memory = verb

opcode, index = int(input), 0
while opcode != 99:
if opcode == 1:
sum = memory[memory[index + 1]] + memory[memory[index + 2]]
memory[memory[index + 3]] = sum
elif opcode == 2:
product = memory[memory[index + 1]] * memory[memory[index + 2]]
memory[memory[index + 3]] = product
elif opcode != 99:
print('Something went wrong')

index += 4
opcode = memory[index]

output = memory

if output == goal:
final_noun = noun
final_verb = verb
found = True
break
if found == True:
break
print(f'Puzzle 2 - {100 * final_noun + final_verb}')

puzzle_one()
puzzle_two()
`````` Matt Ellen

In the browser!

``````function process(one, two)
{
let pretext = document.getElementsByTagName('pre').innerHTML;
let instructions = pretext.split(',').map(i => parseInt(i, 10));
instructions = one;
instructions = two;
for(let i = 0; i < instructions.length; i += 4)
{
let inst = instructions[i];
if(inst == 99)
{
break;
}

let ai = instructions[i+1];
let bi = instructions[i+2];

if(inst == 1)
{
}
else if(inst == 2)
{
}
}

return instructions;
}

/* part 2 */
let done = false;
for(let a = 0; a < 100 && !done; a++)
{
for(let b = 0; b < 100; b++)
{
let n = process(a, b);
if(n == 19690720)
{
console.log(a, b)
done = true;
break;
}
}
}
`````` Ryan Palo

Here's my Rust code. I was lucky that I caught that bit at the very end of the instructions about setting the initial values. Otherwise I probably would have spiraled trying to figure out why my answer to Part 1 was wrong.

Now I just need to refactor this out to make it easy to extend for future days!

``````/// Day 2: 1202 Program Alarm
///
/// Create an "Intcode" computer that can calculate a gravity slingshot

use std::fs;

/// Parses the input.  Expects a single line of integers separated by
/// commas
fn parse_input() -> Vec<usize> {
let cleaned = text.trim();
cleaned.split(",").map( |c| c.parse().unwrap()).collect()
}

/// An Intcode Interpreter is a simple virtual machine that uses opcodes
/// to modify its internal memory
struct IntcodeInterpreter {
ints: Vec<usize>,
ip: usize,
}

impl IntcodeInterpreter {
pub fn new(ints: Vec<usize>) -> Self {
Self { ints, ip: 0}
}

/// Sets a memory address to a value
pub fn set(&mut self, position: usize, value: usize) {
self.ints[position] = value;
}

pub fn get(&self, position: usize) -> usize {
self.ints[position]
}

/// Runs the program in memory until the stopcode (99) is reached
/// (To be refactored and generalized)
pub fn run(&mut self) {
while self.ints[self.ip] != 99 {
let opcode = self.ints[self.ip];
let in1 = self.ints[self.ip + 1];
let in2 = self.ints[self.ip + 2];
let out = self.ints[self.ip + 3];

if opcode == 1 {
self.ints[out] = self.ints[in1] + self.ints[in2];
} else if opcode == 2 {
self.ints[out] = self.ints[in1] * self.ints[in2];
} else {
panic!("Unrecognized opcode {}!", opcode);
}
self.ip = (self.ip + 4) % self.ints.len();
}
}
}

/// Given a desired output, hunts through the possible values of position
/// 1 and 2 (termed "noun" and "verb") by brute force until the output
/// is found.
fn find_output(output: usize, ints: Vec<usize>) -> (usize, usize) {
for noun in 0..=99 {
for verb in 0..=99 {
let mut interpreter = IntcodeInterpreter::new(ints.clone());
interpreter.set(1, noun);
interpreter.set(2, verb);
interpreter.run();
if interpreter.get(0) == output {
return (noun, verb);
}
}
}

panic!("Couldn't find output!");
}

pub fn run() {
let ints = parse_input();

println!("Part 1:");
let mut interpreter = IntcodeInterpreter::new(ints.clone());
interpreter.set(1, 12);
interpreter.set(2, 2);
interpreter.run();
println!("After running, position 0 is: {}", interpreter.get(0));

println!("Part 2:");
let (noun, verb) = find_output(19690720, ints.clone());
println!("Noun: {}, Verb: {}", noun, verb);
println!("Secret code is: {}{}", noun, verb);

}
`````` Yordi Verkroost

Pretty rough assignment on day two already, but got it working in the end! I've solved it in Elixir. Here's my solution for part two:

``````defmodule Aoc19.Day2b do
@moduledoc false

alias Aoc19.Utils.Common

@multiply 2
@halt 99

def start(input_location) do
opcode =
input_location
|> verify()

try do
for i <- 1..100 do
for j <- 1..100 do
_ =
case result(opcode, i, j) do
19_690_720 ->
throw(100 * i + j)

_ ->
nil
end
end
end
catch
result -> result
end
end

defp result(opcode, noun, verb) do
opcode = replace(opcode, noun, verb)

opcode
|> intcode(opcode, 0)
|> Enum.at(0)
end

defp verify([x | _] = opcode) when x in @opcode, do: opcode

defp replace(opcode, noun, verb) do
opcode
|> List.update_at(1, fn _ -> noun end)
|> List.update_at(2, fn _ -> verb end)
end

defp intcode([@halt | _], opcode, _), do: opcode

defp intcode([@add, int1, int2, result | _], opcode, index) do
opcode =
List.update_at(opcode, result, fn _ ->
Enum.at(opcode, int1) + Enum.at(opcode, int2)
end)

index = index + 4
{_, rest} = Enum.split(opcode, index)

intcode(rest, opcode, index)
end

defp intcode([@multiply, int1, int2, result | _], opcode, index) do
opcode =
List.update_at(opcode, result, fn _ ->
Enum.at(opcode, int1) * Enum.at(opcode, int2)
end)

index = index + 4
{_, rest} = Enum.split(opcode, index)

intcode(rest, opcode, index)
end
end
``````

Check out part one here Rizwan

It took more time than I expected but finally done with it. I actually started Day 1 today as well.

Here is my solution in swift. Incase anyone would like followup code can be found here in Github

``````/// --- Day 2: 1202 Program Alarm ---
func computeIntCode(_ input: [Int]) -> Int {
var numbers = input

func add(_ aPosition: Int, _ bPosistion: Int) -> Int {
return numbers[aPosition] + numbers[bPosistion]
}

func multiply(_ aPosition: Int, _ bPosistion: Int) -> Int {
return numbers[aPosition] * numbers[bPosistion]
}

func compute(integers:[Int]) {
let opcode = integers
switch opcode {
case 1:
numbers[integers] = result
//print(numbers)
break
case 2:
let result = multiply(integers, integers)
numbers[integers] = result
//print(numbers)
break
case 99:
break
default:
break
}
}

var index = 0
while true {
let number = numbers[index]
if number == 1 || number == 2 {
compute(integers: Array(numbers[index...index+4]))
index = index + 4
}
else if number == 99 {
break
}
}
//print(numbers)
return numbers
}

func computeIntCode(_ input:[Int], _ noun: Int, _ verb: Int) -> Int {
var input = input
input = noun
input = verb
return computeIntCode(input)
}

let input = """
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,2,9,19,23,1,9,23,27,2,27,9,31,1,31,5,35,2,35,9,39,1,39,10,43,2,43,13,47,1,47,6,51,2,51,10,55,1,9,55,59,2,6,59,63,1,63,6,67,1,67,10,71,1,71,10,75,2,9,75,79,1,5,79,83,2,9,83,87,1,87,9,91,2,91,13,95,1,95,9,99,1,99,6,103,2,103,6,107,1,107,5,111,1,13,111,115,2,115,6,119,1,119,5,123,1,2,123,127,1,6,127,0,99,2,14,0,0
"""
let numbers = input.components(separatedBy: ",").compactMap{Int(\$0)}

func partOne() {
dump(computeIntCode(numbers,12,2))
}

func partTwo() {
for i in 0..<99 {
for j in 0..<99 {
if computeIntCode(numbers,i,j) == 19690720 {
print("noun: \(i) \n verb: \(j)")
dump(100 * i + j)
return
}
}
}
}

partOne()
partTwo()
`````` Christopher Kruse

Back again with more Clojure.

My favorite part of this is how the actions get selected. the `get-action` function actually returns the function used for handling the inputs (where 99 returns a function that, regardless of input, returns "stop"). Then, that function is used with the `apply` function inside `calculate` to actually pass the arguments to that function.

I'm sure there should be a better way of handling the brute force handling of part 2, but for now, it's just a poor man's nested for loop implemented using atoms.

``````(ns aoc2019.day2
(:require [clojure.string :as st]))

(defn get-action
"Selects an action from the available opcodes"
[action]
(condp = action
1 +
2 *
99 (constantly "stop")))

(defn parse-input
"Converts input into atom holding instruction integers."
[input]
(map #(Integer/parseInt %) (st/split (st/trim-newline input) #",")))

[instructions noun verb]
(-> instructions
(assoc 1 noun)
(assoc 2 verb)))

(defn calculate
[input noun verb]
(loop [instructions (initial-adjustments (vec (parse-input input)) noun verb)
cursor 0]
(let [[action pos1 pos2 result-pos] (take 4 (drop cursor instructions))
result (apply (get-action action) [(get instructions pos1) (get instructions pos2)])]
(if (= result "stop")
(first instructions)
(recur (assoc instructions result-pos result) (+ 4 cursor))))))

(defn p2019-02-part1
[input]
(calculate input 12 2))

(defn p2019-02-part2
"Using the calculator from part 1, determine the proper inputs for our expected value."
[input]
(let [expected-result 19690720
noun (atom 0)
verb (atom 0)]
(while (not= expected-result (calculate input @noun @verb))
(swap! verb inc)
(if (= @verb 100)
(do
(swap! noun inc)
(reset! verb 0))))
(+ @verb (* 100 @noun))))

(defn run
"Runs the Day 2 solutions."
[]
(let [input (slurp "inputs/2019-02-input")]
(println (str "Part 1: " (p2019-02-part1 input)))
(println (str "Part 2: " (p2019-02-part2 input)))))
`````` Shaurya Shubham

My solution in Rust

``````fn part_a(mut input: Vec<u32>) -> u32 {
input = 12;
input = 2;

let mut i: usize = 0;
while i < input.len() {
if i % 4 == 0 {
let opcode = input[i];
if opcode == 99 {
break;
}
let index_1 = input[i + 1] as usize;
let index_2 = input[i + 2] as usize;
let index_3 = input[i + 3] as usize;

if opcode == 1 {
input[index_3] = input[index_1] + input[index_2];
} else if opcode == 2 {
input[index_3] = input[index_1] * input[index_2];
}
}
i = i + 1;
}

input
}

fn part_b(input: Vec<u32>) -> u32 {
let mut i = 0;
let mut j = 0;
while i < 100 {
let mut input = input.clone();

if exec_intcode_program(input, i, j) == 19690720 {
return 100 * i + j;
break;
}

if j == 99 {
i = i + 1;
j = 0;
}
j = j + 1;
}

0
}
let mut input = input.clone();

let mut i: usize = 0;
while i < input.len() {
if i % 4 == 0 {
let opcode = input[i];
if opcode == 99 {
break;
}
let index_1 = input[i + 1] as usize;
let index_2 = input[i + 2] as usize;
let index_3 = input[i + 3] as usize;

if opcode == 1 {
input[index_3] = input[index_1] + input[index_2];
} else if opcode == 2 {
input[index_3] = input[index_1] * input[index_2];
}
}
i = i + 1;
}

input
}
`````` Jon Bristow

My kotlin solution:

``````object Day02 {

private const val FILENAME = "src/main/resources/day02.txt"

fun handleOpcode(offset: Int, intList: Either<Array<Int>, Array<Int>>): Either<Array<Int>, Array<Int>> =
intList.flatMap {
val opcodeChunk = it.drop(offset).take(4)

when (opcodeChunk) {
1 -> {
it[opcodeChunk] = it[opcodeChunk] + it[opcodeChunk]
it.right()
}
2 -> {
it[opcodeChunk] = it[opcodeChunk] * it[opcodeChunk]
it.right()
}
99 -> it.left()
else -> throw Error("Unknown opcode: \${opcodeChunk}")
}
}

.trim()
.prepInput().let {
it = 12
it = 2
it
}.operate()
.toString()

fun part2(): String {
.trim().prepInput()

return (0..99).fold(Unit.right() as Either<Pair<Int, Int>, Unit>) { foundSoFar, noun ->
foundSoFar.flatMap {
val found = (0..99).find { verb ->
val inputCopy = input.copyOf()
inputCopy = noun
inputCopy = verb
inputCopy.operate() == 19690720
}
if (found == null) {
foundSoFar
} else {
(noun to found).left()
}
}
}.fold({ (noun, verb) ->
"%02d%02d".format(noun, verb)
}, { throw Error("No match found.") })
}
}

fun String.prepInput() = split(",").map { it.toInt() }.toTypedArray()

fun Array<Int>.operate() =
this.let {
(0..this.size / 4).map { it * 4 }
.fold(this.right() as Either<Array<Int>, Array<Int>>) { intArr, offset ->
handleOpcode(offset, intArr)
}.fold({ it }, { it })
}

fun main() {
println("Part 1: \${Day02.part1()}")
println("Part 2: \${Day02.part2()}")
}

`````` Noak Palander

A bit late to the party, got my c++17 code working however

``````#include <fstream>
#include <vector>
#include <string>
#include <optional>
#include <optional>
#include <iostream>
#include <cmath>
#include <sstream>

std::optional<std::vector<unsigned int>> ReadFile(const std::string& filename) {

std::string data;

std::stringstream ss(data);

std::vector<unsigned int> out;
for (unsigned int val; ss >> val;) {
out.emplace_back(val);
if (ss.peek() == ',')
ss.ignore();
}

return out;
}

return {};
}

unsigned int Calculate(unsigned int first, unsigned int second, std::vector<unsigned int> data) {
// Set initial values
data = first;
data = second;

for (unsigned int i = 0; i < data.size(); i += 4) {
const unsigned int FIRST = data[i + 1];
const unsigned int SECOND = data[i + 2];
const unsigned int LOCATION = data[i + 3];

switch (data[i]) {
case 1:
data[LOCATION] = data[FIRST] + data[SECOND];
break;

// Multiplication
case 2:
data[LOCATION] = data[FIRST] * data[SECOND];
break;

// Terminate
case 99:
return data;
break;

default:
break;
}
}

return data;
}

int main() {
if (auto data = ReadFile("puzzle_input"); data.has_value()) {
/* Part one */
unsigned int ans1 = Calculate(12, 2, data.value());
std::cout << "The answer to part_1 is " << ans1 << "\n";

/* Part 2 */
// Reset data set

const unsigned int GOAL = 19690720;

// 100*100 is enough iterations
for (unsigned int noun = 0; noun < 100; noun++)
for (unsigned int verb = 0; verb < 100; verb++)
if (Calculate(noun, verb, data.value()) == GOAL)
std::cout << "\nThe answer to part_2 is " << 100 * noun + verb << "\n";
}
else
std::cerr << "Failed to read puzzle_input!\n";

return 0;
}
``````  