-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay11.swift
More file actions
70 lines (56 loc) · 1.58 KB
/
Copy pathDay11.swift
File metadata and controls
70 lines (56 loc) · 1.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import AoCCommon
import Foundation
struct Day11: AdventDay, Sendable {
let data: String
let day = 11
let puzzleName: String = "--- Day 11: Plutonian Pebbles ---"
init(data: String) {
self.data = data
}
var stoneDictionary: [Int: Int] {
do {
let numbers = try NumberLine(separator: " ").parse(data)
return Dictionary(grouping: numbers, by: { $0 }).mapValues(\.count)
} catch {
fatalError("Could not parse input \(error)")
}
}
func part1() async throws -> Int {
stepper(stoneDictionary, blinks: 25)
}
func part2() async throws -> Int {
stepper(stoneDictionary, blinks: 75)
}
}
extension Day11 {
func stepper(_ dict: [Int: Int], blinks: Int) -> Int {
var dict = dict
for _ in 0 ..< blinks {
dict = step(dict)
}
return dict.values.reduce(0, +)
}
func step(_ dict: [Int: Int]) -> [Int: Int] {
var keys = dict.keys.filter { $0 != 0 }.map { ($0, String($0)) }
let partitionIndex = keys.partition { $0.1.count % 2 == 1 }
var accum = [Int: Int]()
if let zeroes = dict[0] {
accum[1] = zeroes
}
// even length keys
for pair in keys[0 ..< partitionIndex] {
let (key, strKey) = pair
let count = dict[key]!
let midpoint = strKey.count / 2
accum[Int(strKey.prefix(midpoint))!, default: 0] += count
accum[Int(strKey.suffix(midpoint))!, default: 0] += count
}
for pair in keys[partitionIndex ..< keys.count] {
let key = pair.0
let newKey = key * 2024
let value = dict[key]!
accum[newKey, default: 0] += value
}
return accum
}
}