// // File.swift // // // Created by Max Nuding on 14.12.21. // import Foundation import Runner struct Pair: Hashable { let first: String.Element let second: String.Element init(_ str: String) { first = str.first! second = str.last! } init(first: String.Element, second: String.Element) { self.first = first self.second = second } } class Day14: Runnable { let inputPath: String required init(inputPath: String) { self.inputPath = inputPath } public func run() { let input = try! String(contentsOfFile: inputPath) let parts = input .trimmingCharacters(in: .newlines) .components(separatedBy: "\n\n") let startingPolymer = parts.first! let replacements = parts.last! .components(separatedBy: .newlines) .map {$0.components(separatedBy: " -> ")} .reduce(into: [Pair:String.Element](), { $0[Pair($1.first!)] = $1.last!.first! }) var pairCounts = [Pair:Int]() var charCount = [String.Element:Int](minimumCapacity: 26) for i in startingPolymer.indices { let firstCharacter = startingPolymer[i] charCount[firstCharacter, default: 0] += 1 let next = startingPolymer.index(i, offsetBy: 1) guard next != startingPolymer.endIndex else { continue } pairCounts[Pair(first: firstCharacter, second: startingPolymer[next]), default: 0] += 1 } for step in 1...40 { let tmpPairCounts = pairCounts tmpPairCounts.forEach { pairCount in let pair = pairCount.key let replacement = replacements[pair]! pairCounts[pair]! -= pairCount.value pairCounts[Pair(first: pair.first, second: replacement), default: 0] += pairCount.value pairCounts[Pair(first: replacement, second: pair.second), default: 0] += pairCount.value charCount[replacement, default: 0] += pairCount.value } if step == 10 { printResult(charCount: charCount) } } printResult(charCount: charCount) } func printResult(charCount: [String.Element:Int]) { // Sort instead of min/max so we need to only go through the dict once let sorted = charCount.sorted(by: {$0.value > $1.value }) let maxC = sorted.first! let minC = sorted.last! print(maxC.value - minC.value) } }