diff --git a/Sources/16/16.swift b/Sources/16/16.swift index 2405ee4..2678720 100644 --- a/Sources/16/16.swift +++ b/Sources/16/16.swift @@ -2,7 +2,7 @@ // File.swift // // -// Created by Max Nuding on 15s.12.21. +// Created by Max Nuding on 15.12.21. // import Foundation @@ -23,19 +23,46 @@ enum OperatorType: Int { protocol Packet { var version: Int { get } - var type: OperatorType { get } + + func getTotalVersion() -> Int + func getValue() -> Int } struct ValuePacket: Packet { - let type: OperatorType = .value let version: Int let value: Int + + func getTotalVersion() -> Int { version } + func getValue() -> Int { value } } struct OperatorPacket: Packet { let type: OperatorType let version: Int let subPackets: [Packet] + + func getTotalVersion() -> Int { version + subPackets.map { $0.getTotalVersion() }.reduce(0, +) } + func getValue() -> Int { + let spValues = subPackets.map { $0.getValue() } + switch type { + case .sum: + return spValues.reduce(0, +) + case .product: + return spValues.reduce(1, *) + case .minimum: + return spValues.min()! + case .maximum: + return spValues.max()! + case .greaterThan: + return spValues.first! > spValues.last! ? 1 : 0 + case .lessThan: + return spValues.first! < spValues.last! ? 1 : 0 + case .equal: + return spValues.first! == spValues.last! ? 1 : 0 + case .value: + fatalError() + } + } } class Day16: Runnable { @@ -52,47 +79,8 @@ class Day16: Runnable { let bytes = parts.ToBinary().joined() let packets = parsePacket(bytes: bytes) let p: Packet = packets.0 - let totalVersion = getPacketVersion(p: p) - print(totalVersion) - print(getPacketValue(p: p)) - } - - func getPacketVersion(p: Packet) -> Int { - //print("Found packet: \(p)") - if let packet = p as? OperatorPacket { - return packet.version + packet.subPackets.map(getPacketVersion).reduce(0, +) - } else { - return p.version - } - } - - func getPacketValue(p: Packet) -> Int { - var spValues = [Int]() - if let packet = p as? OperatorPacket { - spValues = packet.subPackets.map(getPacketValue) - } else if let packet = p as? ValuePacket { - spValues = [packet.value] - } else { - fatalError() - } - switch p.type { - case .sum: - return spValues.reduce(0, +) - case .product: - return spValues.reduce(1, *) - case .minimum: - return spValues.min()! - case .maximum: - return spValues.max()! - case .greaterThan: - return spValues.first! > spValues.last! ? 1 : 0 - case .lessThan: - return spValues.first! < spValues.last! ? 1 : 0 - case .equal: - return spValues.first! == spValues.last! ? 1 : 0 - case .value: - return spValues.first! - } + print(p.getTotalVersion()) + print(p.getValue()) } func parsePacket(bytes: String) -> (Packet, String) { @@ -156,7 +144,7 @@ class Day16: Runnable { extension String { func ToBinary() -> [String] { - self.map {$0.toBinary()!} + self.map { $0.bits } } func binaryToDecimal() -> Int { @@ -167,7 +155,7 @@ extension String { } extension Character { - func toBinary() -> String? { + var bits: String { switch self { case "0": return "0000" @@ -202,6 +190,7 @@ extension Character { case "F": return "1111" default: - return nil} + fatalError() + } } }