Coverage Summary for Class: Box (day15p2)

Class Class, % Method, % Line, %
Box 100% (1/1) 100% (5/5) 100% (7/7)


 package day15p2
 
 import day15p2.Step.AddLens
 import day15p2.Step.RemoveLens
 
 class Boxes {
   val boxes: List<Box> = (0..255).map { Box(it) }
 
   fun processInitSeq(initSeqInput: String): Long {
     initSeqInput.parseSteps().forEach { step ->
       when (step) {
         is AddLens -> boxes[step.lens.hash].addLens(step.lens, step.focalLength)
         else -> boxes[step.lens.hash].removeLens(step.lens)
       }
     }
 
     return boxes.sumOf { it.focusingPower() }
   }
 }
 
 data class Box(val id: Int) {
   val lenses: LinkedHashMap<String, Int> = LinkedHashMap()
 
   fun addLens(lens: Lens, focalLength: Int) {
     lenses[lens.label] = focalLength
   }
 
   fun removeLens(lens: Lens) {
     lenses.remove(lens.label)
   }
 
   fun focusingPower(): Long = lenses.entries.asSequence().withIndex().sumOf { (index, entry) ->
     val (_, focusingPower) = entry
 
     (id + 1L) * (index + 1) * focusingPower
   }
 }
 
 fun String.parseSteps(): List<Step> = parseInitSeq().map { input ->
   val addLensParts = input.split('=')
   return@map if (addLensParts.size == 2) {
     AddLens(Lens(addLensParts[0]), addLensParts[1].toInt())
   } else {
     RemoveLens(Lens(input.removeSuffix("-")))
   }
 }
 
 data class Lens(val label: String, val hash: Int) {
   constructor(label: String) : this(label, HASH(label))
 }
 
 sealed interface Step {
   val lens: Lens
 
   fun toText(): String
 
   data class AddLens(override val lens: Lens, val focalLength: Int) : Step {
     override fun toText() = "${lens.label}=$focalLength"
   }
 
   data class RemoveLens(override val lens: Lens) : Step {
     override fun toText() = "${lens.label}-"
   }
 }
 
 private fun String.parseInitSeq(): List<String> = filter { it != '\n' }.split(',')
 
 fun HASH(input: String): Int = 0.HASH(input)
 
 fun Int.HASH(input: String): Int {
   var result = this
   for (i in input.indices) {
     result += input[i].code
     result *= 17
     result %= 256
   }
 
   return result
 }