advent-of-code/2019/Scala/day07/intcode/Solver.scala

47 lines
1.4 KiB
Scala
Raw Normal View History

2019-12-07 18:49:02 +01:00
package day07.intcode
class Solver(software: Array[Int])
{
2019-12-07 19:11:36 +01:00
/** Array containing the amplifiers */
2019-12-07 18:49:02 +01:00
val amps: Array[Amplifier] = Array(new Amplifier(software), new Amplifier(software), new Amplifier(software), new Amplifier(software), new Amplifier(software))
2019-12-07 19:11:36 +01:00
/** Reset the amplifiers to the original state */
2019-12-07 18:49:02 +01:00
def reset(): Unit =
amps.foreach(_.reset())
2019-12-07 19:11:36 +01:00
/** Inserts phases AKA the first inputs into amplifiers */
2019-12-07 18:49:02 +01:00
def setupPhases(phases: Array[Int]): Unit =
{
amps.foreach(_.runUntilIO())
2019-12-07 19:11:36 +01:00
for (i <- amps.indices)
{
amps(i).runInput(phases(i))
}
2019-12-07 18:49:02 +01:00
}
2019-12-07 19:11:36 +01:00
/** Solves the single run */
2019-12-07 18:49:02 +01:00
def solveSequenceSingleRun(phases: Array[Int]): Int =
{
reset()
setupPhases(phases)
2019-12-07 19:11:36 +01:00
amps.foldLeft(0){ (input, amp) => amp.runUntilIO().runInput(input).runUntilIO().runOutput() }
2019-12-07 18:49:02 +01:00
}
@scala.annotation.tailrec
2019-12-07 19:11:36 +01:00
private[this] final def solveSequenceFeedback(lastOutput: Int = 0): Int =
2019-12-07 18:49:02 +01:00
{
2019-12-07 19:11:36 +01:00
val result = amps.foldLeft(lastOutput){ (input, amp) => amp.runUntilIO().runInput(input).runUntilIO().runOutput() }
2019-12-07 18:49:02 +01:00
if (amps.foldLeft(false) {(bool, amp) => bool || amp.isHalted}) lastOutput
2019-12-07 19:11:36 +01:00
else solveSequenceFeedback(result)
2019-12-07 18:49:02 +01:00
}
2019-12-07 19:11:36 +01:00
/** Solves the sequence featuring a feedback loop */
2019-12-07 18:49:02 +01:00
def solveSequenceMultiRun(phases: Array[Int]): Int =
{
reset()
setupPhases(phases)
solveSequenceFeedback()
}
}