generated from swiftlang/swift-aoc-starter-example
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Y2023Day01.swift
61 lines (44 loc) · 1.99 KB
/
Y2023Day01.swift
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
import Foundation
struct Y2023Day01: AdventDay {
var data: String
func part1() -> Any {
var numbers: [Int] = []
for line in data.components(separatedBy: .newlines) {
guard !line.isEmpty else { continue }
guard let firstNumber = line.first(where: \.isNumber),
let lastNumber = line.reversed().first(where: \.isNumber),
let number = try? 10 * firstNumber.toInteger() + lastNumber.toInteger()
else { fatalError() }
numbers.append(number)
}
return numbers.reduce(into: 0) { $0 += $1 }
}
func part2() -> Any {
let spelledOutNumbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
let reversedSpelledOutNumbers = spelledOutNumbers.map { String($0.reversed()) }
var numbers: [Int] = []
for line in data.components(separatedBy: .newlines) {
guard !line.isEmpty else { continue }
let firstNumber = self.firstNumber(in: line, spelledOutNumbers: spelledOutNumbers)
let lastNumber = self.firstNumber(in: String(line.reversed()), spelledOutNumbers: reversedSpelledOutNumbers)
let number = 10 * firstNumber + lastNumber
numbers.append(number)
}
return numbers.reduce(into: 0) { $0 += $1 }
}
private func firstNumber(in line: String, spelledOutNumbers: [String]) -> Int {
var number = 0
for (index, char) in line.enumerated() {
if let value = try? char.toInteger() {
number = value
break
}
let subSequence = line.dropFirst(index)
if let index = spelledOutNumbers.firstIndex(where: { subSequence.hasPrefix($0) }) {
number = index + 1
break
}
}
return number
}
}