How do I perform a circular shift in Swift? - swift

I am trying to perform a circular shift in Swift and I currently have the following code which uses a string containing the bits of the number I am trying to perform the circular shift on. Here is the code I have so far,
func circularRightShift(_ input: UInt8, _ amount: UInt8) -> UInt8 {
guard amount > 0 else { return input }
var a = String(UInt("\(input)")!, radix: 2)
if a.count != 8 {
a = "".padding(toLength: 8-a.count, withPad: "0", startingAt: 0) + a
}
for _ in 1...amount {
a.insert(a.last!, at: a.startIndex)
a.removeLast()
}
return UInt8(a, radix: 2)!
}
This code works properly, but it's a bit slow. Is there any better way to achieve this, possibly without using a string? Thanks in advance.

You can achieve this with two bit shift operators and a bitwise OR:
func circularRightShift(_ input: UInt8, _ amount: UInt8) -> UInt8 {
let amount = amount % 8 // Reduce to the range 0...7
return (input >> amount) | (input << (8 - amount))
}
Example (amount=5):
abcdefgh <- bits of input
00000abc <- bits of input >> amount
defgh000 <- bits of input << (8 - amount)
defghabc <- bits of result

Another, more general answer is this:
func circularShift<ShiftType: BinaryInteger>(_ first: ShiftType, by shiftAmount: Int) -> ShiftType {
(first << shiftAmount) | (first >> (first.bitWidth - shiftAmount))
}
You can also create an extension:
extension BinaryInteger {
func circularShifted(by shiftAmount: Int) -> Self {
(self << shiftAmount) | (self >> (self.bitWidth - shiftAmount))
}
}
To be even more flexible, you can take the sign of the operation into account and differentiate between left and right shifting:
extension BinaryInteger where Self: UnsignedInteger {
func rotateLeft(by shiftAmount: Int) -> Self {
if shiftAmount < 0 {
return rotateRight(by: -shiftAmount)
}
return (self << shiftAmount) | (self >> (self.bitWidth - shiftAmount))
}
func rotateRight(by shiftAmount: Int) -> Self {
if shiftAmount < 0 {
return rotateLeft(by: -shiftAmount)
}
return (self >> shiftAmount) | (self << (self.bitWidth - shiftAmount))
}
}
which can then be used like
let x: UInt8 = 0xE
String(x.rotateLeft(by: 2), radix: 16) // 3A
String(x.rotateRight(by: 2), radix: 16) // A3

One approach is to shift your number as 16-bits, and then combine the two bytes with each other, like this:
func circular(n: UInt8, k: UInt8) -> UInt8 {
var s = UInt16(n) << (k & 0x07)
return UInt8(s & 0xFF) | UInt8(s >> 8)
}
Demo

Related

Can't sort array: "Ambiguous reference to member '<'"

