aoc2023/Day15.scala
2023-12-15 12:11:06 +01:00

63 lines
1.5 KiB
Scala

package aoc.day15
import aoc._
import scala.collection.mutable
val instructionStrings = lines.next().split(',').toSeq
// part 1
extension (s: String)
def day15Hash =
s.foldLeft(0)((a, b) => ((a + b) * 17) & 255)
def part1 =
println(instructionStrings.map(_.day15Hash).sum)
// part 2
enum Ins:
case Del(label: String)
case Add(label: String, length: Int)
def hash = this match
case Del(label) => label.day15Hash
case Add(label, length) => label.day15Hash
import Ins._
object Parser extends CommonParser:
val insKind =
"""[a-z]+""".r.flatMap { label =>
("-" ^^^ Del(label)) |
("=" ~ num ^^ { case _ ~ num => Add(label, num) })
}
def apply(s: String) = parse(insKind, s).get
val instructions = instructionStrings.map(Parser(_))
class Sim(ss: Seq[Ins]):
private val boxes = (0 to 255).map(_ => mutable.ArrayBuffer.empty[Add]).toArray
def handle(ins: Ins): Unit = ins match
case a @ Add(label, length) =>
boxes(ins.hash).indexWhere(_.label == label) match
case -1 => boxes(ins.hash).append(a)
case pos => boxes(ins.hash)(pos) = a
case Del(label) => boxes(ins.hash).filterInPlace(_.label != label)
ss.foreach(handle)
def remain =
boxes.toIterator.zipWithIndex.flatMap { (box, idx) =>
box.toIterator.zipWithIndex.map { (add, pos) =>
(idx + 1, pos + 1, add.length)
}
}
def part2 =
println(Sim(instructions).remain.map(_ * _ * _).sum)
@main def Day15(part: Int) = part match
case 1 => part1
case 2 => part2