mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 13:59:51 +01:00
Adding day 18 p1 and 19 p1 + creating folder 2018
This commit is contained in:
68
2018/day19/part1.scala
Normal file
68
2018/day19/part1.scala
Normal file
@@ -0,0 +1,68 @@
|
||||
import scala.io.StdIn.readLine
|
||||
|
||||
def ifb(A: Int, B: Int, f: (Int, Int) => Boolean): Int = if (f(A, B)) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
val OP_CODES: Map[String, ((Int, Int, Int, Registers) => Registers)] = Map(
|
||||
"addr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) + regs(B)), 1)),
|
||||
"addi" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) + B), 1)),
|
||||
|
||||
"mulr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) * regs(B)), 1)),
|
||||
"muli" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) * B), 1)),
|
||||
|
||||
"banr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) & regs(B)), 1)),
|
||||
"bani" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) & B), 1)),
|
||||
|
||||
"borr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) | regs(B)), 1)),
|
||||
"bori" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) | B), 1)),
|
||||
|
||||
"setr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A)), 1)),
|
||||
"seti" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(A), 1)),
|
||||
|
||||
"gtir" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(A, regs(B), _ > _)), 1)),
|
||||
"gtri" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), B, _ > _)), 1)),
|
||||
"gtrr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), regs(B), _ > _)), 1)),
|
||||
|
||||
"eqir" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(A, regs(B), _ == _)), 1)),
|
||||
"eqri" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), B, _ == _)), 1)),
|
||||
"eqrr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), regs(B), _ == _)), 1))
|
||||
)
|
||||
|
||||
type Registers = List[Int]
|
||||
|
||||
case class Instruction(opcode: String, A: Int, B: Int, C: Int) {
|
||||
override def toString: String = s"$opcode $A $B $C"
|
||||
}
|
||||
|
||||
object Instruction {
|
||||
def apply(str: String): Instruction = str.split(" ").toList match {
|
||||
case op :: a :: b :: c :: Nil => Instruction(op, a.toInt, b.toInt, c.toInt)
|
||||
case _ => throw new RuntimeException("Invalid input")
|
||||
}
|
||||
}
|
||||
|
||||
val (Some(ptr), programLines) = Iterator
|
||||
.continually(readLine)
|
||||
.takeWhile(_ != null)
|
||||
.foldLeft(
|
||||
(None : Option[Int], List.empty[Instruction])
|
||||
) {
|
||||
case ((None, _), line) => (Some(line.split(" ")(1).toInt), List())
|
||||
case ((ptr, lines), line) => (ptr, lines ++ List(Instruction(line)))
|
||||
}
|
||||
|
||||
def executeProgram(ptr: Int, instructions: List[Instruction], regs: Registers): Registers = regs(ptr) match {
|
||||
case p if instructions.isDefinedAt(p) =>
|
||||
val inst = instructions(p)
|
||||
val outputRegs = OP_CODES(inst.opcode)(inst.A, inst.B, inst.C, regs)
|
||||
val incrPtrInRegs = outputRegs.patch(ptr, List(outputRegs(ptr) + 1), 1)
|
||||
// println(s"ip=$ptr ${regs.mkString("[", ", ", "]")} $inst ${incrPtrInRegs.mkString("[", ", ", "]")}")
|
||||
executeProgram(ptr, instructions, incrPtrInRegs)
|
||||
case _ => regs
|
||||
}
|
||||
|
||||
val endRegs = executeProgram(ptr, programLines, List.fill(6)(0))
|
||||
println(s"End value in reg 0: " + endRegs(0))
|
||||
Reference in New Issue
Block a user