extension Array where Element: Numeric {
func closest(to givenValue: Element) -> Element {
let sorted = self.sorted(by: <)
let over = sorted.first(where: { $0 >= givenValue })!
let under = sorted.last(where: { $0 <= givenValue })!
let diffOver = over - givenValue
let diffUnder = givenValue - under
return (diffOver < diffUnder) ? over : under
}
}
In line 3 of this example code, Xcode gives me the incomprehensible error message Ambiguous reference to member '<', along with this great list:
What am I supposed to do here? I just want this array to get sorted.
You have to declare Element to be Comparable:
extension Array where Element: Numeric & Comparable {
In
let sorted = self.sorted(by: <)
you're not giving a boolean function for the function to use. Maybe try replacing it with :
let sorted = self.sorted(by: { $0 < $1 })
Problem is that you have defined your Element as Numeric only where > will work with Comparable.
Do it as:
extension Array where Element: Numeric, Element: Comparable {
func closest(to givenValue: Element) -> Element {
//... your code here ...
}
}
I was just running into a similar problem stemming from the type inference when chaining multiple higher order functions (sort, map, etc), when I found this post and I couldn't help but notice the inefficiency of your function.
Here is an example of how you can implement this same function using binary search, massively reducing the time it takes to execute on large datasets:
extension Array where Element: Numeric & Comparable {
func closest2(to target: Element) -> Element {
if target <= self[0] {
return self[0]
}
if target >= self[count - 1] {
return self[count - 1]
}
var i = 0
var j = count
var mid = 0
while i < j {
mid = (i + j) / 2
if self[mid] == target {
return self[mid]
}
if target < self[mid] {
if mid > 0 && target > self[mid - 1] {
return getClosest(val1: self[mid - 1], val2: self[mid], target: target)
}
j = mid
} else {
if mid < count - 1 && target < self[mid + 1] {
return getClosest(val1: self[mid], val2: self[mid + 1], target: target)
}
i = mid + 1
}
}
return self[mid]
}
private func getClosest(val1: Element, val2: Element, target: Element) -> Element {
return target - val1 > val2 - target ? val2 : val1
}
}

How to execute multiplications and/or divisions in the right order?

I am doing a simple calculator, but when performing the multiplication and division, my code doesn't make them a priority over plus and minus.
When doing -> 2 + 2 * 4, result = 16 instead of 10...
How to conform to the math logic inside my switch statement?
mutating func calculateTotal() -> Double {
var total: Double = 0
for (i, stringNumber) in stringNumbers.enumerated() {
if let number = Double(stringNumber) {
switch operators[i] {
case "+":
total += number
case "-":
total -= number
case "÷":
total /= number
case "×":
total *= number
default:
break
}
}
}
clear()
return total
}
Assuming you want a generalised and perhaps extensible algorithm for any arithmetic expression, the right way to do this is to use the Shunting Yard algorithm.
You have an input stream, which is the numbers and operators as the user typed them in and you have an output stream, which is the same numbers and operators but rearranged into reverse Polish notation. So, for example 2 + 2 * 4 would be transformed into 2 2 4 * + which is easily calculated by putting the numbers on a stack as you read them and applying the operators to the top items on the stack as you read them.
To do this the algorithm has an operator stack which can be visualised as a siding (hence "shunting yard") into which low priority operators are shunted until they are needed.
The general algorithm is
read an item from the input
if it is a number send it to the output
if the number is an operator then
while the operator on the top of the stack is of higher precedence than the operator you have pop the operator on the stack and send it to the output
push the operator you read from input onto the stack
repeat the above until the input is empty
pop all the operators on the stack into the output
So if you have 2 + 2 * 4 (NB top of the stack is on the left, bottom of the stack is on the right)
start:
input: 2 + 2 * 4
output: <empty>
stack: <empty>
step 1: send the 2 to output
input: + 2 * 4
output: 2
stack: <empty>
step 2: stack is empty so put + on the stack
input: 2 * 4
output: 2
stack: +
step 3: send the 2 to output
input: * 4
output: 2 2
stack: +
step 4: + is lower priority than * so just put * on the stack
input: 4
output: 2 2
stack: * +
step 5: Send 4 to output
input:
output: 2 2 4
stack: * +
step 6: Input is empty so pop the stack to output
input:
output: 2 2 4 * +
stack:
The Wikipedia entry I linked above has a more detailed description and an algorithm that can handle parentheses and function calls and is much more extensible.
For completeness, here is an implementation of my simplified version of the algorithm
enum Token: CustomStringConvertible
{
var description: String
{
switch self
{
case .number(let num):
return "\(num)"
case .op(let symbol):
return "\(symbol)"
}
}
case op(String)
case number(Int)
var precedence: Int
{
switch self
{
case .op(let symbol):
return Token.precedences[symbol] ?? -1
default:
return -1
}
}
var operation: (inout Stack<Int>) -> ()
{
switch self
{
case .op(let symbol):
return Token.operations[symbol]!
case .number(let value):
return { $0.push(value) }
}
}
static let precedences = [ "+" : 10, "-" : 10, "*" : 20, "/" : 20]
static let operations: [String : (inout Stack<Int>) -> ()] =
[
"+" : { $0.push($0.pop() + $0.pop()) },
"-" : { $0.push($0.pop() - $0.pop()) },
"*" : { $0.push($0.pop() * $0.pop()) },
"/" : { $0.push($0.pop() / $0.pop()) }
]
}
struct Stack<T>
{
var values: [T] = []
var isEmpty: Bool { return values.isEmpty }
mutating func push(_ n: T)
{
values.append(n)
}
mutating func pop() -> T
{
return values.removeLast()
}
func peek() -> T
{
return values.last!
}
}
func shuntingYard(input: [Token]) -> [Token]
{
var operatorStack = Stack<Token>()
var output: [Token] = []
for token in input
{
switch token
{
case .number:
output.append(token)
case .op:
while !operatorStack.isEmpty && operatorStack.peek().precedence >= token.precedence
{
output.append(operatorStack.pop())
}
operatorStack.push(token)
}
}
while !operatorStack.isEmpty
{
output.append(operatorStack.pop())
}
return output
}
let input: [Token] = [ .number(2), .op("+"), .number(2), .op("*"), .number(4)]
let output = shuntingYard(input: input)
print("\(output)")
var dataStack = Stack<Int>()
for token in output
{
token.operation(&dataStack)
}
print(dataStack.pop())
If you only have the four operations +, -, x, and ÷, you can do this by keeping track of a pendingOperand and pendingOperation whenever you encounter a + or -.
Then compute the pending operation when you encounter another + or -, or at the end of the calculation. Note that + or - computes the pending operation, but then immediately starts a new one.
I have modified your function to take the stringNumbers, operators, and initial values as input so that it could be tested independently in a Playground.
func calculateTotal(stringNumbers: [String], operators: [String], initial: Double) -> Double {
func performPendingOperation(operand: Double, operation: String, total: Double) -> Double {
switch operation {
case "+":
return operand + total
case "-":
return operand - total
default:
return total
}
}
var total = initial
var pendingOperand = 0.0
var pendingOperation = ""
for (i, stringNumber) in stringNumbers.enumerated() {
if let number = Double(stringNumber) {
switch operators[i] {
case "+":
total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total)
pendingOperand = total
pendingOperation = "+"
total = number
case "-":
total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total)
pendingOperand = total
pendingOperation = "-"
total = number
case "÷":
total /= number
case "×":
total *= number
default:
break
}
}
}
// Perform final pending operation if needed
total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total)
// clear()
return total
}
Tests:
// 4 + 3
calculateTotal(stringNumbers: ["3"], operators: ["+"], initial: 4)
7
// 4 × 3
calculateTotal(stringNumbers: ["3"], operators: ["×"], initial: 4)
12
// 2 + 2 × 4
calculateTotal(stringNumbers: ["2", "4"], operators: ["+", "×"], initial: 2)
10
// 2 × 2 + 4
calculateTotal(stringNumbers: ["2", "4"], operators: ["×", "+"], initial: 2)
8
// 17 - 2 × 3 + 10 + 7 ÷ 7
calculateTotal(stringNumbers: ["2", "3", "10", "7", "7"], operators: ["-", "×", "+", "+", "÷"], initial: 17)
22
First you have to search in the array to see if there is a ÷ or × sign.
Than you can just sum or subtract.
mutating func calculateTotal() -> Double {
var total: Double = 0
for (i, stringNumber) in stringNumbers.enumerated() {
if let number = Double(stringNumber) {
switch operators[i] {
case "÷":
total /= number
case "×":
total *= number
default:
break
}
//Remove the number from the array and make another for loop with the sum and subtract operations.
}
}
clear()
return total
}
This will work if you are not using complex numbers.
If you don't care speed, as it's running by a computer and you may use the machine way to handle it. Just pick one feasible calculate to do it and then repeat until every one is calculated.
Just for fun here. I use some stupid variable and function names.
func evaluate(_ values: [String]) -> String{
switch values[1] {
case "+": return String(Int(values[0])! + Int(values[2])!)
case "-": return String(Int(values[0])! - Int(values[2])!)
case "×": return String(Int(values[0])! * Int(values[2])!)
case "÷": return String(Int(values[0])! / Int(values[2])!)
default: break;
}
return "";
}
func oneTime(_ string: inout String, _ strings: [String]) throws{
if let first = try NSRegularExpression(pattern: "(\\d+)\\s*(\(strings.map{"\\\($0)"}.joined(separator: "|")))\\s*(\\d+)", options: []).firstMatch(in: string , options: [], range: NSMakeRange(0, string.count)) {
let tempResult = evaluate((1...3).map{ (string as NSString).substring(with: first.range(at: $0))})
string.replaceSubrange( Range(first.range(at: 0), in: string)! , with: tempResult)
}
}
func recursive(_ string: inout String, _ strings: [String]) throws{
var count : Int!
repeat{ count = string.count ; try oneTime(&string, strings)
} while (count != string.count)
}
func final(_ string: inout String, _ strings: [[String]]) throws -> String{
return try strings.reduce(into: string) { (result, signs) in
try recursive(&string, signs)
}}
var string = "17 - 23 + 10 + 7 ÷ 7"
try final(&string, [["×","÷"],["+","-"]])
print("result:" + string)
Using JeremyP method and the Shunting Yard algorithm was the way that worked for me, but I had some differences that had to do with the Operator Associativity(left or right priority) so I had to work with it and I developed the code, which is based on JeremyP answer but uses arrays.
First we have the array with the calculation in Strings, e.g.:
let testArray = ["10","+", "5", "*" , "4", "+" , "10", "+", "20", "/", "2"]
We use the function below to get the RPN version using the Shunting Yard algorithm.
func getRPNArray(calculationArray: [String]) -> [String]{
let c = calculationArray
var myRPNArray = [String]()
var operandArray = [String]()
for i in 0...c.count - 1 {
if c[i] != "+" && c[i] != "-" && c[i] != "*" && c[i] != "/" {
//push number
let number = c[i]
myRPNArray.append(number)
} else {
//if this is the first operand put it on the opStack
if operandArray.count == 0 {
let firstOperand = c[i]
operandArray.append(firstOperand)
} else {
if c[i] == "+" || c[i] == "-" {
operandArray.reverse()
myRPNArray.append(contentsOf: operandArray)
operandArray = []
let uniqOperand = c[i]
operandArray.append(uniqOperand)
} else if c[i] == "*" || c[i] == "/" {
let strongOperand = c[i]
//If I want my mult./div. from right(eg because of parenthesis) the line below is all I need
//--------------------------------
// operandArray.append(strongOperand)
//----------------------------------
//If I want my mult./div. from left
let lastOperand = operandArray[operandArray.count - 1]
if lastOperand == "+" || lastOperand == "-" {
operandArray.append(strongOperand)
} else {
myRPNArray.append(lastOperand)
operandArray.removeLast()
operandArray.append(strongOperand)
}
}
}
}
}
//when I have no more numbers I append the reversed operant array
operandArray.reverse()
myRPNArray.append(contentsOf: operandArray)
operandArray = []
print("RPN: \(myRPNArray)")
return myRPNArray
}
and then we enter the RPN array in the function below to calculate the result. In every loop we remove the numbers and the operand used before and we import the previous result and two "p" in the array so in the end we are left with the solution and an array of "p".
func getResultFromRPNarray(myArray: [String]) -> Double {
var a = [String]()
a = myArray
print("a: \(a)")
var result = Double()
let n = a.count
for i in 0...n - 1 {
if n < 2 {
result = Double(a[0])!
} else {
if a[i] == "p" {
//Do nothing else. Calculations are over and the result is in your hands!!!
} else {
if a[i] == "+" {
result = Double(a[i-2])! + Double(a[i-1])!
a.insert(String(result), at: i-2)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.insert("p", at: 0)
a.insert("p", at: 0)
} else if a[i] == "-" {
result = Double(a[i-2])! - Double(a[i-1])!
a.insert(String(result), at: i-2)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.insert("p", at: 0)
a.insert("p", at: 0)
} else if a[i] == "*" {
result = Double(a[i-2])! * Double(a[i-1])!
a.insert(String(result), at: i-2)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.insert("p", at: 0)
a.insert("p", at: 0)
} else if a[i] == "/" {
result = Double(a[i-2])! / Double(a[i-1])!
a.insert(String(result), at: i-2)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.remove(at: i - 1)
a.insert("p", at: 0)
a.insert("p", at: 0)
} else {
// it is a number so do nothing and go the next one
}
}//no over yet
}//n>2
}//iterating
return result
}//Func

Sum integers from a key value until there is one-digit

I need a function that both reduces integers to a single digit and accepts strings. Variants using reduce would also be appreciated.
let dict: [Character:Int] = ["a": 1, "j":1, "s":1, "b":2, "k":2, "t":2, "c":3, "l":3, "u":3, "d":4, "m":4, "v":4, "e":5, "n":5, "w":5, "f":6, "o":6, "x":6, "g":7, "p":7, "y":7, "h":8, "q":8, "z":8, "i":9, "r":9]
This function accepts strings and reduces by summing, but does not reduce to a single digit.
func f1(_ str: String) -> Int {
return str.reduce(0) { $0 + (dict[$1] ?? 0) }
}
f1("lighthouse") //52
This function reduces to a single digit but does not accepts strings.
func f2(_ n: Int) -> Int {
return (1 + ((n-1) % 9))
}
f2(52) //7
You just need to combine your both methods in the return statement:
return 1 + (str.reduce(0) {$0 + (dict[$1] ?? 0)} - 1) % 9
Here is a function that converts a string into a single digit Int.
Input: "9l231ffi1j"
func f1(_ str: String) -> Int {
return str.reduce(0) { $0 + ((Int(String($1)) ?? dict[$1]) ?? 0) }
}
func f3(_ input : String) -> Int {
return f2(f1(input))
}
f3("lighthouse") //7
f3("9l231ffi1j") //5
Thanks to Leo's answer in this question and Martin's answer in my other related [question] I was able to produce a standard version using Swift's for in loop without shorthand {$0 $1} and reduce().
let n = "lighthouse"
var nScore = 0
for i in n.indices {
let curChar = n[i]
let curVal = dict[curChar, default: 0]
nScore = 1 + (nScore + curVal - 1) % 9
}
nScore //7

