这是@AMomchilov's 的替代版本,rot13
它使用 aswitch
和更少的数学并消除了幻数:
func rot13(_ unicodeScalar: UnicodeScalar) -> Character {
var result = unicodeScalar.value
switch unicodeScalar {
case "A"..."M", "a"..."m":
result += 13
case "N"..."Z", "n"..."z":
result -= 13
default:
break
}
return Character(UnicodeScalar(result)!)
}
func rot13(_ input: String) -> String {
return String(input.unicodeScalars.map(rot13))
}
print(rot13("Uryyb, jbeyq!")) // "Hello, world!"
泛化到 rotN
我采用了rot13
上面的函数并将它们概括为rotN
通过让它们采用ClosedRange<UnicodeScalar>
. 这允许您以非常直接的方式实现rot13
、rot47
、和和rot5
的组合。rot13
rot5
func rotN(_ unicodeScalar: UnicodeScalar, intervals:[ClosedRange<UnicodeScalar>]) -> Character {
var result = unicodeScalar.value
for interval in intervals {
let half = (interval.upperBound.value - interval.lowerBound.value + 1) / 2
let halfway = UnicodeScalar(interval.lowerBound.value + half)!
switch unicodeScalar {
case interval.lowerBound..<halfway:
result += half
case halfway...interval.upperBound:
result -= half
default:
break
}
}
return Character(UnicodeScalar(result)!)
}
func rotN(_ input: String, intervals:[ClosedRange<UnicodeScalar>]) -> String {
return String(input.unicodeScalars.map {rotN($0, intervals: intervals)})
}
func rot13(_ input: String) -> String {
return rotN(input, intervals:["A"..."Z", "a"..."z"])
}
func rot47(_ input: String) -> String {
return rotN(input, intervals:["!"..."~"])
}
func rot5(_ input: String) -> String {
return rotN(input, intervals:["0"..."9"])
}
func rot13and5(_ input: String) -> String {
return rotN(input, intervals:["A"..."Z", "a"..."z", "0"..."9"])
}
print(rot13("Uryyb, jbeyq!")) // "Hello, world!"
print(rot47("%96 BF:4< 3C@H? 7@I")) // "The quick brown fox"
print(rot5("6 + 7 = 8")) // "1 + 2 = 3"
print(rot13and5("Whyl 9, 6221")) // "July 4, 1776"
这是rotN
基于@AMomchilov's
原始版本的版本rot13
:
func rotN(_ unicodeScalar: UnicodeScalar, intervals:[ClosedRange<UnicodeScalar>]) -> UnicodeScalar {
var result = unicodeScalar.value
for interval in intervals {
let start = interval.lowerBound.value
let length = interval.upperBound.value - start + 1
if interval ~= unicodeScalar {
result = (result + length/2 - start) % length + start
}
}
return UnicodeScalar(result)!
}
func rotN(_ input: String, intervals:[ClosedRange<UnicodeScalar>]) -> String {
return String(input.unicodeScalars.map {Character(rotN($0, intervals:intervals))})
}