16a
This commit is contained in:
parent
c7e8bf103e
commit
e70e71b068
@ -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")]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
184
Sources/16/16.swift
Normal file
184
Sources/16/16.swift
Normal file
@ -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..<bytes.index(bytes.startIndex, offsetBy: 3)].description.binaryToDecimal()
|
||||
let typeId = bytes[bytes.index(bytes.startIndex, offsetBy: 3)..<bytes.index(bytes.startIndex, offsetBy: 6)].description
|
||||
var value: Packet
|
||||
var reminder: String
|
||||
switch typeId {
|
||||
case "100":
|
||||
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)
|
||||
reminder = r
|
||||
}
|
||||
return (value, reminder)
|
||||
}
|
||||
|
||||
func parseOperatorPacker(bytes: String) -> ([Packet], String) {
|
||||
let startNextBitsIndex = bytes.index(bytes.startIndex, offsetBy: 7)
|
||||
let lengthTypeId = bytes[bytes.index(bytes.startIndex, offsetBy: 6)..<startNextBitsIndex].description
|
||||
let isTotalLength = lengthTypeId == "0"
|
||||
|
||||
let nextBitsLength = isTotalLength ? 15 : 11
|
||||
let endNextBitsIndex = bytes.index(startNextBitsIndex, offsetBy: nextBitsLength)
|
||||
let nextBits = bytes[startNextBitsIndex..<endNextBitsIndex].description
|
||||
|
||||
var number = nextBits.binaryToDecimal()
|
||||
var reminder = bytes[endNextBitsIndex...].description
|
||||
var subPackets = [Packet]()
|
||||
|
||||
while number > 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..<ei].description
|
||||
if bytes[index] == "0" {
|
||||
reminder = bytes[ei...].description
|
||||
break
|
||||
}
|
||||
index = bytes.index(ei, offsetBy: 0)
|
||||
}
|
||||
return (bits.binaryToDecimal(), reminder)
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
func ToBinary() -> [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}
|
||||
}
|
||||
}
|
12
Sources/16/main.swift
Normal file
12
Sources/16/main.swift
Normal file
@ -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()
|
1
Sources/Runner/Resources/input/16.txt
Normal file
1
Sources/Runner/Resources/input/16.txt
Normal file
@ -0,0 +1 @@
|
||||
020D708041258C0B4C683E61F674A1401595CC3DE669AC4FB7BEFEE840182CDF033401296F44367F938371802D2CC9801A980021304609C431007239C2C860400F7C36B005E446A44662A2805925FF96CBCE0033C5736D13D9CFCDC001C89BF57505799C0D1802D2639801A900021105A3A43C1007A1EC368A72D86130057401782F25B9054B94B003013EDF34133218A00D4A6F1985624B331FE359C354F7EB64A8524027D4DEB785CA00D540010D8E9132270803F1CA1D416200FDAC01697DCEB43D9DC5F6B7239CCA7557200986C013912598FF0BE4DFCC012C0091E7EFFA6E44123CE74624FBA01001328C01C8FF06E0A9803D1FA3343E3007A1641684C600B47DE009024ED7DD9564ED7DD940C017A00AF26654F76B5C62C65295B1B4ED8C1804DD979E2B13A97029CFCB3F1F96F28CE43318560F8400E2CAA5D80270FA1C90099D3D41BE00DD00010B893132108002131662342D91AFCA6330001073EA2E0054BC098804B5C00CC667B79727FF646267FA9E3971C96E71E8C00D911A9C738EC401A6CBEA33BC09B8015697BB7CD746E4A9FD4BB5613004BC01598EEE96EF755149B9A049D80480230C0041E514A51467D226E692801F049F73287F7AC29CB453E4B1FDE1F624100203368B3670200C46E93D13CAD11A6673B63A42600C00021119E304271006A30C3B844200E45F8A306C8037C9CA6FF850B004A459672B5C4E66A80090CC4F31E1D80193E60068801EC056498012804C58011BEC0414A00EF46005880162006800A3460073007B620070801E801073002B2C0055CEE9BC801DC9F5B913587D2C90600E4D93CE1A4DB51007E7399B066802339EEC65F519CF7632FAB900A45398C4A45B401AB8803506A2E4300004262AC13866401434D984CA4490ACA81CC0FB008B93764F9A8AE4F7ABED6B293330D46B7969998021C9EEF67C97BAC122822017C1C9FA0745B930D9C480
|
1
Sources/Runner/Resources/input/16_test.txt
Normal file
1
Sources/Runner/Resources/input/16_test.txt
Normal file
@ -0,0 +1 @@
|
||||
38006F45291200
|
Loading…
Reference in New Issue
Block a user