How do I convert a bitmask Int into a set of Ints?

I want a function that takes in a bitmask Int, and returns its masked values as a set of Ints. Something like this:
func split(bitmask: Int) -> Set<Int> {
// Do magic
}
such that
split(bitmask: 0b01001110) == [0b1000000, 0b1000, 0b100, 0b10]
One solution is to check each bit and add the corresponding mask if the bit is set.
func split(bitmask: Int) -> Set<Int> {
var results = Set<Int>()
// Change 31 to 63 or some other appropriate number based on how big your numbers can be
for shift in 0...31 {
let mask = 1 << shift
if bitmask & mask != 0 {
results.insert(mask)
}
}
return results
}
print(split(bitmask: 0b01001110))
For the binary number 0b01001110 the results will be:
[64, 2, 4, 8]
which are the decimal equivalent of the results in your question.
For the hex number 0x01001110 (which is 1000100010000 in binary) the results will be:
[16, 256, 4096, 16777216]
Here's another solution that doesn't need to know the size of the value and it's slightly more efficient for smaller numbers:
func split(bitmask: Int) -> Set<Int> {
var results = Set<Int>()
var value = bitmask
var mask = 1
while value > 0 {
if value % 2 == 1 {
results.insert(mask)
}
value /= 2
mask = mask &* 2
}
return results
}
Note that the most common use cases for bit masks include packing a collection of specific, meaningful Boolean flags into a single word-sized value, and performing tests against those flags. Swift provides facilities for this in the OptionSet type.
struct Bits: OptionSet {
let rawValue: UInt // unsigned is usually best for bitfield math
init(rawValue: UInt) { self.rawValue = rawValue }
static let one = Bits(rawValue: 0b1)
static let two = Bits(rawValue: 0b10)
static let four = Bits(rawValue: 0b100)
static let eight = Bits(rawValue: 0b1000)
}
let someBits = Bits(rawValue: 13)
// the following all return true:
someBits.contains(.four)
someBits.isDisjoint(with: .two)
someBits == [.one, .four, .eight]
someBits == [.four, .four, .eight, .one] // set algebra: order/duplicates moot
someBits == Bits(rawValue: 0b1011)
(In real-world use, of course, you'd give each of the "element" values in your OptionSet type some value that's meaningful to your use case.)
An OptionSet is actually a single value (that supports set algebra in terms of itself, instead of in terms of an element type), so it's not a collection — that is, it doesn't provide a way to enumerate its elements. But if the way you intend to use a bitmask only requires setting and testing specific flags (or combinations of flags), maybe you don't need a way to enumerate elements.
And if you do need to enumerate elements, but also want all the set algebra features of OptionSet, you can combine OptionSet with bit-splitting math such as that found in #rmaddy's answer:
extension OptionSet where RawValue == UInt { // try being more generic?
var discreteElements: [Self] {
var result = [Self]()
var bitmask = self.rawValue
var element = RawValue(1)
while bitmask > 0 && element < ~RawValue.allZeros {
if bitmask & 0b1 == 1 {
result.append(Self(rawValue: element))
}
bitmask >>= 1
element <<= 1
}
return result
}
}
someBits.discreteElements.map({$0.rawValue}) // => [1, 4, 8]
Here's my "1 line" version:
let values = Set(Array(String(0x01001110, radix: 2).characters).reversed().enumerated().map { (offset, element) -> Int in
Int(String(element))! << offset
}.filter { $0 != 0 })
Not super efficient, but fun!
Edit: wrapped in split function...
func split(bitmask: Int) -> Set<Int> {
return Set(Array(String(bitmask, radix: 2).characters).reversed().enumerated().map { (offset, element) -> Int in
Int(String(element))! << offset
}.filter { $0 != 0 })
}
Edit: a bit shorter
let values = Set(String(0x01001110, radix: 2).utf8.reversed().enumerated().map { (offset, element) -> Int in
Int(element-48) << offset
}.filter { $0 != 0 })

