Swift - for loop statement not taking an absolute value - swift

Such a weird question, but I set up this code in a playground:
let currentNumber = "1999999999"
let absNumber = abs(Double(currentNumber)!)
var digitCount = 0
if absNumber > 999999999 {
for n in currentNumber {
if n.isNumber {
digitCount += 1
} else {
break
}
print(digitCount)
}
}
As written, this code gets evaluated and my for loop runs...however, if is set my string to "-1999999999", the for loop doesn't run. The absolute value of -1999999999 is 100% greater than 999999999, so what did I miss?

The thing you did not understand is the control flow operator. You can get the expected behavior just change a single line:
if n.isNumber {
digitCount += 1
} else {
break // here change to continue
}
to this:
if n.isNumber {
digitCount += 1
} else {
continue
}
However, I highly recommend you try LLDB in an Xcode Project, either a Commandline tool or app. The stepover tool is quite useful for such a logical problem.

Related

Combine if statement and for loop such that loop only gets executed once per every execution of if statement in swift

I'm trying to understand swift and therefore try to come up with simple command line games: in this game a player has to guess a secret word within 6 attempts by typing something in the command line, but every time he gets it wrong, a statement prints the number of his wrong attempts:
let response = readLine()
if response != "secret word" {
for n in 1...6 {
print(n)
}
}
else {
print("you are right!")
}
Now I know that my code will print all lines once the condition is not true, but I'm looking for a way to only print one item out of the four loop for every if statement consecutively.
I think a while loop works pretty well. Maybe something like this:
print("Welcome to the input game!\n\n\n\n")
var remainingTries = 5
let dictionary = ["apple", "grape", "pear", "banana"]
let secretWord = dictionary.randomElement()
print("Please guess a fruit")
while remainingTries > 0 {
remainingTries -= 1
let response = readLine()
if response == secretWord {
print("You got it!")
remainingTries = 0
} else if remainingTries <= 0 {
print("Too bad, you lose!")
remainingTries = 0
} else {
print("Incorrect. Tries remaining: \(remainingTries)")
}
}

Rolling a dice in swift using a while function and printing results until the result is 1

I'm really new to Swift and I have a task asking me to create a while loop that simulates rolling a 6-sided dice repeatedly until a 1 is rolled. After each roll, print the value.
In just about every iteration I've tried over the last 2 hours I keep ending in an infinite loop that explodes Xcode.
Any help would be fantastic!
var dieRoll = Int.random(in: 1...6)
while dieRoll <= 6 {
print (dieRoll)
if dieRoll == 1 {
print ("You win!")
}
}
Got it to this point, it no longer runs endlessly but it acts weird and returns values of 1 without printing "You win!"
func dieRoll(x: Int) -> Int {
return Int.random(in:1...6)
}
while dieRoll(x: 0) > 1 {
print(dieRoll(x: 0))
if dieRoll(x: 1) == 1 {
print("You win!")
}
else {
RETURN
}
}
Your dieRoll variable is declared AS A VARIABLE yet you never change it! Try “rerolling” within the While Loop
Also, there’s always the chance that a 6 never gets rolled... idk if you want to mess with “real” probabilities but if you’re finding issues you may want to institute a “max number of rolls”... personally I wouldn’t but hey you never know
TDLR: last line of the while-loop should reroll your dieRoll var
Okay, so I got away from the string text and focused on what the code was saying versus what my typing was saying. Ended up with this (probably a monstrosity to you experienced folks) but it looks something like this.
var rolling = Int.random(in: 1...6)
while rolling > 1 {
print(rolling)
if rolling == 1 {
break
} else {
rolling = Int.random(in: 1...6)
}
}
print(rolling)
And every time I run it it ends on a 1 so it does what it needs to!

fatal error with a simple swift program

import UIKit
import Foundation
func randomnumber (low:Int,high:Int )->Int
{
let range = high - (low-1)
return (Int (arc4random()) % range ) + ( low - 1)
}
let answer = randomnumber(low: 0, high: 100)
var turn = 1
while (true)
{
print ("Guess #\(turn): enter a number between 0 and 100")
let userinput = readLine();
if let guess:Int = Int(userinput!)
{
if( guess<answer )
{
print("choose a higher number")
}
if ( guess>answer )
{
print ("choose a smaller number")
}
if( guess==answer)
{
print("wohoo you won")
break;
}
}
}
this code is about a simple game using swift , by having a random number and then putting an input and if this input is bigger than the random number we have to choose smaller number and the opposite if we choose a smaller number and its still not equal to the random number and if it's equal to the random number you win.
this error appears :
fatal error: unexpectedly found nil while unwrapping an Optional value
As Tristan Beaton pointed out, readLine() doesn't work on playground hence your userInput is always nil.
CREATE A COMMAND LINE TOOL APPLICATION
CHOSE SWIFT WHEN YOU SAVE
COPY AN PASTE YOUR CODE
RUN AND PLAY
Also be really careful when you force unwrapping. That's always a crash waiting to happen ;) You can read this tutorial
I have tested this in a Command Line Tool and it worked. Also don't force unwrap optionals since you can just check if they have data without crashing the app.
I have added continue statements within your other if statements. Although it isn't really needed in this case, it is good practice to have it so that any code after the continue doesn't get executed. It just saves a bit of computing power.
import Foundation
func randomnumber(low: Int, high: Int) - >Int {
let range = high - (low-1)
return (Int(arc4random()) % range) + (low - 1)
}
let answer = randomnumber(low: 0, high: 100)
var turn = 1
while (true) {
print("Guess #\(turn): enter a number between 0 and 100")
if let userinput = readLine() {
if let guess:Int = Int(userinput) {
// Putting this here will only increase the guess count if their input in a number.
turn += 1
if guess < answer {
print("choose a higher number")
continue
}
if guess > answer {
print ("choose a smaller number")
continue
}
if guess == answer {
print("wohoo you won")
break
}
}
}
}
This is the console output

Difference between 'for index' and traditional 'for loop'

I'm new to Swift and pretty new to programming. I'm not sure if it's because it's 2:34 am but can somebody help me identify the difference between these two loops?
The first one is resulting in the values I want yet uses (as the Swift documentation explains) a 'traditional C loop' where the one after is using what seems like a Swift preferred 'for index' loop (which I personally like as it is clearer to me), the problem is that this loop returns every number rather than meeting the conditional.
func findLargestPrimeFactor(number: Int) {
for var i = 2; i < number; i += i {
if number/i % 1 > 0 {
} else {
print(i);
}
}
}
findLargestPrimeFactor(13195);
Below is returning every number to 13195
func findLargestPrimeFactor(number: Int) {
for i in 2...number {
if number/i % 1 > 0 {
} else {
print(i);
}
}
}
findLargestPrimeFactor(13195);
I've realised how stupid my mistakes were, first of all I have no idea why I was doing i += i, that just didn't make sense at all.
Also, my conditional was never being met because I declared it as an Int when really I needed a Float because I care about remainders!
Edit: I've updated my code yet again (taken everyones feedback into consideration), I feel a bit better with this and will continue working on the solution.
Thanks to everyone for your help!
Updated code
func findLargestPrimeFactor(number: Int) {
for i in 2...number {
var n = Float(number)
var count = Float(i)
if n/count % 1 > 0 {
print("not divisible")
} else {
print(i)
}
}
}
findLargestPrimeFactor(13195);

Cannot change tuple in an array

I'm trying to change a tuple in an array , however ,when I try
emo = (type:emo.type,strength:increaseStrength(emo.strength))
it gives me error
"cannot assign to 'let' value 'emo'
here is my code :
var emotions : [(type : String, strength: Int)] = [("happy",0),("scared",0),("tender",0),("excited",0),("sad",0)]
func increaseStrength(i:Int)->Int {
switch i {
case 0: return 1
case 1: return 2
case 2: return 3
case 3: return 0
default :return 0
}
}
#IBAction func HappyBA(sender: AnyObject) {
for emo in emotions {
if (emo.type == "happy" ){
emo = (type:emo.type,strength:increaseStrength(emo.strength))
}
}
println(emotions)
}
If there are better way to do the assignment please tell me I am so appreciated ! Thanks..
There is no point assigning to emo even if you could do it. This is not the same as replacing the corresponding object in the array - which is what you do want to do. emo is a copy; even if you were to set a property of it, it wouldn't affect the one back in the array. And certainly setting the variable would not magically read back into the array!
Here's one solution. Instead of cycling thru emotions in your for-loop, cycle thru enumerate(emotions). Now you have a tuple of an index number along with an emotion. If this is the right emotion type, write into the array via the index number.
for (ix,emo) in enumerate(emotions) {
if emo.type == "happy" {
emotions[ix] = (type:emo.type,strength:increaseStrength(emo.strength))
}
}
Or you could use map.
emotions = emotions.map {
emo in
if emo.type == "happy" {
return (type:emo.type,strength:increaseStrength(emo.strength))
} else {
return emo
}
}