Add files via upload
This commit is contained in:
parent
6396c14e48
commit
af8814a3c1
41
2019/day5/Main.scala
Normal file
41
2019/day5/Main.scala
Normal file
|
@ -0,0 +1,41 @@
|
|||
package day5
|
||||
|
||||
import day5.opcode.{Action, Jump, OpCode1, OpCode2, OpCode99}
|
||||
|
||||
import scala.io.Source
|
||||
|
||||
object Main {
|
||||
|
||||
val insertTape = Source.fromFile(getClass.getResource("/input5.txt").getFile).mkString.split("[^\\d-]+").map(x => x.toInt)
|
||||
|
||||
def opCodeRunner(tape: Array[Int], nextPtr: Int): Boolean =
|
||||
{
|
||||
//println("=======\nParsing at "+nextPtr+": ["+tape(nextPtr)+", "+tape(nextPtr+1)+", "+tape(nextPtr+2)+", "+tape(nextPtr+3)+ "]");
|
||||
val tuple = OpCode1.parseInt(tape(nextPtr));
|
||||
//println("Executing: " + tuple)
|
||||
tuple match
|
||||
{
|
||||
case (_, _, _, OpCode99) => true // finish
|
||||
case (m3, m2, m1, instruction: Jump) =>
|
||||
{
|
||||
val (bool, jmpPtr) = instruction.checkConditionAndJump(tape, tape(nextPtr+1), tape(nextPtr+2), tape(nextPtr+3), m1, m2, m3)
|
||||
//println("Jumping?: " + bool + " " + jmpPtr)
|
||||
if (bool) opCodeRunner(tape, jmpPtr)
|
||||
else opCodeRunner(tape, nextPtr + instruction.length)
|
||||
}
|
||||
case (m3, m2, m1, instruction: Action) =>
|
||||
{
|
||||
instruction.exec(tape, tape(nextPtr+1), tape(nextPtr+2), tape(nextPtr+3), m1, m2, m3)
|
||||
opCodeRunner(tape, nextPtr + instruction.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
println("Starting program...")
|
||||
|
||||
opCodeRunner(insertTape, 0)
|
||||
|
||||
println("Program finished...")
|
||||
}
|
||||
}
|
7
2019/day5/opcode/Action.scala
Normal file
7
2019/day5/opcode/Action.scala
Normal file
|
@ -0,0 +1,7 @@
|
|||
package day5.opcode
|
||||
|
||||
trait Action extends OpCode
|
||||
{
|
||||
/** Executes instruction for given parameters and modes */
|
||||
def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int)
|
||||
}
|
8
2019/day5/opcode/Jump.scala
Normal file
8
2019/day5/opcode/Jump.scala
Normal file
|
@ -0,0 +1,8 @@
|
|||
package day5.opcode
|
||||
|
||||
trait Jump extends OpCode
|
||||
{
|
||||
/** Executes instruction for given parameters and modes */
|
||||
def checkConditionAndJump(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): (Boolean, Int)
|
||||
}
|
||||
|
49
2019/day5/opcode/OpCode.scala
Normal file
49
2019/day5/opcode/OpCode.scala
Normal file
|
@ -0,0 +1,49 @@
|
|||
package day5.opcode
|
||||
|
||||
abstract trait OpCode
|
||||
{
|
||||
/** length of an instruction */
|
||||
val length: Int
|
||||
|
||||
/** Parse int to full OpCode */
|
||||
def parseInt(code: Int): (Int, Int, Int, OpCode) = // Dunno how to make this static lmao
|
||||
{
|
||||
val opCodeInt: Int = code % 100 // Instruction Code
|
||||
val modeStr = code.toString.substring(0, {if (code.toString.length > 1) code.toString.length - 2 else 0})
|
||||
val modes = ("000".substring(modeStr.length) + modeStr).toArray.map(_.asDigit) // List of modes
|
||||
opCodeInt match {
|
||||
case 1 => (modes(0), modes(1), modes(2), OpCode1)
|
||||
case 2 => (modes(0), modes(1), modes(2), OpCode2)
|
||||
case 3 => (modes(0), modes(1), modes(2), OpCode3)
|
||||
case 4 => (modes(0), modes(1), modes(2), OpCode4)
|
||||
case 5 => (modes(0), modes(1), modes(2), OpCode5)
|
||||
case 6 => (modes(0), modes(1), modes(2), OpCode6)
|
||||
case 7 => (modes(0), modes(1), modes(2), OpCode7)
|
||||
case 8 => (modes(0), modes(1), modes(2), OpCode8)
|
||||
case 99 => (0, 0, 0, OpCode99)
|
||||
case c => throw new Exception("Wrong instruction code " + c)
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns correct value, immediate or positional */
|
||||
protected[this] def accessor(param: Int, mode: Int, tape: Array[Int]): Int =
|
||||
{
|
||||
mode match
|
||||
{
|
||||
case 0 => /* println("Reading "+tape(param)+" from array("+param+")");*/ tape(param);
|
||||
case 1 => /*println("Reading "+param+" immediate");*/ param
|
||||
case p => throw new Exception("HCF: wrong accessor parameter " + p)
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes to the tape in a manner specified by the mode */
|
||||
protected[this] def writer(param: Int, mode: Int, tape: Array[Int], value: Int): Unit =
|
||||
{
|
||||
mode match
|
||||
{
|
||||
case 0 => tape(param) = value//; println("Writing "+value+" to array("+param+")")
|
||||
case 1 => throw new Exception("HCF: unimplemented writer parameter 1")
|
||||
case p => throw new Exception("HCF: wrong writer parameter " + p)
|
||||
}
|
||||
}
|
||||
}
|
15
2019/day5/opcode/OpCode1.scala
Normal file
15
2019/day5/opcode/OpCode1.scala
Normal file
|
@ -0,0 +1,15 @@
|
|||
package day5.opcode
|
||||
|
||||
/** Sum */
|
||||
case object OpCode1 extends Action
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 4
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): Unit =
|
||||
{
|
||||
val result = accessor(param1, mode1, tape) + accessor(param2, mode2, tape)
|
||||
writer(param3, 0, tape, result) // Write mode is 0 default for now
|
||||
}
|
||||
}
|
15
2019/day5/opcode/OpCode2.scala
Normal file
15
2019/day5/opcode/OpCode2.scala
Normal file
|
@ -0,0 +1,15 @@
|
|||
package day5.opcode
|
||||
|
||||
/** Multiplication */
|
||||
case object OpCode2 extends Action
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 4
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): Unit =
|
||||
{
|
||||
val result = accessor(param1, mode1, tape) * accessor(param2, mode2, tape)
|
||||
writer(param3, 0, tape, result) // Write mode is 0 default for now
|
||||
}
|
||||
}
|
16
2019/day5/opcode/OpCode3.scala
Normal file
16
2019/day5/opcode/OpCode3.scala
Normal file
|
@ -0,0 +1,16 @@
|
|||
package day5.opcode
|
||||
|
||||
/** Input */
|
||||
case object OpCode3 extends Action
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 2
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): Unit =
|
||||
{
|
||||
println("<< input")
|
||||
val userInput = scala.io.StdIn.readInt()
|
||||
writer(param1, 0, tape, userInput)
|
||||
}
|
||||
}
|
18
2019/day5/opcode/OpCode4.scala
Normal file
18
2019/day5/opcode/OpCode4.scala
Normal file
|
@ -0,0 +1,18 @@
|
|||
package day5.opcode
|
||||
|
||||
/** Output */
|
||||
case object OpCode4 extends Action
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 2
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): Unit =
|
||||
{
|
||||
mode1 match
|
||||
{
|
||||
case 0 => println(accessor(param1, 0, tape))
|
||||
case 1 => println(param1)
|
||||
}
|
||||
}
|
||||
}
|
14
2019/day5/opcode/OpCode5.scala
Normal file
14
2019/day5/opcode/OpCode5.scala
Normal file
|
@ -0,0 +1,14 @@
|
|||
package day5.opcode
|
||||
|
||||
case object OpCode5 extends Jump
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 3
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def checkConditionAndJump(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): (Boolean, Int) =
|
||||
{
|
||||
if (accessor(param1, mode1, tape) != 0) (true, accessor(param2, mode2, tape))
|
||||
else (false, 0)
|
||||
}
|
||||
}
|
14
2019/day5/opcode/OpCode6.scala
Normal file
14
2019/day5/opcode/OpCode6.scala
Normal file
|
@ -0,0 +1,14 @@
|
|||
package day5.opcode
|
||||
|
||||
case object OpCode6 extends Jump
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 3
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def checkConditionAndJump(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): (Boolean, Int) =
|
||||
{
|
||||
if (accessor(param1, mode1, tape) == 0) (true, accessor(param2, mode2, tape))
|
||||
else (false, 0)
|
||||
}
|
||||
}
|
16
2019/day5/opcode/OpCode7.scala
Normal file
16
2019/day5/opcode/OpCode7.scala
Normal file
|
@ -0,0 +1,16 @@
|
|||
package day5.opcode
|
||||
|
||||
case object OpCode7 extends Action
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 4
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): Unit =
|
||||
{
|
||||
if (accessor(param1, mode1, tape) < accessor(param2, mode2, tape))
|
||||
writer(param3, 0, tape, 1)
|
||||
else
|
||||
writer(param3, 0, tape, 0)
|
||||
}
|
||||
}
|
16
2019/day5/opcode/OpCode8.scala
Normal file
16
2019/day5/opcode/OpCode8.scala
Normal file
|
@ -0,0 +1,16 @@
|
|||
package day5.opcode
|
||||
|
||||
case object OpCode8 extends Action
|
||||
{
|
||||
/** length of an instruction */
|
||||
override val length: Int = 4
|
||||
|
||||
/** Executes instruction for given parameters and modes */
|
||||
override def exec(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): Unit =
|
||||
{
|
||||
if (accessor(param1, mode1, tape) == accessor(param2, mode2, tape))
|
||||
writer(param3, 0, tape, 1)
|
||||
else
|
||||
writer(param3, 0, tape, 0)
|
||||
}
|
||||
}
|
6
2019/day5/opcode/OpCode99.scala
Normal file
6
2019/day5/opcode/OpCode99.scala
Normal file
|
@ -0,0 +1,6 @@
|
|||
package day5.opcode
|
||||
|
||||
case object OpCode99 extends OpCode {
|
||||
/** length of an instruction */
|
||||
override val length: Int = 1
|
||||
}
|
Loading…
Reference in a new issue