From e70e71b0685a9f64294b74a0a78587e4651719ae Mon Sep 17 00:00:00 2001 From: Max Nuding Date: Thu, 16 Dec 2021 07:52:35 +0100 Subject: [PATCH] 16a --- Package.swift | 11 +- Sources/16/16.swift | 184 +++++++++++++++++++++ Sources/16/main.swift | 12 ++ Sources/Runner/Resources/input/16.txt | 1 + Sources/Runner/Resources/input/16_test.txt | 1 + 5 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 Sources/16/16.swift create mode 100644 Sources/16/main.swift create mode 100644 Sources/Runner/Resources/input/16.txt create mode 100644 Sources/Runner/Resources/input/16_test.txt diff --git a/Package.swift b/Package.swift index caf8c54..046f1cb 100644 --- a/Package.swift +++ b/Package.swift @@ -24,7 +24,8 @@ let package = Package( .executable(name: "12", targets: ["12"]), .executable(name: "13", targets: ["13"]), .executable(name: "14", targets: ["14"]), - .executable(name: "15", targets: ["15"]) + .executable(name: "15", targets: ["15"]), + .executable(name: "16", targets: ["16"]) ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -112,12 +113,16 @@ let package = Package( .executableTarget( name: "14", dependencies: [ .targetItem(name: "Runner", condition: nil) ] - ) - , + ), .executableTarget( name: "15", dependencies: [ .targetItem(name: "Runner", condition: nil), .product(name: "Collections", package: "swift-collections")] + ), + .executableTarget( + name: "16", + dependencies: [ .targetItem(name: "Runner", condition: nil), + .product(name: "Collections", package: "swift-collections")] ) ] ) diff --git a/Sources/16/16.swift b/Sources/16/16.swift new file mode 100644 index 0000000..19113f7 --- /dev/null +++ b/Sources/16/16.swift @@ -0,0 +1,184 @@ +// +// File.swift +// +// +// Created by Max Nuding on 15s.12.21. +// + +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 + } + } +} + +protocol Packet { + //var type: PacketType { get } + var version: Int { get } +} + +struct ValuePacket: Packet { + //let type: PacketType + let version: Int + let value: Int +} + +struct OperatorPacket: Packet { + //let type: PacketType + let version: Int + let subPackets: [Packet] +} + +class Day16: Runnable { + let inputPath: String + + required init(inputPath: String) { + self.inputPath = inputPath + } + + 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() + let packets = parsePacket(bytes: bytes) + let p: Packet = packets.0 + let totalVersion = getPacketVersion(p: p) + print(totalVersion) + } + + 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 parsePacket(bytes: String) -> (Packet, String) { + let version = bytes[bytes.startIndex.. ([Packet], String) { + let startNextBitsIndex = bytes.index(bytes.startIndex, offsetBy: 7) + let lengthTypeId = bytes[bytes.index(bytes.startIndex, offsetBy: 6).. 0 { + let (p, rem) = parsePacket(bytes: reminder) + number -= isTotalLength ? (reminder.count - rem.count) : 1 + subPackets.append(p) + reminder = rem + } + return (subPackets, reminder) + } + + func parseLiteralPacketValue(bytes: String) -> (Int, String) { + var index = bytes.index(bytes.startIndex, offsetBy: 6) + var ei = index + var bits = "" + var reminder = "" + while true { + let si = bytes.index(index, offsetBy: 1) + ei = bytes.index(si, offsetBy: 4) + bits += bytes[si.. [String] { + self.map {$0.toBinary()!} + } + + func binaryToDecimal() -> Int { + self.reversed().enumerated().reduce(0, { p, cur in + p + (cur.element == "0" ? 0 : Int(pow(2.0, Double(cur.offset)))) + }) + } +} + +extension Character { + func toBinary() -> String? { + switch self { + case "0": + return "0000" + case "1": + return "0001" + case "2": + return "0010" + case "3": + return "0011" + case "4": + return "0100" + case "5": + return "0101" + case "6": + return "0110" + case "7": + return "0111" + case "8": + return "1000" + case "9": + return "1001" + case "A": + return "1010" + case "B": + return "1011" + case "C": + return "1100" + case "D": + return "1101" + case "E": + return "1110" + case "F": + return "1111" + default: + return nil} + } +} diff --git a/Sources/16/main.swift b/Sources/16/main.swift new file mode 100644 index 0000000..1a305a7 --- /dev/null +++ b/Sources/16/main.swift @@ -0,0 +1,12 @@ +// +// File.swift +// +// +// Created by Max Nuding on 15.12.21. +// + +import Foundation +import Runner + +//Runner(target: Day16.self, day: "16", isTest: true).run() +Runner(target: Day16.self, day: "16", isTest: false).run() diff --git a/Sources/Runner/Resources/input/16.txt b/Sources/Runner/Resources/input/16.txt new file mode 100644 index 0000000..53f5708 --- /dev/null +++ b/Sources/Runner/Resources/input/16.txt @@ -0,0 +1 @@ +020D708041258C0B4C683E61F674A1401595CC3DE669AC4FB7BEFEE840182CDF033401296F44367F938371802D2CC9801A980021304609C431007239C2C860400F7C36B005E446A44662A2805925FF96CBCE0033C5736D13D9CFCDC001C89BF57505799C0D1802D2639801A900021105A3A43C1007A1EC368A72D86130057401782F25B9054B94B003013EDF34133218A00D4A6F1985624B331FE359C354F7EB64A8524027D4DEB785CA00D540010D8E9132270803F1CA1D416200FDAC01697DCEB43D9DC5F6B7239CCA7557200986C013912598FF0BE4DFCC012C0091E7EFFA6E44123CE74624FBA01001328C01C8FF06E0A9803D1FA3343E3007A1641684C600B47DE009024ED7DD9564ED7DD940C017A00AF26654F76B5C62C65295B1B4ED8C1804DD979E2B13A97029CFCB3F1F96F28CE43318560F8400E2CAA5D80270FA1C90099D3D41BE00DD00010B893132108002131662342D91AFCA6330001073EA2E0054BC098804B5C00CC667B79727FF646267FA9E3971C96E71E8C00D911A9C738EC401A6CBEA33BC09B8015697BB7CD746E4A9FD4BB5613004BC01598EEE96EF755149B9A049D80480230C0041E514A51467D226E692801F049F73287F7AC29CB453E4B1FDE1F624100203368B3670200C46E93D13CAD11A6673B63A42600C00021119E304271006A30C3B844200E45F8A306C8037C9CA6FF850B004A459672B5C4E66A80090CC4F31E1D80193E60068801EC056498012804C58011BEC0414A00EF46005880162006800A3460073007B620070801E801073002B2C0055CEE9BC801DC9F5B913587D2C90600E4D93CE1A4DB51007E7399B066802339EEC65F519CF7632FAB900A45398C4A45B401AB8803506A2E4300004262AC13866401434D984CA4490ACA81CC0FB008B93764F9A8AE4F7ABED6B293330D46B7969998021C9EEF67C97BAC122822017C1C9FA0745B930D9C480 diff --git a/Sources/Runner/Resources/input/16_test.txt b/Sources/Runner/Resources/input/16_test.txt new file mode 100644 index 0000000..a7f8f25 --- /dev/null +++ b/Sources/Runner/Resources/input/16_test.txt @@ -0,0 +1 @@ +38006F45291200