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