Day 7 part 2

This commit is contained in:
Aly 2019-12-07 18:55:07 -08:00 committed by Anthony Cerruti
parent 0664894ef2
commit 37bc98fafb
4 changed files with 50 additions and 11 deletions

View file

@ -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)

View file

@ -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

View file

@ -1,21 +1,22 @@
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 {
val firstInput = order.head
val secondInput = input
val runAmplifier = for {
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
}
}

View file

@ -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 {