Day 7 part 2
This commit is contained in:
parent
0664894ef2
commit
37bc98fafb
|
@ -13,7 +13,7 @@ object Day02 extends Day {
|
||||||
val initialState = Intcode.Machine(memory)
|
val initialState = Intcode.Machine(memory)
|
||||||
val runMachine = for {
|
val runMachine = for {
|
||||||
_ <- initialReplacement(noun, verb)
|
_ <- initialReplacement(noun, verb)
|
||||||
ran <- Intcode.run
|
ran <- Intcode.run()
|
||||||
} yield ran
|
} yield ran
|
||||||
val endState = runMachine.runS(initialState).value
|
val endState = runMachine.runS(initialState).value
|
||||||
endState.memory(0)
|
endState.memory(0)
|
||||||
|
|
|
@ -13,7 +13,7 @@ object Day05 extends Day {
|
||||||
val machineInput = diagnosticNumber
|
val machineInput = diagnosticNumber
|
||||||
val runMachine: Intcode.Operation = for {
|
val runMachine: Intcode.Operation = for {
|
||||||
_ <- Intcode.input(machineInput)
|
_ <- Intcode.input(machineInput)
|
||||||
ran <- Intcode.run
|
ran <- Intcode.run()
|
||||||
} yield ran
|
} yield ran
|
||||||
val endState = runMachine.runS(initialState).value
|
val endState = runMachine.runS(initialState).value
|
||||||
endState.output.last
|
endState.output.last
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
package aoc.y2019
|
package aoc.y2019
|
||||||
|
|
||||||
import aoc.Day
|
import aoc.Day
|
||||||
|
import cats._
|
||||||
|
import cats.implicits._
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
object Day07 extends Day {
|
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) {
|
if(order.isEmpty) {
|
||||||
input
|
input
|
||||||
} else {
|
} else {
|
||||||
val firstInput = order.head
|
val firstInput = order.head
|
||||||
val secondInput = input
|
val secondInput = input
|
||||||
val runAmplifier = for {
|
val runAmplifier = for {
|
||||||
_ <- Intcode.input(firstInput)
|
_ <- Intcode.input(firstInput)
|
||||||
_ <- Intcode.input(secondInput)
|
_ <- Intcode.input(secondInput)
|
||||||
ran <- Intcode.run
|
ran <- Intcode.run()
|
||||||
} yield ran
|
} yield ran
|
||||||
val output = runAmplifier.runS(machine).value.output.head
|
val output = runAmplifier.runS(machine).value.output.head
|
||||||
runAmplifiers(machine, order.tail, output)
|
runAmplifiers(machine, order.tail, output)
|
||||||
|
@ -29,5 +30,39 @@ object Day07 extends Day {
|
||||||
maximumSignal.toString
|
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,
|
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 =>
|
machine: Machine =>
|
||||||
val instructionAndFlags = machine.memory(machine.pc)
|
val instructionAndFlags = machine.memory(machine.pc)
|
||||||
val instruction: Instruction = instructions(instructionAndFlags % 100)
|
val instruction: Instruction = instructions(instructionAndFlags % 100)
|
||||||
|
@ -32,12 +32,13 @@ object Intcode {
|
||||||
}
|
}
|
||||||
(instruction, flags)
|
(instruction, flags)
|
||||||
}
|
}
|
||||||
val step: Operation = for {
|
def step(instructions: Map[Int, Instruction] = instructions): Operation = for {
|
||||||
(instruction, flags) <- parse
|
(instruction, flags) <- parse(instructions)
|
||||||
_ <- advance(1)
|
_ <- advance(1)
|
||||||
result <- instruction.run(flags)
|
result <- instruction.run(flags)
|
||||||
} yield result
|
} 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(())
|
val noop: Operation = State.pure(())
|
||||||
|
|
||||||
|
@ -62,6 +63,9 @@ object Intcode {
|
||||||
machine.copy(output = machine.output :+ value)
|
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 {
|
object Instruction {
|
||||||
|
|
||||||
def trans(operandCount: Int, operation: Kleisli[State[Machine, *], Vector[Int], Unit]): Instruction = Kleisli {
|
def trans(operandCount: Int, operation: Kleisli[State[Machine, *], Vector[Int], Unit]): Instruction = Kleisli {
|
||||||
|
|
Loading…
Reference in New Issue