From e6ef68d81852e1aa7717d20c0694146c3fae24c3 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Fri, 15 Dec 2023 09:42:11 +0100 Subject: [PATCH] day 15 puzzle 2 --- src/day15/Box.scala | 33 ++++++++++++++++ src/day15/Lens.scala | 5 +++ src/day15/Puzzle2.scala | 71 +++++++++++++++++++++++++++++++++++ tests/day15/Puzzle2Test.scala | 9 +++++ 4 files changed, 118 insertions(+) create mode 100644 src/day15/Box.scala create mode 100644 src/day15/Lens.scala create mode 100644 src/day15/Puzzle2.scala create mode 100644 tests/day15/Puzzle2Test.scala diff --git a/src/day15/Box.scala b/src/day15/Box.scala new file mode 100644 index 0000000..d2fc6b9 --- /dev/null +++ b/src/day15/Box.scala @@ -0,0 +1,33 @@ +package day15 + +import scala.collection.mutable.ArrayBuffer + +class Box(val id: Int) { + var lenses: ArrayBuffer[Lens] = new ArrayBuffer() + var lensesLabels: ArrayBuffer[String] = new ArrayBuffer() + + def addLens(lens: Lens): Unit = { + if (lensesLabels.contains(lens.label)) { + val i: Int = lensesLabels.indexOf(lens.label) + lenses(i) = lens + } else { + lenses.addOne(lens) + lensesLabels.addOne(lens.label) + } + } + + def removeLens(label: String): Unit = { + if (lensesLabels.contains(label)) { + val i: Int = lensesLabels.indexOf(label) + lenses.remove(i) + lensesLabels.remove(i) + } + } + def getFocusingPower(): Long = { + var power: Long = 0 + for ((lens: Lens, i: Int) <- lenses.zipWithIndex) { + power += (i+1) * lens.focalLength + } + return power + } +} diff --git a/src/day15/Lens.scala b/src/day15/Lens.scala new file mode 100644 index 0000000..2a4baf2 --- /dev/null +++ b/src/day15/Lens.scala @@ -0,0 +1,5 @@ +package day15 + +class Lens(val label: String, val focalLength: Int) { + +} diff --git a/src/day15/Puzzle2.scala b/src/day15/Puzzle2.scala new file mode 100644 index 0000000..ff3ec53 --- /dev/null +++ b/src/day15/Puzzle2.scala @@ -0,0 +1,71 @@ +package day15 + +import scala.io.{BufferedSource, Source} +import scala.util.matching.Regex +import scala.util.matching.Regex.Match + +object Puzzle2 { + var steps: Array[String] = Array.empty + val boxes: Array[Box] = new Array(256) + val regex: Regex = new Regex("([a-z]+)(-|=\\d)") + def loadInput(path: String): Unit = { + val source: BufferedSource = Source.fromFile(path) + val line: String = source.getLines().mkString + + for (i: Int <- 0 until 256) { + boxes(i) = new Box(i) + } + + steps = line.split(",") + + source.close() + } + + def hash(str: String): Int = { + var value: Int = 0 + for (c: Char <- str) { + value += c + value *= 17 + value %= 256 + } + return value + } + + def getFocusingPower(): Long = { + var power: Long = 0 + for (box: Box <- boxes) { + power += (box.id+1) * box.getFocusingPower() + } + return power + } + + def placeLenses(): Unit = { + for (step: String <- steps) { + val m: Match = regex.findFirstMatchIn(step).get + val label: String = m.group(1) + val labelHash: Int = hash(label) + val action: Char = m.group(2)(0) + val box: Box = boxes(labelHash) + if (action == '=') { + val lens: Lens = new Lens(label, m.group(2)(1) - '0') + box.addLens(lens) + } else { + box.removeLens(label) + } + } + } + + def solve(path: String): Long = { + loadInput(path) + placeLenses() + + val solution: Long = getFocusingPower() + + return solution + } + + def main(args: Array[String]): Unit = { + val solution: Long = solve("./res/day15/input1.txt") + println(solution) + } +} diff --git a/tests/day15/Puzzle2Test.scala b/tests/day15/Puzzle2Test.scala new file mode 100644 index 0000000..71f84f7 --- /dev/null +++ b/tests/day15/Puzzle2Test.scala @@ -0,0 +1,9 @@ +package day15 + +import org.scalatest.funsuite.AnyFunSuite + +class Puzzle2Test extends AnyFunSuite { + test("Puzzle2.solve") { + assert(Puzzle2.solve("tests_res/day15/input1.txt") == 145) + } +}