82 lines
2.5 KiB
Swift
82 lines
2.5 KiB
Swift
//
|
|
// 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)
|
|
}
|
|
}
|