A concise way to not execute a loop now that C-Style for loops are going to be removed from Swift 3?

Imagine we have this code which works perfectly for n >= 0.
func fibonacci(n: Int) -> Int {
var memo = [0,1]
for var i = 2; i <= n; i++ {
memo.append(memo[i-1] + memo[i-2])
}
return memo[n]
}
If I remove the C-style for loop due to upcoming changes to Swift 3.0, I get something like this:
func fibonacci(n: Int) -> Int {
var memo = [0,1]
for i in 2...n {
memo.append(memo[i-1] + memo[i-2])
}
return memo[n]
}
While this works fine for n >= 2, it fails for the numbers 0 and 1 with this error message:
fatal error: Can't form Range with end < start
What's the most concise way to fix this code so it works properly for 0 and 1?
(Note: It's okay, and even desirable, for negative numbers to crash the app.)
Note: I realize I could add a guard statement:
guard n >= 2 else { return memo[n] }
... but I'm hoping there is a better way to fix just the faulty part of the code (2...n).
For example, if there was a concise way to create a range that returns zero elements if end < start, that would be a more ideal solution.
To do this in a way that works for n < 2, you can use the stride method.
let startIndex = 2
let endIndex = n
for i in stride(from: startIndex, through: endIndex, by: 1) {
memo.append(memo[i-1] + memo[i-2])
}
You can easily create a valid range with the max() function:
for i in 2 ..< max(2, n+1) {
memo.append(memo[i-1] + memo[i-2])
}
This evaluates to an empty range 2 ..< 2 if n < 2.
It is important to use the ..< operator which excludes the upper bound because 2 ... 1 is not a valid range.
But in this function I would simply treat the special cases first
func fibonacci(n: Int) -> Int {
// Let it crash if n < 0:
precondition(n >= 0, "n must not be negative")
// Handle n = 0, 1:
if n <= 1 {
return n
}
// Handle n >= 2:
var memo = [0,1]
for i in 2 ... n {
memo.append(memo[i-1] + memo[i-2])
}
return memo[n]
}
(Note that your memo array is set to the initial value [0, 1]
for each function call, so the values are not really "memoized".
Without memoization you don't need an array, it would suffice to keep the last two numbers to compute the next.)
As it turns out, the variable i will always be equal to the count of the memoizing array, so you can just use that as your loop condition:
func fibonacci(n: Int) -> Int {
var memo = [0,1]
while n >= memo.count {
memo.append(memo[memo.count-1] + memo[memo.count-2])
}
return memo[n]
}
Alternatively, you could express the loop as a recursive function:
func fibonacci(n: Int) -> Int {
var memo = [0,1]
func rec(i: Int) -> Int {
if i >= memo.count { memo.append(rec(i-2) + rec(i-1)) }
return memo[i]
}
return rec(n)
}
Really, though, if is the best solution here. Ranges don't allow the end to be smaller than the beginning by design. The extra line for:
func fibonacci(n: Int) -> Int {
if n < 2 { return n }
var memo = [0,1]
for i in 2...n {
memo.append(memo[i-1] + memo[i-2])
}
return memo[n]
}
Is readable and understandable. (To my eye, the code above is better than the for ;; version)
#Marc's answer is great: https://stackoverflow.com/a/34324032/1032900
But the stride syntax is too long for frequent usage, so I made it a little more pleasant for the common i++ usages...
extension Strideable {
#warn_unused_result
public func stride(to end: Self) -> StrideTo<Self> {
return stride(to: end, by: 1)
}
}
extension Strideable {
#warn_unused_result
public func stride(thru end: Self) -> StrideThrough<Self> {
return stride(through: end, by: 1)
}
}
So use like this:
for i in startPos.stride(to: endPos) {
print("pos at: \(i)")
}