80 lines
1.9 KiB
Swift
80 lines
1.9 KiB
Swift
extension String {
|
|
func increment() -> String {
|
|
var ascii = map { $0.asciiValue! }
|
|
|
|
var carry: UInt8 = 0
|
|
for index in ascii.indices.reversed() {
|
|
let next = ascii[index] + 1
|
|
if next > UInt8(ascii: "z") {
|
|
carry = 1
|
|
ascii[index] = UInt8(ascii: "a")
|
|
} else {
|
|
ascii[index] = next
|
|
carry = 0
|
|
}
|
|
|
|
if carry == 0 {
|
|
break
|
|
}
|
|
}
|
|
|
|
if carry != 0 {
|
|
ascii.insert(UInt8(ascii: "a") + carry - 1, at: 0)
|
|
}
|
|
|
|
return String(ascii.map { Character(UnicodeScalar($0)) })
|
|
}
|
|
|
|
var isValid: Bool {
|
|
containsStraight &&
|
|
!containsForbidden &&
|
|
containsTwoPair
|
|
}
|
|
|
|
var containsForbidden: Bool {
|
|
contains { $0 == "i" || $0 == "o" || $0 == "l" }
|
|
}
|
|
|
|
var containsStraight: Bool {
|
|
for i in indices.dropLast(2) {
|
|
let next = index(after: i)
|
|
let next2 = index(after: next)
|
|
|
|
let value = self.unicodeScalars[i].value
|
|
let value2 = UnicodeScalar(value + 1)
|
|
let value3 = UnicodeScalar(value + 2)
|
|
|
|
if self.unicodeScalars[next] == value2 && self.unicodeScalars[next2] == value3 {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
var containsTwoPair: Bool {
|
|
var firstPair: Character? = nil
|
|
for i in indices.dropLast() {
|
|
let next = index(after: i)
|
|
|
|
guard self[i] == self[next] else { continue }
|
|
|
|
if firstPair == nil {
|
|
firstPair = self[i]
|
|
} else if firstPair != self[i] {
|
|
return true
|
|
}
|
|
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
let start = "hxbxwxba"
|
|
|
|
var password = start
|
|
repeat {
|
|
password = password.increment()
|
|
} while !password.isValid
|
|
password
|
|
|