Advertisement
vbe_elvis

2021 Day 16

Dec 16th, 2021 (edited)
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.67 KB | None | 0 0
  1. class Packet private constructor(binary: String) {
  2.     private val version = binary.substring(0..2).toInt(2)
  3.     private val type = binary.substring(3..5).toInt(2)
  4.     private var subPackets = emptyList<Packet>()
  5.     private var value = 0L
  6.     private val length: Int
  7.  
  8.     init {
  9.         length = when {
  10.             type == 4 -> {
  11.                 var pointer = 1
  12.                 var binaryValue = ""
  13.                 do {
  14.                     pointer += 5
  15.                     binaryValue += binary.substring(pointer + 1..pointer + 4)
  16.                 } while (binary[pointer] == '1')
  17.                 value = binaryValue.toLong(2)
  18.                 pointer + 5
  19.             }
  20.             binary[6] == '1' -> {
  21.                 var pointer = 18
  22.                 val numberOfPackages = binary.substring(7 until pointer).toInt(2)
  23.                 repeat(numberOfPackages) { pointer += extractSubPacket(binary.substring(pointer)) }
  24.                 pointer
  25.             }
  26.             else -> {
  27.                 var pointer = 22
  28.                 val lengthOfPackges = binary.substring(7 until pointer).toInt(2)
  29.                 while (pointer - 21 < lengthOfPackges) {
  30.                     pointer += extractSubPacket(binary.substring(pointer))
  31.                 }
  32.                 pointer
  33.             }
  34.         }
  35.     }
  36.  
  37.     private fun extractSubPacket(binary: String): Int {
  38.         val subPacket = Packet(binary)
  39.         subPackets = subPackets + subPacket
  40.         return subPacket.length
  41.     }
  42.  
  43.     fun versionSum(): Int = version + subPackets.sumBy { it.versionSum() }
  44.  
  45.     fun calculate(): Long {
  46.         val values = subPackets.map { it.calculate() }
  47.         return when (type) {
  48.             0 -> values.sum()
  49.             1 -> values.fold(1L) { product, it -> product * it }
  50.             2 -> values.min() ?: 0L
  51.             3 -> values.max() ?: 0L
  52.             4 -> value
  53.             5 -> if (values[0] > values[1]) 1L else 0L
  54.             6 -> if (values[0] < values[1]) 1L else 0L
  55.             7 -> if (values[0] == values[1]) 1L else 0L
  56.             else -> 0L
  57.         }
  58.     }
  59.  
  60.     companion object HexPacket {
  61.         operator fun invoke(hexadecimal: String) = Packet(hexadecimal.toBinary())
  62.     }
  63. }
  64.  
  65. private fun String.toBinary() = this.toCharArray().joinToString("") { hex ->
  66.     when (hex) {
  67.         '0' -> "0000"
  68.         '1' -> "0001"
  69.         '2' -> "0010"
  70.         '3' -> "0011"
  71.         '4' -> "0100"
  72.         '5' -> "0101"
  73.         '6' -> "0110"
  74.         '7' -> "0111"
  75.         '8' -> "1000"
  76.         '9' -> "1001"
  77.         'A' -> "1010"
  78.         'B' -> "1011"
  79.         'C' -> "1100"
  80.         'D' -> "1101"
  81.         'E' -> "1110"
  82.         'F' -> "1111"
  83.         else -> ""
  84.     }
  85. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement