Stuck in a loop. Very strange because the code sometimes work and sometimes just freezes - ios

I am writing a puzzle game for an IOS. In my code I need to fill an array with some random (and non-random numbers) that will represent the main data structure.
func Random(r : Range<Int>) -> Int {
return Int(arc4random_uniform(UInt32(r.endIndex - r.startIndex))) + r.startIndex
} // function to generate random number
var arrWithColors = [Int]() // array that will hold the numbers
//function to that check if an array contains a number in a range already
func checkForNumberInArrayWithRange(r: Range <Int>, n: Int ) -> Bool {
for i in r.startIndex..<r.endIndex {
if arrWithColors[i] == n { return true }
}
return false
}
// here is the main function where i keep getting stuck. Out of let's say five times it would only work 3 or even less.
func randHexWithTag() {
var rNumber : Int = Random(0...5)
for i in 0...5 {
while (true) {
rNumber = Random(0...5)
if !checkForNumberInArrayWithRange(0...5, n: rNumber) {
break
}
}
arrWithColors[i] = rNumber
}
arrWithColors[10] = arrWithColors[1]
for i in 6...11 {
while(true) {
rNumber = Random(0...5)
if ((rNumber == arrWithColors[0] && i == 9) || (rNumber == arrWithColors[2] && i == 11)) {
continue
}
if !checkForNumberInArrayWithRange(6...11, n: rNumber) {
break
}
}
if (i != 10) {
arrWithColors[i] = rNumber
}
}
arrWithColors[13] = arrWithColors[4]
for i in 12...17 {
while(true) {
rNumber = Random(0...5)
if (rNumber == arrWithColors[3] && i == 12) || (rNumber == arrWithColors[5] && i == 14) {
continue
}
if !checkForNumberInArrayWithRange(12...17, n: rNumber) {
break
}
}
if (i != 13) {
arrWithColors[i] = rNumber
}
}
}

The above code will ALWAYS fail during the first call to checkForNumberInArrayWithRange on this line:
if arrWithColors[i] == n { return true }
That is because arrWithColors is empty, and index i is out of range

Related

Why is this handmade square root function in Swift not returning the value, but throws the error?

Just trying to create an analog of sqrt() in Swift, but it throws .noRoot in all the matched cases.
Also I add the error .outOfBound, this is working correctly.
import UIKit
enum WrongNumber: Error {
case outOfBounds
case noRoot
}
func mySqrt(_ number: Int) throws -> Int {
if number < 1 || number > 10_000 {
throw WrongNumber.outOfBounds
}
var result = 0
for i in 1...10_000 {
if i * i == number {
result = i
} else {
throw WrongNumber.noRoot
}
}
return result
}
var number = 1000
do {
let result = try mySqrt(number)
print(result)
}
catch WrongNumber.outOfBounds {
print("You're puting a wrong number. Please try again with range from 1 to 10_000")
}
catch WrongNumber.noRoot {
print("There is no square root in your number")
}
You should return once you find it
func mySqrt(_ number: Int) throws -> Int {
if number < 1 || number > 10_000 {
throw WrongNumber.outOfBounds
}
for i in 1...10_000 {
if i * i == number {
return i
}
}
throw WrongNumber.noRoot
}

Generate consecutive and same number on Array effectively in Swift

I have an example of a case in the application to create a numeric pin pattern that should not have a consecutive number and the same number of all.
Examples of PIN patterns that are rejected are as follows:
123456,
234567,
345678,
654321,
765432,
876543,
000000 and other similar PIN patterns.
var rejectedPinList: [[Int]] = [[Int]]()
var consecutiveNumber = [0,1,2,3,4,5,6,7,8,9,0]
func incrementNumber(currentIndex: Int) -> [Int] {
var rejectedPinPattern: [Int] = [Int]()
for currentIndex in stride(from: currentIndex, to: currentIndex+6, by: 1){
rejectedPinPattern.append(consecutiveNumber[currentIndex])
}
return rejectedPinPattern
}
func decrementNumber(currentIndex: Int) -> [Int] {
var rejectedPinPattern: [Int] = [Int]()
for currentIndex in stride(from: currentIndex, to: currentIndex-6, by: -1){
rejectedPinPattern.append(consecutiveNumber[currentIndex])
}
return rejectedPinPattern
}
func constantNumber(currentIndex: Int) -> [Int] {
var rejectedPinPattern: [Int] = [Int]()
for _ in currentIndex...currentIndex+6 {
rejectedPinPattern.append(consecutiveNumber[currentIndex])
}
return rejectedPinPattern
}
for number in consecutiveNumber {
rejectedPinList.append(constantNumber(currentIndex: number))
if number < 5 {
rejectedPinList.append(incrementNumber(currentIndex: number))
} else if number > 5 {
rejectedPinList.append(decrementNumber(currentIndex: number))
} else {
rejectedPinList.append(incrementNumber(currentIndex: number))
rejectedPinList.append(decrementNumber(currentIndex: number))
}
}
func inputPin(pin: [Int]) {
if rejectedPinList.contains(pin) {
print("Pin Rejected!")
} else {
}
}
inputPin(pin: [8,7,6,5,4,3]) // Should be Rejected!
What I'm looking for is to be more effective than the algorithm code I made above in generating consecutive & same numbers. Because in my opinion, the code I made is too long and not very effective and may be wasteful. Thank you!
Instead of computing a list of all invalid pins in advance, you can verify the given pin by computing the set of all differences of adjacent digits. A pin is invalid if the set consists of -1, 0, or +1 only:
func validatePIN(_ pin: [Int]) -> Bool {
if pin.isEmpty { return false }
let diffs = Set(zip(pin, pin.dropFirst()).map(-))
return diffs.count != 1 || abs(diffs.first!) > 1
}
As the question was to improve efficiency, the approach below this implements the some initial checks before it starts looping through the array to minimise the total number of iterations/time.
func validatePin(_ pin: [Int], minLength: Int = 2 ) -> Bool {
guard pin.count >= max(minLength, 2) else {return false}
guard Set(pin).count != 1 else {return false} //all the same
guard abs(pin.first! - pin.last!) == pin.count - 1 else {return true} //can't be a sequence
let delta = pin.first! < pin.last! ? -1 : 1
for index in (0...pin.count - 2) {
if pin[index] - pin[index + 1] != delta {return true} //items not sequential
}
return false //items are sequential
}
I think this should do what you want. It checks to see if there are any consecutive digits that have an absolute difference that isn't 1. If so then the PIN may be valid (pending a check for repeated digits).
To check for repeated digits, the digits are added to an NSCountedSet. If the count for any digit is the same as the number of digits then the PIN is invalid.
func validatePIN(_ candidate: [Int]) -> Bool {
guard !candidate.isEmpty else {
return false
}
let digitSet = NSCountedSet()
var possiblyValid = false
var lastSign: Int?
for i in 0..<candidate.count {
digitSet.add(candidate[i])
if i > 0 && !possiblyValid {
let difference = candidate[i]-candidate[i-1]
let thisSign = difference.signum()
if abs(difference) != 1 {
possiblyValid = true
} else if let sign = lastSign, sign != thisSign {
possiblyValid = true
}
lastSign = thisSign
}
}
for digit in digitSet {
if digitSet.count(for: digit) == candidate.count {
return false
}
}
return possiblyValid
}
print(validatePIN([]))
print(validatePIN([8,7,6,5,3,3]))
print(validatePIN([8,7,6,5,4,3]))
print(validatePIN([2,2,2,2,2,2]))
print(validatePIN([1,2,3,4,3,2]))
gives:
false
true
false
false
true
You could also add a test for minimum length in the guard statement
Thank you all for helping me. I also improvise my algorithm. Here's my code:
func validatePIN(_ pin: [Int]) -> Bool {
if (pin.isEmpty == true) ||
(pin[0] < 5 && pin == Array(pin[0]...pin[0]+5)) ||
(pin[0] > 5 && pin == Array(stride(from: pin[0], through: pin[0]-5, by: -1)) ||
(pin.allSatisfy({ $0 == pin[0] }))) { return false }; return true
}

Swift equivalent of this ActionScript function

