// // File.swift // // // Created by Max Nuding on 14.12.21. // import Foundation import Runner struct Replacement { let from: String let to: String init(line: String) { let r = line.components(separatedBy: " -> ") from = r.first! to = r.last! } func replace(pair: String) -> String.Element? { pair == from ? to.first : nil } } 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: [String:String](), { p, c in p[c.first!] = c.last! }) var pairCounts = [String:Int]() for i in startingPolymer.indices { let next = startingPolymer.index(i, offsetBy: 1) guard next != startingPolymer.endIndex else { continue } let pair = "\(startingPolymer[i])\(startingPolymer[next])" pairCounts[pair, 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 let firstCharacter = pair.first! let secondCharacter = pair.last! pairCounts["\(firstCharacter)\(replacement)", default: 0] += pairCount.value pairCounts["\(replacement)\(secondCharacter)", default: 0] += pairCount.value charCount[replacement.first!, default: 0] += pairCount.value } if step == 10 { printResult(charCount: charCount) } } printResult(charCount: charCount) } func printResult(charCount: [String.Element:Int]) { let maxC = charCount.max(by: {$0.value < $1.value })! let minC = charCount.min(by: {$0.value < $1.value })! print(maxC.value - minC.value) } }