This commit is contained in:
Max Nuding 2021-12-16 08:07:37 +01:00
parent e70e71b068
commit a786262683
Signed by: phlaym
GPG Key ID: A06651BAB6777237

View File

@ -9,33 +9,31 @@ import Foundation
import Runner
import Collections
enum PacketType: String {
case value
case op
init(rawValue: String) {
switch rawValue {
case "100":
self = .value
default:
self = .op
}
}
enum OperatorType: Int {
case sum = 0
case product = 1
case minimum = 2
case maximum = 3
case value = 4
case greaterThan = 5
case lessThan = 6
case equal = 7
}
protocol Packet {
//var type: PacketType { get }
var version: Int { get }
var type: OperatorType { get }
}
struct ValuePacket: Packet {
//let type: PacketType
let type: OperatorType = .value
let version: Int
let value: Int
}
struct OperatorPacket: Packet {
//let type: PacketType
let type: OperatorType
let version: Int
let subPackets: [Packet]
}
@ -49,8 +47,6 @@ class Day16: Runnable {
public func run() {
let input = try! String(contentsOfFile: inputPath)
//let input = "620080001611562C8802118E34"
//let input = "D2FE28"
let parts = input
.trimmingCharacters(in: .newlines)
let bytes = parts.ToBinary().joined()
@ -58,6 +54,7 @@ class Day16: Runnable {
let p: Packet = packets.0
let totalVersion = getPacketVersion(p: p)
print(totalVersion)
print(getPacketValue(p: p))
}
func getPacketVersion(p: Packet) -> Int {
@ -69,22 +66,48 @@ class Day16: Runnable {
}
}
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!
}
}
func parsePacket(bytes: String) -> (Packet, String) {
let version = bytes[bytes.startIndex..<bytes.index(bytes.startIndex, offsetBy: 3)].description.binaryToDecimal()
let typeId = bytes[bytes.index(bytes.startIndex, offsetBy: 3)..<bytes.index(bytes.startIndex, offsetBy: 6)].description
let typeId = bytes[bytes.index(bytes.startIndex, offsetBy: 3)..<bytes.index(bytes.startIndex, offsetBy: 6)].description.binaryToDecimal()
var value: Packet
var reminder: String
switch typeId {
case "100":
case 4:
let (v, r) = parseLiteralPacketValue(bytes: bytes)
value = ValuePacket(version: version, value: v)
reminder = r
//case "110":
// break
default:
//fatalError("Unknown packet \(typeId)")
let (v, r) = parseOperatorPacker(bytes: bytes)
value = OperatorPacket(version: version, subPackets: v)
value = OperatorPacket(type: OperatorType(rawValue: typeId)!, version: version, subPackets: v)
reminder = r
}
return (value, reminder)