aoc2021/Sources/14/14.swift
2021-12-14 20:31:09 +01:00

83 lines
2.6 KiB
Swift

//
// 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)
}
}