Switched from string fiddling to actual character pairs

This commit is contained in:
Max Nuding 2021-12-14 20:13:34 +01:00
parent dac98f99b5
commit 40053ef992
Signed by: phlaym
GPG Key ID: A06651BAB6777237

View File

@ -8,17 +8,19 @@
import Foundation import Foundation
import Runner import Runner
struct Replacement { struct Pair: Hashable {
let from: String let first: String.Element
let to: String let second: String.Element
init(line: String) { init(_ str: String) {
let r = line.components(separatedBy: " -> ") first = str.first!
from = r.first! second = str.last!
to = r.last!
} }
func replace(pair: String) -> String.Element? { pair == from ? to.first : nil } init(first: String.Element, second: String.Element) {
self.first = first
self.second = second
}
} }
class Day14: Runnable { class Day14: Runnable {
@ -37,18 +39,17 @@ class Day14: Runnable {
let replacements = parts.last! let replacements = parts.last!
.components(separatedBy: .newlines) .components(separatedBy: .newlines)
.map {$0.components(separatedBy: " -> ")} .map {$0.components(separatedBy: " -> ")}
.reduce(into: [String:String](), { p, c in .reduce(into: [Pair:String.Element](), {
p[c.first!] = c.last! $0[Pair($1.first!)] = $1.last!.first!
}) })
var pairCounts = [String:Int]() var pairCounts = [Pair:Int]()
for i in startingPolymer.indices { for i in startingPolymer.indices {
let next = startingPolymer.index(i, offsetBy: 1) let next = startingPolymer.index(i, offsetBy: 1)
guard next != startingPolymer.endIndex else { guard next != startingPolymer.endIndex else {
continue continue
} }
let pair = "\(startingPolymer[i])\(startingPolymer[next])" pairCounts[Pair(first: startingPolymer[i], second: startingPolymer[next]), default: 0] += 1
pairCounts[pair, default: 0] += 1
} }
var charCount = startingPolymer.reduce(into: [String.Element:Int](), { var charCount = startingPolymer.reduce(into: [String.Element:Int](), {
$0[$1, default: 0] += 1 $0[$1, default: 0] += 1
@ -56,15 +57,14 @@ class Day14: Runnable {
for step in 1...40 { for step in 1...40 {
let tmpPairCounts = pairCounts let tmpPairCounts = pairCounts
for pairCount in tmpPairCounts { for pairCount in tmpPairCounts {
let pair = pairCount.key let pair = pairCount.key
let replacement = replacements[pair]! let replacement = replacements[pair]!
pairCounts[pair]! -= pairCount.value pairCounts[pair]! -= pairCount.value
let firstCharacter = pair.first! pairCounts[Pair(first: pair.first, second: replacement), default: 0] += pairCount.value
let secondCharacter = pair.last! pairCounts[Pair(first: replacement, second: pair.second), default: 0] += pairCount.value
pairCounts["\(firstCharacter)\(replacement)", default: 0] += pairCount.value charCount[replacement, default: 0] += pairCount.value
pairCounts["\(replacement)\(secondCharacter)", default: 0] += pairCount.value
charCount[replacement.first!, default: 0] += pairCount.value
} }
if step == 10 { if step == 10 {
printResult(charCount: charCount) printResult(charCount: charCount)
@ -74,8 +74,10 @@ class Day14: Runnable {
} }
func printResult(charCount: [String.Element:Int]) { func printResult(charCount: [String.Element:Int]) {
let maxC = charCount.max(by: {$0.value < $1.value })! // Sort instead of min/max so we need to only go through the dict once
let minC = charCount.min(by: {$0.value < $1.value })! let sorted = charCount.sorted(by: {$0.value > $1.value })
let maxC = sorted.first!
let minC = sorted.last!
print(maxC.value - minC.value) print(maxC.value - minC.value)
} }
} }