Skip to content

Instantly share code, notes, and snippets.

@sangkeon
Created January 22, 2021 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sangkeon/e82f67f4f68509f32616b493804c61df to your computer and use it in GitHub Desktop.
Save sangkeon/e82f67f4f68509f32616b493804c61df to your computer and use it in GitHub Desktop.
import scala.annotation.tailrec
import scala.collection.immutable.HashSet
import scala.io.Source
object Main {
def main(args: Array[String]): Unit = {
val lines = Source.fromFile("input.txt").getLines().toList
val (part1,_) = execute(lines, 0, 0, HashSet[Integer]())
println("part1=" + part1)
lines.zipWithIndex.foreach(
(code, number) => {
if (code.startsWith("jmp") || code.startsWith("nop")) {
val (inst, param) = code.splitAt(3)
val newInst = if(inst == "jmp") "nop" else "jmp"
val trialLines = lines.updated(number, newInst + param)
val (acc, terminated) = execute(trialLines, 0, 0, HashSet[Integer]())
if(terminated) {
println("part2=" + acc)
}
}
}
)
}
@tailrec
def execute(codes: List[String], pos:Integer, acc:Integer, visited:Set[Integer]) : (Integer, Boolean) = {
val code = codes(pos)
val (inst, op) = parse(code)
if(pos >= codes.size - 1) (acc, true)
else if (visited.contains(pos)) (acc, false)
else {
inst match {
case "acc" => execute(codes, pos + 1, acc + op, visited + pos)
case "jmp" => execute(codes, pos + op, acc, visited + pos)
case _ => execute(codes, pos + 1, acc, visited + pos)
}
}
}
def parse(code:String) : (String, Integer) = {
val (inst, op) = code.splitAt(4)
(inst.trim, parseOp(op))
}
def parseOp(op:String): Integer = {
val (sign, amountStr) = op.splitAt(1)
val amount = Integer.parseInt(amountStr)
sign match {
case "-" => -amount
case _ => amount
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment