63 lines
1.9 KiB
Scala
63 lines
1.9 KiB
Scala
package aoc.y2019
|
|
|
|
import aoc.Day
|
|
import cats.data.State
|
|
|
|
object Day02 extends Day {
|
|
|
|
case class Machine(memory: List[Int], pointer: Int)
|
|
type MachineState = State[Machine, Boolean]
|
|
|
|
val ops: Map[Int, (Int, Int) => Int] = Map(
|
|
1 -> (_ + _),
|
|
2 -> (_ * _)
|
|
)
|
|
|
|
def initialReplacement(noun: Int, verb: Int): MachineState = State {
|
|
case Machine(memory, 0) =>
|
|
(Machine(memory.updated(1, noun).updated(2, verb), 0), false)
|
|
}
|
|
|
|
val step: MachineState = State {
|
|
case Machine(memory, pointer) =>
|
|
memory(pointer) match {
|
|
case 99 => (Machine(memory, pointer), true)
|
|
case opcode =>
|
|
val inputAAddress = memory(pointer + 1)
|
|
val inputBAddress = memory(pointer + 2)
|
|
val valueA = memory(inputAAddress)
|
|
val valueB = memory(inputBAddress)
|
|
val outputAddress = memory(pointer + 3)
|
|
val op = ops(opcode)
|
|
(Machine(memory.updated(outputAddress, op(valueA, valueB)), pointer + 4), false)
|
|
}
|
|
}
|
|
|
|
def runMachine(memory: List[Int], noun: Int, verb: Int): Int = {
|
|
val initialState = Machine(memory, 0)
|
|
val initialReplacementState = initialReplacement(noun, verb).run(initialState).value
|
|
lazy val states: LazyList[(Machine, Boolean)] =
|
|
initialReplacementState #:: states.map {
|
|
case (currentState, _) => step.run(currentState).value
|
|
}
|
|
val (lastState, _) = states.takeWhile(!_._2).last
|
|
lastState.memory.head
|
|
}
|
|
|
|
override def part1(input: String): String = {
|
|
val memory = input.split(",").map(_.toInt).toList
|
|
runMachine(memory, 12, 2).toString
|
|
}
|
|
|
|
override def part2(input: String): String = {
|
|
val memory = input.split(",").map(_.toInt).toList
|
|
val magic = 19690720
|
|
val solutions = for {
|
|
noun <- 0 to 99
|
|
verb <- 0 to 99 if runMachine(memory, noun, verb) == magic
|
|
} yield noun * 100 + verb
|
|
solutions.head.toString
|
|
}
|
|
|
|
}
|