Add files via upload

This commit is contained in:
kamoshi 2019-12-06 22:45:29 +01:00 committed by GitHub
parent a4fbb2d7f1
commit 29d696c4d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 241 additions and 0 deletions

View file

@ -0,0 +1,32 @@
package day05
import day05.opcode.{Action, Jump, OpCode99}
class Day5
{
@scala.annotation.tailrec
final def opCodeRunner(tape: Array[Int], nextPtr: Int = 0): Boolean =
{
//println("=======\nParsing at "+nextPtr+": ["+tape(nextPtr)+", "+tape(nextPtr+1)+", "+tape(nextPtr+2)+", "+tape(nextPtr+3)+ "]");
val tuple = OpCode99.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)
}
case _ => throw new Exception("Something went wrong")
}
}
}

View file

@ -0,0 +1,18 @@
package day05
import kamlib.{Reader, Wrapper}
object Main {
def main(args: Array[String]): Unit = {
val input: Array[Int] = Reader.readString("/input5.txt").split("[^\\d-]+").map(x => x.toInt)
val solution: Day5 = new Day5
println("Running program...")
Wrapper(solution.opCodeRunner(input)).print()
println("Program finished...")
}
}

View file

@ -0,0 +1,7 @@
package day05.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)
}

View file

@ -0,0 +1,8 @@
package day05.opcode
trait Jump extends OpCode
{
/** Checks if the condition for jumping is fulfilled, returns boolean and jump pointer */
def checkConditionAndJump(tape: Array[Int], param1: Int, param2: Int, param3: Int, mode1: Int, mode2: Int, mode3: Int): (Boolean, Int)
}

View file

@ -0,0 +1,50 @@
package day05.opcode
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
(modes(0).asDigit, modes(1).asDigit, modes(2).asDigit, opCodeInt) match
{
case (a, b, c, 1) => (a, b, c, OpCode1)
case (a, b, c, 2) => (a, b, c, OpCode2)
case (a, b, c, 3) => (a, b, c, OpCode3)
case (a, b, c, 4) => (a, b, c, OpCode4)
case (a, b, c, 5) => (a, b, c, OpCode5)
case (a, b, c, 6) => (a, b, c, OpCode6)
case (a, b, c, 7) => (a, b, c, OpCode7)
case (a, b, c, 8) => (a, b, c, 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)
}
}
}

View file

@ -0,0 +1,15 @@
package day05.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
}
}

View file

@ -0,0 +1,15 @@
package day05.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
}
}

View file

@ -0,0 +1,16 @@
package day05.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)
}
}

View file

@ -0,0 +1,14 @@
package day05.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 =
{
println(accessor(param1, mode1, tape))
}
}

View file

@ -0,0 +1,14 @@
package day05.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)
}
}

View file

@ -0,0 +1,14 @@
package day05.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)
}
}

View file

@ -0,0 +1,16 @@
package day05.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)
}
}

View file

@ -0,0 +1,16 @@
package day05.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)
}
}

View file

@ -0,0 +1,6 @@
package day05.opcode
case object OpCode99 extends OpCode {
/** length of an instruction */
override val length: Int = 1
}