-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay4.swift
131 lines (116 loc) · 4.34 KB
/
Day4.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
let puzzleInput = "197487-673251"
import Foundation
struct PasswordRange {
let begin: Int
let end: Int
}
func populateRange(input: String) -> PasswordRange? {
let range = input.split { $0.isPunctuation }
if range.count == 2 {
if let rangeBegin = Int(range[0]) {
if let rangeEnd = Int(range[1]) {
return PasswordRange(begin: rangeBegin, end: rangeEnd)
}
}
}
return nil
}
func ensureSixDigits(input: Int) -> Bool {
// It is a six-digit number.
let password = String(input)
return password.count == 6
}
func ensureAdjacentDigits(input: Int) -> Bool {
// Two adjacent digits are the same (like 22 in 122345).
let password = String(input)
return password.range(of: #"(\d)\1+"#, options: .regularExpression) != nil
}
func ensureNoDecrease(input: Int) -> Bool {
let password = String(input)
// Going from left to right, the digits never decrease; they only ever increase or stay the same (like 111123 or 135679).
var passwordOK = false
for i in 0 ..< password.count - 1 {
let currentIndex = password.index(password.startIndex, offsetBy: i)
let nextIndex = password.index(password.startIndex, offsetBy: i + 1)
let currentValue = String(password[currentIndex])
let nextValue = String(password[nextIndex])
if let currentInt = Int(currentValue) {
if let nextInt = Int(nextValue) {
if currentInt <= nextInt {
passwordOK = true
} else {
passwordOK = false
break
}
}
}
}
return passwordOK
}
func ensureOnlyTwoAdjacentDigits(input: Int) -> Bool {
let password = String(input)
var passwordOK = false
for i in 0 ... password.count - 3 {
let currentIndex = password.index(password.startIndex, offsetBy: i)
let nextIndex = password.index(password.startIndex, offsetBy: i + 1)
let finalIndex = password.index(password.startIndex, offsetBy: i + 2)
let currentValue = String(password[currentIndex])
let nextValue = String(password[nextIndex])
let finalValue = String(password[finalIndex])
if let currentInt = Int(currentValue) {
if let nextInt = Int(nextValue) {
if let finalInt = Int(finalValue) {
if i == 0 {
if currentInt == nextInt && finalInt != currentInt {
passwordOK = true
break
}
} else if i == password.count - 3 {
if(nextInt == finalInt && currentInt != finalInt) {
passwordOK = true
break
}
}
if i > 0 {
if currentInt == nextInt {
let previousIndex = password.index(password.startIndex, offsetBy: i - 1)
let previousValue = String(password[previousIndex])
if let previousInt = Int(previousValue) {
if previousInt != currentInt && finalInt != currentInt {
passwordOK = true
break
}
}
}
}
}
}
}
}
return passwordOK
}
if let passwordRange = populateRange(input: puzzleInput) {
var passwordCountPartOne = 0
// Within the range, exclude begin and end
for i in passwordRange.begin + 1 ..< passwordRange.end {
if (ensureSixDigits(input: i)) {
if (ensureAdjacentDigits(input: i)) {
if (ensureNoDecrease(input: i)) {
passwordCountPartOne += 1
}
}
}
}
print(passwordCountPartOne)
var passwordCountPartTwo = 0
for i in passwordRange.begin + 1 ..< passwordRange.end {
if (ensureSixDigits(input: i)) {
if (ensureOnlyTwoAdjacentDigits(input: i)) {
if (ensureNoDecrease(input: i)) {
passwordCountPartTwo += 1
}
}
}
}
print(passwordCountPartTwo)
}