fatal error with a simple swift program - swift

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

Related

Count number of characters between two specific characters

Trying to make a func that will count characters in between two specified char like:
count char between "#" and "." or "#" and ".com"
If this is only solution could this code be written in a simple way with .count or something less confusing
func validateEmail(_ str: String) -> Bool {
let range = 0..<str.count
var numAt = Int()
numDot = Int()
if str.contains("#") && str.contains(".") && str.characters.first != "#" {
for num in range {
if str[str.index(str.startIndex, offsetBy: num)] == "#" {
numAt = num
print("The position of # is \(numAt)")
} else if
str[str.index(str.startIndex, offsetBy: num)] == "." {
numDot = num
print("The position of . is \(numDot)")
}
}
if (numDot - numAt) > 1 {
return true
}
}
return false
}
With help from #Βασίλης Δ. i made a direct if statement for func validateEmail that check if number of char in between are less than 1
if (str.split(separator: "#").last?.split(separator: ".").first!.count)! < 1{
return false
}
It could be usefull
There are many edge cases to what you're trying to do, and email validation is notoriously complicated. I recommend doing as little of it as possible. Many, many things are legal email addresses. So you will need to think carefully about what you want to test. That said, this addresses what you've asked for, which is the distance between the first # and the first . that follows it.
func lengthOfFirstComponentAfterAt(in string: String) -> Int? {
guard
// Find the first # in the string
let firstAt = string.firstIndex(of: "#"),
// Find the first "." after that
let firstDotAfterAt = string[firstAt...].firstIndex(of: ".")
else {
return nil
}
// Return the distance between them (not counting the dot itself)
return string.distance(from: firstAt, to: firstDotAfterAt) - 1
}
lengthOfFirstComponentAfterAt(in: "rob#example.org") // Optional(7)
There's a very important lesson about Collections in this code. Notice the expression:
string[firstAt...].firstIndex(of: ".")
When you subscript a Collection, each element of the resulting slice has the same index as in the original collection. The returned value from firstIndex can be used directly to subscript string without offsetting. This is very different than how indexes work in many other languages, and allows powerful algorithms, and also creates at lot of bugs when developers forget this.

Swift - for loop statement not taking an absolute value

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.

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!

Swift - Program to print and repeat message based on counter

I have a work related learning course and struck with a hands-on question on Swift programming - Control Transfer Statements like break, continue, fallthrough, return, & throw.
Write a function named printMessage that takes two parameters - a string message and an integer count. The message should print and repeat the message as specified in the count parameter.
Message:"Hello , How are You"
For instance take Count as 8
This should print Message:"Hello , How are You" 8 times consecutively.
So far I got the below code working fine on Xcode, should use control transfer Statements, so tried this. But some extra eyes/other best practice way would help. As I am stuck with this hands-on and it is stopping me to complete the course. The way its designed is it gets input on the text box on the web page and runs the code on the coding area and gets output, if it matches the expected output, it let you submit, but that does not means I am successful as it tests the code with their answer key and my code don't match the answer key and I am failing. Please help
func printMessage(message: String, count: Int){
for i in 0...count{
if( i == count){
break;
} else {
print(message);
continue;
}
}
}
let message: String = readLine()!;
let c = readLine();
let count: Int = Int(c!)!;
printMessage(message: message, count: count);
The following piece of code works as it is meant to, in a while loop and also incorporates the Control Transfer Statements, like you asked:
func printMessage(message: String, count: Int) {
var i: Int = 0
while true {
if i < count {
print(message)
i += 1
} else { break }
}
}
let message: String = "Hello!"
let count: Int = 3
printMessage(message: message, count: count)
If there are any more specifications, let me know. Also, it would be helpful to have a link to the lesson/tutorial. Hope this helps! :)
If you want to do it with for loop:
func PrintMessage (message: String, count: Int) {
for _ in 0..<count {
print(message)
}
}
let message = readLine()
let count = Int(readLine()!)
PrintMessage(message: message!, count: count!);
Try this one, Hope this will help you :)
func printMessage(message: String, count: Int) {
var localCount = 1
while localCount <= count {
print(message)
localCount = localCount + 1
}
}
printMessage(message: "Hello", count: 8)

Swift NSString to Int conversion issues

First off, I'm fairly new to programming and trying to learn Swift, though I've worked with python and perl in the past.
I'm creating a simple prime number command line application. The program runs correctly when I provide the arguments for the functions, but causes consistently incorrect outputs when I prompt user input. I researched the best way to implement this behavior in Swift, as it doesn't have scanf() or raw_input() type commands, but I have something screwed up.
The program has several different functions, but the one I've been fighting with checks whether an integer is prime. The code for the function follows:
func testForPrime(num:Int)->Bool{
var num = num
var counter = 0
var primeTest : Bool = true
if num <= 1 || num % 2 == 0{
println("\(num) is not a prime number")
primeTest = false
}else{
##'checkerNumbers' is another function to determine the denominator
for i in checkerNumbers(Double(num)){
if num % i == 0 {
++counter
println("\(num) is not a prime number.")
println("\(num / i)*\(i)=\(num)")
primeTest = false
break
}
}
if counter == 0{
println("\(num) is a prime number!")
primeTest = true
}
}
return primeTest
}
And here is the input for the function:
var input = NSFileHandle.fileHandleWithStandardInput()
println("Enter a number to check if it is prime")
if let data : NSData = input.availableData as NSData? {
if let var x : Int = NSInteger(NSUTF8StringEncoding) as NSInteger?{
var intInput = x
testForPrime(intInput)
}
}
When a any number is entered in the terminal, the output is always '4'. However, if I run the function with testForPrime(13), instead of with user input, it responds as I would expect. I was thinking it may have to do with the conversion from NSString and NSUTF8StringEncoding to Int...
Can someone help me sort this out?
Thanks in advance!
Ok... So I figured out a way to make it work, though it may not be the best. I replaced the whole input section with the following:
println("Enter a number to check if it is prime")
var input = NSString(data: NSFileHandle.fileHandleWithStandardInput().availableData, encoding:NSUTF8StringEncoding)
var intInput = input?.intValue
testForPrime(Int(intInput!))