Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Packet private constructor(binary: String) {
- private val version = binary.substring(0..2).toInt(2)
- private val type = binary.substring(3..5).toInt(2)
- private var subPackets = emptyList<Packet>()
- private var value = 0L
- private val length: Int
- init {
- length = when {
- type == 4 -> {
- var pointer = 1
- var binaryValue = ""
- do {
- pointer += 5
- binaryValue += binary.substring(pointer + 1..pointer + 4)
- } while (binary[pointer] == '1')
- value = binaryValue.toLong(2)
- pointer + 5
- }
- binary[6] == '1' -> {
- var pointer = 18
- val numberOfPackages = binary.substring(7 until pointer).toInt(2)
- repeat(numberOfPackages) { pointer += extractSubPacket(binary.substring(pointer)) }
- pointer
- }
- else -> {
- var pointer = 22
- val lengthOfPackges = binary.substring(7 until pointer).toInt(2)
- while (pointer - 21 < lengthOfPackges) {
- pointer += extractSubPacket(binary.substring(pointer))
- }
- pointer
- }
- }
- }
- private fun extractSubPacket(binary: String): Int {
- val subPacket = Packet(binary)
- subPackets = subPackets + subPacket
- return subPacket.length
- }
- fun versionSum(): Int = version + subPackets.sumBy { it.versionSum() }
- fun calculate(): Long {
- val values = subPackets.map { it.calculate() }
- return when (type) {
- 0 -> values.sum()
- 1 -> values.fold(1L) { product, it -> product * it }
- 2 -> values.min() ?: 0L
- 3 -> values.max() ?: 0L
- 4 -> value
- 5 -> if (values[0] > values[1]) 1L else 0L
- 6 -> if (values[0] < values[1]) 1L else 0L
- 7 -> if (values[0] == values[1]) 1L else 0L
- else -> 0L
- }
- }
- companion object HexPacket {
- operator fun invoke(hexadecimal: String) = Packet(hexadecimal.toBinary())
- }
- }
- private fun String.toBinary() = this.toCharArray().joinToString("") { hex ->
- when (hex) {
- '0' -> "0000"
- '1' -> "0001"
- '2' -> "0010"
- '3' -> "0011"
- '4' -> "0100"
- '5' -> "0101"
- '6' -> "0110"
- '7' -> "0111"
- '8' -> "1000"
- '9' -> "1001"
- 'A' -> "1010"
- 'B' -> "1011"
- 'C' -> "1100"
- 'D' -> "1101"
- 'E' -> "1110"
- 'F' -> "1111"
- else -> ""
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement