Shift Swift Array - ios

Array of Colors
let colorArray = [
UIColor.redColor(),
UIColor.orangeColor(),
UIColor.yellowColor(),
UIColor.greenColor(),
UIColor.blueColor()
]
The goal is to shift the array:
To start with a different color.
To preserve the circular order of colors.
Example #1
If we wanted to start with the orange color (the color at index 1 in the original array), the array would look like this:
let colorArray = [
UIColor.orangeColor(),
UIColor.yellowColor(),
UIColor.greenColor(),
UIColor.blueColor(),
UIColor.redColor(),
]
Example #2
If we wanted to start with the green color (the color at index 3 in the original array), the array would look like this:
let colorArray = [
UIColor.greenColor(),
UIColor.blueColor(),
UIColor.redColor(),
UIColor.orangeColor(),
UIColor.yellowColor()
]

Short & clear Swift 3 & 4 solution I came up with:
extension Array {
func shifted(by shiftAmount: Int) -> Array<Element> {
// 1
guard self.count > 0, (shiftAmount % self.count) != 0 else { return self }
// 2
let moduloShiftAmount = shiftAmount % self.count
let negativeShift = shiftAmount < 0
let effectiveShiftAmount = negativeShift ? moduloShiftAmount + self.count : moduloShiftAmount
// 3
let shift: (Int) -> Int = { return $0 + effectiveShiftAmount >= self.count ? $0 + effectiveShiftAmount - self.count : $0 + effectiveShiftAmount }
// 4
return self.enumerated().sorted(by: { shift($0.offset) < shift($1.offset) }).map { $0.element }
}
}
Explanation:
Arrays with no elements and shifts producing the identity of the
original array are returned immediately
To get the effective shift amount regardless of the amount passed with the function, we do some modulo calculation to get rid of shifts that would rotate the elements in the array more than once (e.g. in an Array with 5 Objects, a shift of +7 is the same as a shift of +2). Since we always want to shift to the right, in order to be done with one simple function instead of two, negative inputs have to be dealt with (e.g. in an Array with 5 Objects, a shift of -2 is the same as a shift of +3). Therefore we adjust the negative results of the modulo calculation by the length of the array.
Of course those 3 lines could be done in one, but I wanted to make this as readable as possible.
Now we prepare the actual shift by taking the index ($0) of element and returning the shifted index by adding the amount calculated in step 2. If the new index lands outside of the array length, it needs to be wrapped around to the front.
And finally we apply all the preparation to our array with some trickery: enumerated() gives us an array of tuples [(offset: Int, element: Int)], which is simply the original index of every element and the element itself. We then sort this enumerated array by the manipulated offset (aka the element's index) via applying the function from step 3. Lastly we get rid of the enumeration by mapping the sorted elements back into an array.
This extension works with arrays of any type. Examples:
let colorArray = [
UIColor.red,
UIColor.orange,
UIColor.yellow,
UIColor.green,
UIColor.blue
]
let shiftedColorArray = [
UIColor.green,
UIColor.blue,
UIColor.red,
UIColor.orange,
UIColor.yellow
]
colorArray.shifted(by: 2) == shiftedColorArray // returns true
[1,2,3,4,5,6,7].shifted(by: -23) // returns [3,4,5,6,7,1,2]

I know this might be late. But the easiest way to rotate or shift an array is
func shifter(shiftIndex: Int) {
let strArr: [String] = ["a","b","c","d"]
var newArr = strArr[shiftIndex..<strArr.count]
newArr += strArr[0..<shiftIndex]
println(newArr) }
shifter(2) //[c, d, a, b] you can modify the function to take array as input

You can extend Array to include a method to return an array containing the elements of the original array rotated by one element:
extension Array {
func rotate(shift:Int) -> Array {
var array = Array()
if (self.count > 0) {
array = self
if (shift > 0) {
for i in 1...shift {
array.append(array.removeAtIndex(0))
}
}
else if (shift < 0) {
for i in 1...abs(shift) {
array.insert(array.removeAtIndex(array.count-1),atIndex:0)
}
}
}
return array
}
}
To shifts the elements of an array once
let colorArray:[UIColor] = [
.redColor(),
.orangeColor(),
.yellowColor(),
.greenColor(),
.blueColor()
]
let z = colorArray.rotate(1)
// z is [.orangeColor(), .yellowColor(), .greenColor(), .blueColor(), .redColor()]
and twice
let z = colorArray.rotate(2)
// z is [.yellowColor(), .greenColor(), .blueColor(), .redColor(), .orangeColor()]

A variation of #zizutg's answer, that can shift in both directions (positive and negative)
extension Array {
public func shifted(by index: Int) -> Array {
let adjustedIndex = index %% self.count
return Array(self[adjustedIndex..<self.count] + self[0..<adjustedIndex])
}
}
// True modulo function https://stackoverflow.com/a/41180619/683763
infix operator %%
public func %%(_ dividend: Int, _ divisor: Int) -> Int {
precondition(divisor > 0, "modulus must be positive")
let reminder = dividend % divisor
return reminder >= 0 ? reminder : reminder + divisor
}

You can iterate by handling starting index.
func iterate<T>(array:Array<T>, start:Int, callback:(T) -> ()) {
let count = array.count
for index in start..<(start + count) {
callback(array[index % count])
}
}
If you want to start from index 3
iterate(colors, 3, { (color) -> () in println("color - \(color)")})

Related

Find the Missing no from an array the efficient way

I am trying to find an efficient way to solve the find a missing number from an array. I implemented the following way it's O(n). Please write any codes that efficiently solves this, just for learning purpose.
func findMissingNo(arrA: [Int]) -> [Int] {
let firstIndex = arrA.first ?? 0
let lastIndex = arrA.last ?? 0
let rslt = Array(firstIndex...lastIndex)
let missingNoArray = rslt.filter{ !arrA.contains($0)}
return missingNoArray
}
findMissingNo(arrA: [11,12,14,15,16,18]) // Prints [13, 17] by looping 9 times
Quickly written and tested (in terms of times performances against your code, but not in term of possible edges cases/mistakes, for instance, if array is 0...10, it won't work, but I'll let you work on the edges cases, since I focused mainly on the main cases, cases which might be covered during an edit and the end of the question)
Your current code:
func findMissingNo(arrA: [Int]) -> [Int] {
let firstIndex = arrA.first ?? 0
let lastIndex = arrA.last ?? 0
let rslt = Array(firstIndex...lastIndex)
let missingNoArray = rslt.filter{ !arrA.contains($0)}
return missingNoArray
}
let numberArray = [11,12,14,15,18]
let missing1 = findMissingNo(arrA: numberArray)
print("Missing1: \(missing1)")
My attempt:
func findMissingNo2(arrA: [Int]) -> [Int] {
var missingNumbers: [Int] = []
guard arrA.count > 2 else { return missingNumbers }
for i in 0...arrA.count-2 {
var current = arrA[i]
let next = arrA[i+1]
if next != current + 1 {
current += 1
while current != next {
missingNumbers.append(current)
current += 1
}
}
}
return missingNumbers
}
let missing2 = findMissingNo2(arrA: numberArray)
print("Missing1: \(missing2)")
Creating a big batch:
var array = Array(0...1000)
for _ in 0...10 {
if let index = array.indices.randomElement() {
let value = array.remove(at: index)
print("removed: \(value)") //To check just in case that's the good value returned by the methods
}
}
Testing:
let date1 = Date()
for _ in 0...100 {
let missing = findMissingNo(arrA: array)
print(missing)
}
print(Date().timeIntervalSince(date1)) //18.617565035820007
let date2 = Date()
for _ in 0...100 {
let missing = findMissingNo2(arrA: array)
print(missing)
}
print(Date().timeIntervalSince(date2)) //0.09566605091094971
print("---End")
print("")
For the time, I got: 18.857954025268555 vs 0.09159696102142334, a big factor difference (~200 times).
Why is there such a big difference?
Because of
let missingNoArray = rslt.filter{ !arrA.contains($0)}
It means:
for each number in result, check if arrayA contains that number.
->
for each number in result, for each number in arrayA (with a stop condition, so it's not a full iteration, but "almost" in term of complexity) check if there is a match...
Here there is a "double" (which is in fact not double, but n?) iteration that you missed.
I tested first with bigger value (array from "0 to 100000"), but it was taking too much time, with that "low number of values", the difference can already be seen.
Instead, you could use a Set:
let missingNoArray = Array(Set(rslt).subtracting(Set(arrA))).sorted()
It's faster than you method in my tests, (double my solution (0.21 ~ 0.22) in time performances), but still much faster than yours.
I added the sorted(), which may or may not be important in your solution, but will add time consumption since Set aren't ordered.
For the edges cases (ie: [3], [3, 4], [3, 8])
guard arrA.count > 2 else { return missingNumbers }
==>
guard !arrA.isEmpty else { return [] }
guard arrA.count > 2 else {
if arrA[0] + 1 >= arrA[1] {
return []
} else {
return Array((arrA[0] + 1)...arrA[1]).dropLast() //Because last will be arrA[1] which is present)
}
}

Find longest length string in array of tuples

I have an array of tuples var label = [(x: CGFloat, y: CGFloat, v1: String, v2: String)]() and would like to find the string of longest length in v1.
I could iterate through the array like this:
var maxlength = 0
var position = 0
for i in 0 ..< label.count {
if label[i].v1.count > maxlength {
maxlength = label[i].v1.count
position = i
}
}
print("longest string: \(maxlength) chars, at position \(position), is \(label[position].v1)")
but is there a more concise method?
You can use the max(by:) operator on your label array.
let longestString = label.max { $0.v1 < $1.v1}
Or a combination of map and max, as you're only interested in the longest string, not the tuple with the longest string value.
let longestString = label.map(\.v1).max()
For finding the position you have 2 options
enumerated:
let positionOfLongestString: Int? = label
.map(\.v1)
.enumerated() // converts array to a (offset: Index, element: String) tuple array
.max { $0.element < $1.element }?
.offset
firstIndexOf:
let positionOfLongestString: Int? = label
.map(\.v1)
.max()
.flatMap { longestString in
label.firstIndex { $0.v1 == longestString }
}

how to compare pairwise elements of a CGPoint array to determine which has a greater x position

I have an array of CGPoints (which are arranged in a specific order) [A1, A2,...,AN]. How can I compare the elements in pairs of two to determine which has a greater x position? For example, comparing A1.x with A2.x, A2.x with A3.x, A3.x with A4.x and so on all the way to AN.x with A1.x (comparing elements in specific order).
I wrote extension function pairwiseCompare(index: Self.Index?) -> Bool?, that take index of element and compare this element with next (or with first, if it is last):
extension CollectionType where Generator.Element == CGPoint {
func pairwiseCompare(index: Self.Index?) -> Bool? {
guard let index = index where startIndex.distanceTo(index) >= 0 && index.distanceTo(endIndex) > 0 else {
return nil
}
let secondIndex = index.successor() == endIndex ? startIndex : index.successor()
return self[index].x > self[secondIndex].x
}
func pairwiseCompare() -> [Bool] {
var result = [Bool]()
for index in startIndex..<endIndex {
result.append(pairwiseCompare(index)!)
}
return result
}
}
Usage:
let array = [CGPoint(x: 1, y: 1), CGPoint(x: 2, y: 1), CGPoint(x: 5, y: 1)]
print(array.pairwiseCompare(-1)) // nil
print(array.pairwiseCompare(0)) // Optional(false)
print(array.pairwiseCompare(1)) // Optional(false)
print(array.pairwiseCompare(2)) // Optional(true)
print(array.pairwiseCompare(3)) // nil
print(array.pairwiseCompare()) // [false, false, true]

How to choose from an array of sprites in swift

So basically I am looking to choose one of the 4 different coloured balls at random to come into the scene which each have an animation, physics properties and movement & spacing that I have already coded. I am not sure exactly how to make the array then choose at random from the array of the 4 coloured balls so that I have one ball chosen at random to come into the scene.
To make it more clear what I'm asking here's some code (I only use two balls in this code so you don't have to read as much):
var moveandremove = SKAction() < this is in my ballScene.swift
The spawn runBlock is inside didMovetoView
let spawn = SKAction.runBlock({
() in
self.allballs()
})
let delay = SKAction.waitForDuration(2.0)
let SpawnDelay = SKAction.sequence([spawn, delay])
let spawndelayforever = SKAction.repeatActionForever(SpawnDelay)
self.runAction(spawndelayforever)
let distance = CGFloat(brnball.frame.width * 20 + brnball.frame.width)
let moveball = SKAction.moveByX(-distance, y: 0, duration: NSTimeInterval(0.003 * distance))
let removeball = SKAction.removeFromParent()
moveandremove = SKAction.sequence([moveball])
}
func allballs() {
TextureAtlasblk = SKTextureAtlas(named: "blkball")
for i in 1...TextureAtlasblk.textureNames.count{
var Name = "blkball_\(i)"
blkarray.append(SKTexture(imageNamed: Name))
}
blkball = SKSpriteNode(imageNamed: "blkball_1")
blkball.position = CGPoint(x: CGRectGetMidX(self.frame) + 100, y: CGRectGetMidY(self.frame))
blkball.zPosition = 7
blkball.setScale(0.1)
self.addChild(blkball)
blkball.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(blkarray, timePerFrame: 0.2)))
//brownball
TextureAtlasbrn = SKTextureAtlas(named: "brnball")
for i in 1...TextureAtlasbrn.textureNames.count{
var Name = "brnball_\(i)"
brnarray.append(SKTexture(imageNamed: Name))
}
brnball = SKSpriteNode(imageNamed: "brnball_1")
brnball.position = CGPoint(x: CGRectGetMidX(self.frame) + 50, y: CGRectGetMidY(self.frame))
brnball.zPosition = 7
brnball.setScale(0.1)
self.addChild(brnball)
brnball.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(brnarray, timePerFrame: 0.2)))
Here is my terrible starting point at trying to make an array to choose from each ball (this is inside my allballs() function):
var ballarray: NSMutableArray = [blkball, brnball, yelball, bluball]
runAction(moveandremove)
I am new to swift and pretty hopeless, would be awesome if someone could help me out :)
Thanks
It's hard for me to find the array that you're talking about in your code. But nevertheless, I can still show you how.
Let's say we have an [Int]:
let ints = [10, 50, 95, 48, 77]
And we want to get a randomly chosen element of that array.
As you may already know, you use the subscript operator with the index of the element to access an element in the array, e.g. ints[2] returns 95. So if you give a random index to the subscript, a random item in the array will be returned!
Let's see how can we generate a random number.
The arc4random_uniform function returns a uniformly distributed random number between 0 and one less the parameter. Note that this function takes a UInt32 as a parameter and the return value is of the same type. So you need to do some casting:
let randomNumber = Int(arc4random_uniform(UInt32(ints.count)))
With randomNumber, we can access a random element in the array:
let randomItem = ints[randomNumber]
Try to apply this technique to your situation.
Here's a generic method to do this as well:
func randomItemInArray<T> (array: [T]) -> T? {
if array.isEmpty {
return nil
}
let randomNumber = Int(arc4random_uniform(UInt32(array.count)))
return array[randomNumber]
}
Note that if the array passed in is empty, it returns nil.
You could make and extension for Array that returns a random element.
extension Array {
func randomElement() -> Element {
let i = Int(arc4random_uniform(UInt32(count - 1)))
return self[i]
}
}
You could take that a step further and allow a function to be applied directly to a random element.
mutating func randomElement(perform: (Element) -> Element) {
let i = Int(arc4random_uniform(UInt32(count - 1)))
self[i] = perform(self[i])
}
You can use this function when using an array of reference types.
func randomElement(perform: (Element) -> ()) {
let i = Int(arc4random_uniform(UInt32(count - 1)))
perform(self[i])
}

Calculate all permutations of a string in Swift

For the string "ABC" the code snippet below calculates 5 of the 6 total permutations. My strategy was to insert each character at each index possible index. But the function never gets "CBA" as a possible permutation. What am I missing?
var permutationArray:[String] = [];
let string: String = "ABC"
func permute(input: String) -> Array<String>
{
var permutations: Array<String> = []
/* Convert the input string into characters */
var inputArray: Array<String>
inputArray = input.characters.map { String($0) }
print(inputArray)
/* For each character in the input string... */
for var i = 0; i < inputArray.count; i++
{
/* Insert it at every index */
let characterInArray: String = inputArray[i]
var inputArrayCopy: Array<String> = []
for var y = 0; y < inputArray.count; y++
{
inputArrayCopy = inputArray
inputArrayCopy.removeAtIndex(i)
inputArrayCopy.insert(characterInArray, atIndex:y)
let joiner = ""
let permutation = inputArrayCopy.joinWithSeparator(joiner)
if !permutations.contains(permutation) {
permutations.insert(permutation, atIndex: 0)
}
}
}
return permutations
}
var permutations = permute(string)
print(permutations)
While Stefan and Matt make a good point about using Heap's algorithm, I think you have an important question about why your code doesn't work and how you would debug that.
In this case, the algorithm is simply incorrect, and the best way to discover that is with pencil and paper IMO. What you are doing is picking each element, removing it from the array, and then injecting it into each possible location. Your code does what you have asked it to do. But it's not possible to get to "CBA" that way. You're only moving one element at a time, but "CBA" has two elements out of order. If you expanded to ABCD, you'd find many more missing permutations (it only generates 10 of the 24).
While Heap's algorithm is nicely efficient, the deeper point is that it walks through the entire array and swaps every possible pair, rather than just moving a single element through the array. Any algorithm you choose must have that property.
And just to throw my hat into the ring, I'd expand on Matt's implementation this way:
// Takes any collection of T and returns an array of permutations
func permute<C: Collection>(items: C) -> [[C.Iterator.Element]] {
var scratch = Array(items) // This is a scratch space for Heap's algorithm
var result: [[C.Iterator.Element]] = [] // This will accumulate our result
// Heap's algorithm
func heap(_ n: Int) {
if n == 1 {
result.append(scratch)
return
}
for i in 0..<n-1 {
heap(n-1)
let j = (n%2 == 1) ? 0 : i
scratch.swapAt(j, n-1)
}
heap(n-1)
}
// Let's get started
heap(scratch.count)
// And return the result we built up
return result
}
// We could make an overload for permute() that handles strings if we wanted
// But it's often good to be very explicit with strings, and make it clear
// that we're permuting Characters rather than something else.
let string = "ABCD"
let perms = permute(string.characters) // Get the character permutations
let permStrings = perms.map() { String($0) } // Turn them back into strings
print(permStrings) // output if you like
Here's an expression of Heap's (Sedgewick's?) algorithm in Swift. It is efficient because the array is passed by reference instead of being passed by value (though of course this means you must be prepared to have the array tampered with). Swapping is efficiently expressed through the use of the built-in swapAt(_:_:) function:
func permutations(_ n:Int, _ a: inout Array<Character>) {
if n == 1 {print(a); return}
for i in 0..<n-1 {
permutations(n-1,&a)
a.swapAt(n-1, (n%2 == 1) ? 0 : i)
}
permutations(n-1,&a)
}
Let's try it:
var arr = Array("ABC".characters)
permutations(arr.count,&arr)
Output:
["A", "B", "C"]
["B", "A", "C"]
["C", "A", "B"]
["A", "C", "B"]
["B", "C", "A"]
["C", "B", "A"]
If what you wanted to do with each permutation was not merely to print it, replace print(a) with something else. For example, you could append each permutation to an array, combine the array of characters into a string, whatever.
A very straightforward approach as also suggested in Swift coding challenges.
func permutation(string: String, current: String = "") {
let length = string.characters.count
let strArray = Array(string.characters)
if (length == 0) {
// there's nothing left to re-arrange; print the result
print(current)
print("******")
} else {
print(current)
// loop through every character
for i in 0 ..< length {
// get the letters before me
let left = String(strArray[0 ..< i])
// get the letters after me
let right = String(strArray[i+1 ..< length])
// put those two together and carry on
permutation(string: left + right, current: current +
String(strArray[i]))
}
}
}
Apple today released an Algorithms package available at:
https://github.com/apple/swift-algorithms
This package includes a permutations function that works like so:
let string = "abc"
string.permutations()
/*
["a", "b", "c"]
["a", "c", "b"]
["b", "a", "c"]
["b", "c", "a"]
["c", "a", "b"]
["c", "b", "a"]
*/
func generate(n: Int, var a: [String]){
if n == 1 {
print(a.joinWithSeparator(""))
} else {
for var i = 0; i < n - 1; i++ {
generate(n - 1, a: a)
if n % 2 == 0 {
let temp = a[i]
a[i] = a[n-1]
a[n-1] = temp
}
else {
let temp = a[0]
a[0] = a[n-1]
a[n-1] = temp
}
}
generate(n - 1, a: a)
}
}
func testExample() {
var str = "123456"
var strArray = str.characters.map { String($0) }
generate(str.characters.count, a: strArray)
}
Don't reinvent the wheel. Here's a simple port of Heap's algorithm.
Here is my solution.
import Foundation
class Permutator {
class func permutation(_ str: String) -> Set<String> {
var set = Set<String>()
permutation(str, prefix: "", set: &set)
return set
}
private class func permutation(_ str: String, prefix: String, set: inout Set<String>) {
if str.characters.count == 0 {
set.insert(prefix)
}
for i in str.characters.indices {
let left = str.substring(to: i)
let right = str.substring(from: str.index(after: i))
let rem = left + right
permutation(rem, prefix: prefix + String(str[i]), set: &set)
}
}
}
let startTime = Date()
let permutation = Permutator.permutation("abcdefgh")
print("\(permutation) \n")
print("COMBINAISON: \(permutation.count)")
print("TIME: \(String(format: "%.3f", Date().timeIntervalSince(startTime)))s")
You can copy/paste it in a file and execute it with the command line swift binary.
For a permutation of 7 all unique characters, this algorithm take around 0,06 second to execute.
I was searching to solve the same problem, but I wanted a solution that worked with Generic data type, so I wrote one by looking at a scala code (http://vkostyukov.ru/posts/combinatorial-algorithms-in-scala/)
https://gist.github.com/psksvp/8fb5c6fbfd6a2207e95638db95f55ae1
/**
translate from Scala by psksvp#gmail.com
http://vkostyukov.ru/posts/combinatorial-algorithms-in-scala/
*/
extension Array
{
func combinations(_ n: Int) -> [[Element]]
{
guard self.count > 0 else {return [[Element]]()}
guard n <= self.count else {return [[Element]]()}
if 1 == n
{
return self.map {[$0]}
}
else
{
let head = self.first! // at this point head should be valid
let tail = Array(self.dropFirst())
let car = tail.combinations(n - 1).map {[head] + $0} // build first comb
let cdr = tail.combinations(n) // do the rest
return car + cdr
}
}
func variations(_ n:Int) -> [[Element]]
{
func mixone(_ i: Int, _ x: Element, _ ll: [Element]) -> [Element]
{
return Array( ll[0 ..< i] + ([x] + ll[i ..< ll.count]) )
}
func foldone(_ x: Element, _ ll: [Element]) -> [[Element]]
{
let r:[[Element]] = (1 ... ll.count).reduce([[x] + ll])
{
a, i in
[mixone(i, x, ll)] + a
}
return r
}
func mixmany(_ x: Element, _ ll: [[Element]]) -> [[Element]]
{
guard ll.count > 0 else {return [[Element]]()}
let head = ll.first!
let tail = Array<Array<Element>>(ll.dropFirst())
return foldone(x, head) + mixmany(x, tail)
}
guard self.count > 0 else {return [[Element]]()}
guard n <= self.count else {return [[Element]]()}
if 1 == n
{
return self.map {[$0]}
}
else
{
let head = self.first! // at this point head should be valid
let tail = Array(self.dropFirst())
return mixmany(head, tail.variations(n - 1)) + tail.variations(n)
}
}
var permutations: [[Element]]
{
variations(self.count)
}
}
print([1, 2, 3, 4].combinations(2))
print([1, 2, 3, 4].variations(2))
print([1, 2, 3, 4].permutations)
print(Array("ABCD").permutations)
100% working tested
func permute(strInput:String,l:Int,r:Int){
var inputCharacter = Array(strInput)
if ( l==r){
print(strInput)
}else{
for var i in l..<r{
// Swapping done
inputCharacter.swapAt(l, i);
// Recursion called
permute(strInput: String(inputCharacter), l: l+1, r: r);
//backtrack
inputCharacter.swapAt(l, i);
}
}
}
This way you can call method:
permute(strInput: "ABC", l: 0, r: 3)
Output:
ABC
ACB
BAC
BCA
CBA
CAB
You can use the functions of this framework to calculate permutations and combinations both with repetition and without repetition. You can investigate the source code and compare with your own.
https://github.com/amirrezaeghtedari/AECounting
This library calculates the results based on lexicographic order. For example the result of permutation 3 items out of 5 items are same as below:
let result = Permutation.permute(n: 5, r: 3)
//result
//[
// [1, 2, 3],
// [1, 2, 4],
// [1, 2, 5],
// ...,
// 5, 4, 3]
//].
You can easily assign your problem items to 1 to n numbers in the result array.
In case of your problem, you should call:
let result = Permutation.permute(n: 3, r: 3)
For those looking to calculate all permutations of an array:
func permutations<T>(_ arr: [T]) -> [[T]] {
if arr.count < 2 {
return [arr]
}
var ret: [[T]] = []
let rest = Array(arr[1...])
for p in permutations(rest) {
for i in 0...p.count {
ret.append(Array(p[0..<i]) + [arr[0]] + Array(p[i...]))
}
}
return ret
}
🚨 Update: just use array.permuations() as noted by #Caleb

Resources