// // 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") var startingPolymer = parts.first! let replacements = parts.last! .components(separatedBy: .newlines) .map(Replacement.init) for step in 1...10 { var inserts = [(String.Index, Character)]() for i in startingPolymer.indices { let next = startingPolymer.index(i, offsetBy: 1) guard next != startingPolymer.endIndex else { continue } var pair = startingPolymer[i]/* + startingPolymer[next]*/ let p = "\(startingPolymer[i])\(startingPolymer[next])" for replacement in replacements { if let c = replacement.replace(pair: p) { inserts.append((next, c)) break } } } var tmp = startingPolymer var count = 0 for r in inserts { let idx = tmp.index(r.0, offsetBy: count) tmp.insert(r.1, at: idx) count += 1 } startingPolymer = tmp } let charCounts = startingPolymer.reduce(into: [String.Element: Int](), { $0[$1, default: 0] += 1 }) let maxC = charCounts.max(by: {$0.value < $1.value })! let minC = charCounts.min(by: {$0.value < $1.value })! print(maxC.value - minC.value) } }