Last active
November 22, 2015 18:38
-
-
Save possen/24b1c086a4e6c94ad8d8 to your computer and use it in GitHub Desktop.
Description: Single Riffle detection, try to detct if a deck of cards has been riffled only once
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Description: Single Riffle detection, try to detct if a deck of cards has been riffled only once. | |
// | |
// Language: Swift 2.1 (playground) | |
// Author: Paul Ossenbruggen | |
// Date: Nov 21, 2015 | |
// | |
// Uses a stack approach because it is easy to get the next element. It could be done with iterators too which | |
// be non destructive and might be faster, since swift copies the array a distructive approach should work. | |
// | |
import UIKit | |
func shuffleArray(var array : [Int]) -> [Int] { | |
for (index, _) in array[0..<array.count-1].enumerate() { | |
let randomIndex = Int(arc4random_uniform(UInt32(array.count - index))) + index | |
guard index != randomIndex else { continue } // swap does not like it if you swap same indexes | |
swap(&array[index], &array[randomIndex]) | |
} | |
return array | |
} | |
// randomly pick from either half split deck the deck | |
func riffle(var half1 : [Int], var half2 : [Int]) -> [Int] { | |
var result : [Int] = [] | |
while half1.count > 0 || half2.count > 0 { | |
if arc4random_uniform(UInt32(2)) == 0 && half1.count > 0 { | |
let half1element = half1.removeFirst() | |
result += [half1element] | |
} else if half2.count > 0 { | |
let half2ELement = half2.removeFirst() | |
result += [half2ELement] | |
} | |
} | |
return result | |
} | |
// this function is O(N) time. because it copies the original values, as swift usually does, it | |
// uses O(N) space. This is fine for a deck of cards. | |
func isSingleRiffle(var shuffled : [Int], var half1 : [Int], var half2 : [Int]) -> Bool{ | |
while shuffled.count > 0 { | |
let shuffledTop = shuffled.removeFirst() | |
if shuffledTop == half1.first { | |
half1.removeFirst() | |
} else if shuffledTop == half2.first { | |
half2.removeFirst() | |
} else { | |
return false // not found in the order shuffle order, so return false. | |
} | |
} | |
return true | |
} | |
// original shuffled deck | |
let array = shuffleArray(Array(1...52)) | |
let half1 = Array(array[0..<(array.count/2)]) | |
let half2 = Array(array[(array.count/2+1)..<array.count]) | |
// check if it is a single riffle | |
assert(isSingleRiffle(array, half1: half1 , half2:half2) == false, "should not be a single riffle as it is random") | |
// riffle the deck once. | |
let riffleArray = riffle(half1, half2: half2) | |
assert(isSingleRiffle(riffleArray, half1:half1, half2:half2) == true, "should be a single riffle") | |
// split deck again, compare to original halves | |
let newHalf1 = Array(array[0..<(riffleArray.count/2)]) | |
let newHalf2 = Array(array[(riffleArray.count/2+1)..<array.count]) | |
let newRiffleArray = riffle(newHalf1, half2: newHalf2) | |
assert(isSingleRiffle(newRiffleArray, half1:half1, half2:half2) == false, "should not be a single riffle as we sorted twice") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment