aoc-old/aoc/src/main/scala/aoc/y2019/intcode/OperandMode.scala

39 lines
978 B
Scala

package aoc.y2019.intcode
import cats.data.{Kleisli, State}
case class OperandMode(get: Kleisli[Operation, BigInt, BigInt], set: Kleisli[Operation, (BigInt, BigInt), Unit])
object OperandMode {
val position: OperandMode = OperandMode(
Kleisli(Machine.get),
Kleisli { case (address, value) => Machine.set(address, value) }
)
val immediate: OperandMode = OperandMode(
Kleisli(State.pure),
Kleisli(_ => throw new IllegalArgumentException("Cannot set in immediate mode!"))
)
val relative: OperandMode = OperandMode(
Kleisli { address =>
for {
offset <- Machine.getOffset
value <- Machine.get(address + offset)
} yield value
},
Kleisli { case (address, value) =>
for {
offset <- Machine.getOffset
set <- Machine.set(address + offset, value)
} yield set
}
)
val defaultOperandModes: Map[Int, OperandMode] = Map(
0 -> position,
1 -> immediate,
2 -> relative,
)
}