This is my catch-up post for Advent of Code 2019 day 1 and day 2. Both days involved tail recursive functions, which is a whole lot of fun to write! The first day required recursive fuel calculation logic. When adding fuel to a rocket, we need to ensure that we add fuel when a significant amount of fuel is added. Because fuel itself has weight, and has to be propelled.
Day 1: parts 1 and 2
class Puzzle1 { def calculateFuel(input: Int): Int = { val first = Math.floor(input.toFloat / 3).toInt first - 2 } //recursive fuel calculation function! @tailrec final def recursiveFuel(acc: Int = 0, input: Int): Int = { val change = Math.floor(input.toFloat / 3).toInt if (change val result = acc(in1) + acc(in2) process(acc.updated(dest, result), opCount + 1) case MULT :: in1 :: in2 :: dest :: xs => val result = acc(in1) * acc(in2) process(acc.updated(dest, result), opCount + 1) case END :: xs => acc case _ => throw new Exception("Unknown opcode") } } process(ops, 0) } }
I remembered my pattern matching logic from scala! Pattern Matching allowed me to select out the Operation, and then the Parameters to that operation, trivially.
Opcodes (like
1
,2
, or99
) mark the beginning of an instruction. The values used immediately after an opcode, if any, are called the instruction’s parameters. For example, in the instruction1,2,3,4
,1
is the opcode;2
,3
, and4
are the parameters. The instruction99
contains only an opcode and has no parameters.https://adventofcode.com/2019/day/2 – part 2
Using the list builtin method .updated
I can create a new list, changing out that location in the list. Perfect for the IntCode operations. I just have to keep track of how many operations I have done, so I can move along the list and execute the next operation in order.
This proved to be an excellent solution to both part 1 and part 2 of the Advent of Code Day 2 puzzle. For part 2, I pretty much just did the dumbest thing possible, and used tons of CPU power to brute force out the solution. I didn’t even exit the loop early, so I wasted all the CPU cycles.
println("PART TWO:") (0 to 99).inclusive.foreach( noun => { (0 to 99).inclusive.foreach(verb => { val attempt = app.updated(1, noun).updated(2, verb) val result = new IntCode(attempt).execute() if(result.head == 19690720) { println(s"Noun = $noun verb = $verb") println(s"ANSWER: ${100 * noun + verb}") } }) })