// // 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]() for i in startingPolymer.indices { let next = startingPolymer.index(i, offsetBy: 1) guard next != startingPolymer.endIndex else { continue } pairCounts[Pair(first: startingPolymer[i], second: startingPolymer[next]), default: 0] += 1 } var charCount = startingPolymer.reduce(into: [String.Element:Int](), { $0[$1, default: 0] += 1 }) for step in 1...40 { let tmpPairCounts = pairCounts for pairCount in tmpPairCounts { 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) } }