I translated this tutorial on BSP into swift. In the tutorial there's this ActionScript function.
public function getRoom():Rectangle
{
// iterate all the way through these leafs to find a room, if one exists.
if (room != null)
return room;
else
{
var lRoom:Rectangle;
var rRoom:Rectangle;
if (leftChild != null)
{
lRoom = leftChild.getRoom();
}
if (rightChild != null)
{
rRoom = rightChild.getRoom();
}
if (lRoom == null && rRoom == null)
return null;
else if (rRoom == null)
return lRoom;
else if (lRoom == null)
return rRoom;
else if (FlxG.random() > .5)
return lRoom;
else
return rRoom;
}
}
I translated this function into Swift (to the best of my ability) I must have written it wrong because the function is returning a nil value when it shouldn't be.
My version in Swift:
// left/right child are initialized as follows:
// leftChild:Room?
// rightChild:Room?
public func getRoom() -> Room? {
if room != nil {
return room
} else {
var lRoom:Room?
var rRoom:Room?
if leftChild != nil {
lRoom = leftChild!.getRoom()!
}
if rightChild != nil {
rRoom = rightChild!.getRoom()!
}
if lRoom == nil && rRoom == nil {
return nil
} else if rRoom == nil {
return lRoom
} else if lRoom == nil {
return rRoom
} else if Double.random(in: 0..<1.0) > 0.5 {
return lRoom
} else {
return rRoom
}
}
}
Where Room is a basic class I made to help me handle the rooms.
class Room {
var x1:Int
var x2:Int
var y1:Int
var y2:Int
var center:CGPoint
init(X: Int, Y: Int, W: Int, H: Int) {
x1 = X
x2 = X + W
y1 = Y
y2 = Y + H
center = CGPoint(x: (x1 + x2) / 2, y: (y1 + y2) / 2)
}
}
I'm getting a nil value when I shouldn't be. I think I translated the function wrong. Rectangle would be CGRect in Swift but I replaced it with my Room class in other places in the code, so I know it'll work with the Room class here.
How would this function be written in Swift?
Your problem is that you are force unwrapping the result of getRoom - This function returns an optional and can legitimately return nil when your traversal hits a leaf node. Force unwrapping nil results in a crash
By using conditional unwrapping correctly you can not only make your code more readable, you can eliminate the crash.
public func getRoom() -> Room? {
if let _ = room {
return room
}
let lRoom = leftChild?.getRoom()
let rRoom = rightChild?.getRoom()
switch (lRoom != nil, rRoom != nil) {
case (false,false):
return nil
case (true,false):
return lRoom
case (false,true):
return rRoom
case (true,true):
return arc4random_uniform(2) == 1 ? lRoom: rRoom
}
}

Function in Swift will run, but will not execute "completion" in Swift

