From 29d696c4d9fd6f67a127081ea50b146ff77b3714 Mon Sep 17 00:00:00 2001 From: kamoshi <18511281+kamoshi@users.noreply.github.com> Date: Fri, 6 Dec 2019 22:45:29 +0100 Subject: [PATCH] Add files via upload --- 2019/Scala/day05/Day5.scala | 32 +++++++++++++++++ 2019/Scala/day05/Main.scala | 18 ++++++++++ 2019/Scala/day05/opcode/Action.scala | 7 ++++ 2019/Scala/day05/opcode/Jump.scala | 8 +++++ 2019/Scala/day05/opcode/OpCode.scala | 50 ++++++++++++++++++++++++++ 2019/Scala/day05/opcode/OpCode1.scala | 15 ++++++++ 2019/Scala/day05/opcode/OpCode2.scala | 15 ++++++++ 2019/Scala/day05/opcode/OpCode3.scala | 16 +++++++++ 2019/Scala/day05/opcode/OpCode4.scala | 14 ++++++++ 2019/Scala/day05/opcode/OpCode5.scala | 14 ++++++++ 2019/Scala/day05/opcode/OpCode6.scala | 14 ++++++++ 2019/Scala/day05/opcode/OpCode7.scala | 16 +++++++++ 2019/Scala/day05/opcode/OpCode8.scala | 16 +++++++++ 2019/Scala/day05/opcode/OpCode99.scala | 6 ++++ 14 files changed, 241 insertions(+) create mode 100644 2019/Scala/day05/Day5.scala create mode 100644 2019/Scala/day05/Main.scala create mode 100644 2019/Scala/day05/opcode/Action.scala create mode 100644 2019/Scala/day05/opcode/Jump.scala create mode 100644 2019/Scala/day05/opcode/OpCode.scala create mode 100644 2019/Scala/day05/opcode/OpCode1.scala create mode 100644 2019/Scala/day05/opcode/OpCode2.scala create mode 100644 2019/Scala/day05/opcode/OpCode3.scala create mode 100644 2019/Scala/day05/opcode/OpCode4.scala create mode 100644 2019/Scala/day05/opcode/OpCode5.scala create mode 100644 2019/Scala/day05/opcode/OpCode6.scala create mode 100644 2019/Scala/day05/opcode/OpCode7.scala create mode 100644 2019/Scala/day05/opcode/OpCode8.scala create mode 100644 2019/Scala/day05/opcode/OpCode99.scala diff --git a/2019/Scala/day05/Day5.scala b/2019/Scala/day05/Day5.scala new file mode 100644 index 0000000..b8068c3 --- /dev/null +++ b/2019/Scala/day05/Day5.scala @@ -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") + } + } + +} diff --git a/2019/Scala/day05/Main.scala b/2019/Scala/day05/Main.scala new file mode 100644 index 0000000..5363108 --- /dev/null +++ b/2019/Scala/day05/Main.scala @@ -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...") + + } + +} diff --git a/2019/Scala/day05/opcode/Action.scala b/2019/Scala/day05/opcode/Action.scala new file mode 100644 index 0000000..9ceeb44 --- /dev/null +++ b/2019/Scala/day05/opcode/Action.scala @@ -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) +} diff --git a/2019/Scala/day05/opcode/Jump.scala b/2019/Scala/day05/opcode/Jump.scala new file mode 100644 index 0000000..b37e00e --- /dev/null +++ b/2019/Scala/day05/opcode/Jump.scala @@ -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) +} + diff --git a/2019/Scala/day05/opcode/OpCode.scala b/2019/Scala/day05/opcode/OpCode.scala new file mode 100644 index 0000000..d0a517b --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode.scala @@ -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) + } + } +} diff --git a/2019/Scala/day05/opcode/OpCode1.scala b/2019/Scala/day05/opcode/OpCode1.scala new file mode 100644 index 0000000..6cd7c0e --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode1.scala @@ -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 + } +} diff --git a/2019/Scala/day05/opcode/OpCode2.scala b/2019/Scala/day05/opcode/OpCode2.scala new file mode 100644 index 0000000..19892cf --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode2.scala @@ -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 + } +} diff --git a/2019/Scala/day05/opcode/OpCode3.scala b/2019/Scala/day05/opcode/OpCode3.scala new file mode 100644 index 0000000..921ae8a --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode3.scala @@ -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) + } +} diff --git a/2019/Scala/day05/opcode/OpCode4.scala b/2019/Scala/day05/opcode/OpCode4.scala new file mode 100644 index 0000000..8afba0e --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode4.scala @@ -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)) + } +} diff --git a/2019/Scala/day05/opcode/OpCode5.scala b/2019/Scala/day05/opcode/OpCode5.scala new file mode 100644 index 0000000..0b6e42a --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode5.scala @@ -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) + } +} diff --git a/2019/Scala/day05/opcode/OpCode6.scala b/2019/Scala/day05/opcode/OpCode6.scala new file mode 100644 index 0000000..00716b2 --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode6.scala @@ -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) + } +} diff --git a/2019/Scala/day05/opcode/OpCode7.scala b/2019/Scala/day05/opcode/OpCode7.scala new file mode 100644 index 0000000..15fda76 --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode7.scala @@ -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) + } +} diff --git a/2019/Scala/day05/opcode/OpCode8.scala b/2019/Scala/day05/opcode/OpCode8.scala new file mode 100644 index 0000000..ab935b5 --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode8.scala @@ -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) + } +} diff --git a/2019/Scala/day05/opcode/OpCode99.scala b/2019/Scala/day05/opcode/OpCode99.scala new file mode 100644 index 0000000..dffb03c --- /dev/null +++ b/2019/Scala/day05/opcode/OpCode99.scala @@ -0,0 +1,6 @@ +package day05.opcode + +case object OpCode99 extends OpCode { + /** length of an instruction */ + override val length: Int = 1 +}