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