I am trying to call a function in Swift. The first time I call it, it runs as intended, but the second time the completion handler if and else statements don't run. Despite this, I still know the function runs because I had it print "RAN" every time it ran. I have no idea what I am doing wrong. Any help?
My Code:
[other code]
self.movieNum = Int(arc4random_uniform(50) + 1)
// Int movieNum is turned into String
let movieNumNSNumber = self.movieNum as NSNumber
let movieNumString: String = movieNumNSNumber.stringValue
self.checkIfMovieHasAlreadyBeenShown(movieID: movieNumString, completion: { seen in
if seen {
var i = 1
var haveAllBeenSeen = 1
while i <= 50 {
let iNSNumber = i as NSNumber
let iString: String = iNSNumber.stringValue
self.checkIfMovieHasAlreadyBeenShown(movieID: movieNumString, completion: { seen in
if seen {
print("SEEN")
}
else {
print("NOT SEEN")
haveAllBeenSeen = 0
}
})
i += 1
}
if haveAllBeenSeen == 0 {
self.swipingView()
}
else {
[other code]
}
else {
return
}
})

Prime number checker returns the same result each time

I'm a beginner programmer learning Swift and made a basic prime number checker. No matter what it will only give one result, instead of changing based on wether or not the number is prime. Any help would be appreciated.
#IBAction func primeCheck(sender: AnyObject) {
var numberInt = number.text.toInt()
var isPrime = true
if number != nil {
if numberInt == 1 {
isPrime = false
}
if numberInt != 1 {
for var i = 2; i < numberInt; i++ {
if numberInt! % i == 0 {
isPrime = false
} else {
isPrime = true
}
}
}
}
if isPrime == true {
result.text = "\(numberInt!) is a prime number!"
} else {
result.text = "\(numberInt!) is not a prime number!"
}
}
I have another possible solution. At first I divide by two because it cannot be a prime number. Then you loop until the number is prime or the number divided by two is less than the divider.
#IBAction func primeCheck(sender: AnyObject) {
var numberInt = number.text.toInt()
var isPrime = true
var divider = 3
if number < 2 || (number != 2 && number % 2 == 0) {
isPrime = false
}
// you only have to check to half of the number
while(isPrime == true && divider < number / 2){
isPrime = number % divider != 0
divider += 2
}
if isPrime == true {
result.text = "\(numberInt!) is a prime number!"
} else {
result.text = "\(numberInt!) is not a prime number!"
}
}
The error in your logic comes in this section:
if numberInt! % i == 0 {
isPrime = false
} else {
isPrime = true
}
At the top of your function, you initialize isPrime to be true, so in your loop you only need to look for cases that prove the number is not prime. You don't ever need to set isPrime = true again, so just drop the else condition:
if numberInt! % i == 0 {
isPrime = false
}
You actually have two functions here. One to check if a number is prime and the other to display the result. Separating these makes everything much easier to manage.
// function to check primality and return a bool
// note that this can only accept a non optional Int so there is
// no need to check whether it is valid etc...
func checkNumberIsPrime(number: Int) -> Bool {
// get rid of trivial examples to improve the speed later
if number == 2 || number == 3 {
return true
}
if number <= 1 || number%2 == 0 {
return false
}
// square root and round up to the nearest int
let squareRoot: Int = Int(ceil(sqrtf(Float(number))))
// no need to check anything above sqrt of number
// any factor above the square root will have a cofactor
// below the square root.
// don't need to check even numbers because we already checked for 2
// half the numbers checked = twice as fast :-D
for i in stride(from: 3, to: squareRoot, by: 2) {
if number % i == 0 {
return false
}
}
return true
}
// function on the button. Run the check and display results.
#IBAction func primeCheck(sender: AnyObject) {
let numberInt? = numberTextField.text.toInt() // don't call a text field "number", it's just confusing.
if let actualNumber = numberInt {
if checkNumberIsPrime(actualNumber) {
resultLabel.text = "\(actualNumber) is a prime number!" // don't call a label "result" call it "resultLabel". Don't confuse things.
} else {
resultLabel.text = "\(actualNumber) is not a prime number!"
}
} else {
resultLabel.text = "'\(numberTextField.text)' is not a number!"
}
}
It makes it all much easy to read and maintain.
You have to break out of the loop after you find that the number is divisble by another number. Also for prime check you only have to check the divisibility till the square root of the number.
You can also use optional binding to extract numberInt and check for nil. That's the swift way.
#IBAction func primeCheck(sender: AnyObject) {
var isPrime = true
if let numberInt = number.text.toInt() {
if numberInt == 1 {
isPrime = false /
}
else // Add else because you dont have to execute code below if number is 1
{
if numberInt != 1 {
for var i = 2; i * i <= numberInt; i++ { // Only check till squareroot
if numberInt % i == 0 {
isPrime = false
break // Break out of loop if number is divisible.
} // Don't need else condition because isPrime is initialised as true.
}
}
}
if isPrime {
result.text = "\(numberInt) is a prime number!"
} else {
result.text = "\(numberInt) is not a prime number!"
}
}
}
Reason for square root check : Why do we check up to the square root of a prime number to determine if it is prime?
You can refine the code further by refactoring the prime check into a separate function.
func isPrime(number:Int) -> Bool
{
if number == 1 {
return false
}
else
{
if number != 1 {
for var i = 2; i * i <= numberInt; i++ {
if numberInt % i == 0 {
return false
}
}
}
}
return true
}
#IBAction func primeCheck(sender: AnyObject) {
if let numberInt = number.text.toInt() {
if isPrime(numberInt) {
result.text = "\(numberInt) is a prime number!"
} else {
result.text = "\(numberInt) is not a prime number!"
}
}
}
Well i don't know about swift, but maybe this is wrecking your code:
if numberInt! <<
To do a faster algorithm you could just search for divisors from 2 to sqrt(numberInt). (Theorem)

Resources