Day 7 part 2
This commit is contained in:
parent
0664894ef2
commit
37bc98fafb
4 changed files with 50 additions and 11 deletions
|
@ -13,7 +13,7 @@ object Day02 extends Day {
|
|||
val initialState = Intcode.Machine(memory)
|
||||
val runMachine = for {
|
||||
_ <- initialReplacement(noun, verb)
|
||||
ran <- Intcode.run
|
||||
ran <- Intcode.run()
|
||||
} yield ran
|
||||
val endState = runMachine.runS(initialState).value
|
||||
endState.memory(0)
|
||||
|
|
|
@ -13,7 +13,7 @@ object Day05 extends Day {
|
|||
val machineInput = diagnosticNumber
|
||||
val runMachine: Intcode.Operation = for {
|
||||
_ <- Intcode.input(machineInput)
|
||||
ran <- Intcode.run
|
||||
ran <- Intcode.run()
|
||||
} yield ran
|
||||
val endState = runMachine.runS(initialState).value
|
||||
endState.output.last
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package aoc.y2019
|
||||
|
||||
import aoc.Day
|
||||
|
||||
import cats._
|
||||
import cats.implicits._
|
||||
import scala.annotation.tailrec
|
||||
|
||||
object Day07 extends Day {
|
||||
|
||||
@tailrec def runAmplifiers(machine: Intcode.Machine, order: IndexedSeq[Int], input: Int = 0): Int = {
|
||||
@tailrec def runAmplifiers(machine: Intcode.Machine, order: Seq[Int], input: Int = 0): Int = {
|
||||
if(order.isEmpty) {
|
||||
input
|
||||
} else {
|
||||
|
@ -15,7 +16,7 @@ object Day07 extends Day {
|
|||
val runAmplifier = for {
|
||||
_ <- Intcode.input(firstInput)
|
||||
_ <- Intcode.input(secondInput)
|
||||
ran <- Intcode.run
|
||||
ran <- Intcode.run()
|
||||
} yield ran
|
||||
val output = runAmplifier.runS(machine).value.output.head
|
||||
runAmplifiers(machine, order.tail, output)
|
||||
|
@ -29,5 +30,39 @@ object Day07 extends Day {
|
|||
maximumSignal.toString
|
||||
}
|
||||
|
||||
override def part2(input: String): String = ???
|
||||
def loopAmplifiers(base: Intcode.Machine, initialInputs: Seq[Int]): Int = {
|
||||
val numAmplifiers = initialInputs.size
|
||||
val initialMachines = Vector.fill(numAmplifiers)(base).zip(initialInputs).map {
|
||||
case (machine, phase) => machine.copy(input = machine.input :+ phase)
|
||||
}
|
||||
val haltCondition = for {
|
||||
waitingForInput <- Intcode.watingForInput
|
||||
isHalted <- Intcode.isHalted
|
||||
} yield waitingForInput || isHalted
|
||||
val runToNextMachine = Intcode.run(haltCondition = haltCondition)
|
||||
@tailrec def go(index: Int, machines: Vector[Intcode.Machine], lastOutput: Int = 0): Vector[Intcode.Machine] = {
|
||||
if(machines.traverse(machine => Intcode.isHalted.runA(machine)).value.forall(identity)) machines
|
||||
else {
|
||||
val thisMachine = machines(index)
|
||||
val inputAndRun = for {
|
||||
inputLastOutput <- Intcode.input(lastOutput)
|
||||
runAsFarAsPossible<- runToNextMachine
|
||||
} yield runAsFarAsPossible
|
||||
val ranMachine = inputAndRun.runS(thisMachine).value
|
||||
val nextOutput = ranMachine.output.last
|
||||
val nextIndex = (index + 1) % machines.size
|
||||
val nextMachines = machines.updated(index, ranMachine)
|
||||
go(nextIndex, nextMachines, nextOutput)
|
||||
}
|
||||
}
|
||||
go(0, initialMachines).last.output.last
|
||||
}
|
||||
|
||||
override def part2(input: String): String = {
|
||||
val memory = input.split(",").toVector.map(_.toInt)
|
||||
val initialState = Intcode.Machine(memory)
|
||||
val maximumSignal = (5 to 9).permutations.map(loopAmplifiers(initialState, _)).max
|
||||
maximumSignal.toString
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ object Intcode {
|
|||
8 -> Instruction.equals,
|
||||
)
|
||||
|
||||
val parse: State[Machine, (Instruction, LazyList[Boolean])] = State.inspect {
|
||||
def parse(instructions: Map[Int, Instruction] = instructions): State[Machine, (Instruction, LazyList[Boolean])] = State.inspect {
|
||||
machine: Machine =>
|
||||
val instructionAndFlags = machine.memory(machine.pc)
|
||||
val instruction: Instruction = instructions(instructionAndFlags % 100)
|
||||
|
@ -32,12 +32,13 @@ object Intcode {
|
|||
}
|
||||
(instruction, flags)
|
||||
}
|
||||
val step: Operation = for {
|
||||
(instruction, flags) <- parse
|
||||
def step(instructions: Map[Int, Instruction] = instructions): Operation = for {
|
||||
(instruction, flags) <- parse(instructions)
|
||||
_ <- advance(1)
|
||||
result <- instruction.run(flags)
|
||||
} yield result
|
||||
val run: Operation = step.untilM[Vector](State.inspect(machine => machine.memory(machine.pc) % 100 == 99)).map(_.last)
|
||||
def run(instructions: Map[Int, Instruction] = instructions, haltCondition: State[Machine, Boolean] = isHalted): Operation =
|
||||
step(instructions).untilM[Vector](haltCondition).map(_.last)
|
||||
|
||||
val noop: Operation = State.pure(())
|
||||
|
||||
|
@ -62,6 +63,9 @@ object Intcode {
|
|||
machine.copy(output = machine.output :+ value)
|
||||
}
|
||||
|
||||
val isHalted: State[Machine, Boolean] = State.inspect(machine => machine.memory(machine.pc) % 100 == 99)
|
||||
val watingForInput: State[Machine, Boolean] = State.inspect(machine => machine.memory(machine.pc) % 100 == 3 && machine.input.isEmpty)
|
||||
|
||||
object Instruction {
|
||||
|
||||
def trans(operandCount: Int, operation: Kleisli[State[Machine, *], Vector[Int], Unit]): Instruction = Kleisli {
|
||||
|
|
Loading…
Reference in a new issue