What's wrong with my logic? How can 9 come out of this loop both as a prime and not a prime number?
This works as expected for 0, 1, 2, 3, 4, 5, 6, 7, 8 but gets hung up on 9...
var userInput = 9
if userInput == 0 {
print("0 is not a prime number")
} else if userInput == 1 {
print("1 is not a prime number")
} else if userInput == 2 {
print("2 is a prime number")
} else {
for var i = 2; i < userInput; i = i + 1 {
if userInput % i == 0 {
print("\(userInput) is not a prime number")
break
} else {
print("\(userInput) is a prime number")
break
}
}
}
Remove one of the break statements. The loop needs to run completely until it finds a condition where it isn't a prime number. If it does not find said condition, it is a prime number.
var userInput = 9
if userInput == 0 {
print("0 is not a prime number")
} else if userInput == 1 {
print("1 is not a prime number")
} else if userInput == 2 {
print("2 is a prime number")
} else {
for var i = 2; i < userInput; i = i + 1 {
if userInput % i == 0 {
print("\(userInput) is not a prime number")
break
} else {
print("\(userInput) is a prime number")
// no break here
}
}
}
Or a bit more useful :
The logic is embedded in a function so you can use return for the control flow instead of break. Because there is a return true at the end you only have to look for false conditions. If it is not a prime you use return false to escape from the function and the return true at the end will never be called.
extension Int {
func isPrimeNumber() -> Bool {
switch self {
case 0 : return false
case 1 : return false
default :
for i in 2..<self {
if (self % i) == 0 {
return false
}
}
}
return true
}
}
userInput.isPrimeNumber()
The function is placed in an extension to Int so you can just call the function from userInput.
This logic is flawed:
for var i = 2; i < userInput; i = i + 1 {
if userInput % i == 0 {
print("\(userInput) is not a prime number")
break
} else {
print("\(userInput) is a prime number")
break
}
}
The if-else is wrong. Rather, you need to cycle through the entire if part of the for-loop first, testing whether each number is a factor (if userInput % i == 0), over and over; then and only then, if you have finished the loop and still have not discovered a factor, can you declare that this must be a prime.
However, you'll find it hard to succeed in writing that logic if you set everything up at a flat top level as you have done. The problem is that you have no way to do a true exit when you're at top level. Your logic thus requires that you put everything inside a function, from which you can do a forced early exit by saying return.
In this rewrite, I've done that, plus I've used a switch which is clearer (and Swiftier) than your if...else if:
func testForPrime(userInput:Int) {
switch userInput {
case 0: print("0 is not a prime number")
case 1: print("1 is not a prime number")
case 2: print("2 is a prime number")
default:
for i in 2..<userInput {
if userInput % i == 0 {
print("\(userInput) is not a prime number")
return
}
}
print("\(userInput) is a prime number")
}
}
And here is how to test it:
for i in 0...20 {testForPrime(i)}
Output:
0 is not a prime number
1 is not a prime number
2 is a prime number
3 is a prime number
4 is not a prime number
5 is a prime number
6 is not a prime number
7 is a prime number
8 is not a prime number
9 is not a prime number
10 is not a prime number
11 is a prime number
12 is not a prime number
13 is a prime number
14 is not a prime number
15 is not a prime number
16 is not a prime number
17 is a prime number
18 is not a prime number
19 is a prime number
20 is not a prime number
(Also please note that I've used a Swift-style for-loop instead of your C-style for-loop. You should get used to the Swift style, because the C-style for-loop will be deleted from the language soon.)
My solutions look terrible in the comment box. I've re-pasted them here. Thank you again for all of your help!
var uI = 9
var isPrime = true
if uI == 0 || uI == 1 {
isPrime = false
}
for var i = 2; i < uI; i++ {
if uI % i == 0 {
isPrime = false
}
}
if isPrime {
print("\(uI) is prime!")
} else {
print("\(uI) is not prime”)
}
var uI = 11
var isPrime = true
if uI == 0 || uI == 1 {
isPrime = false
}
var i = 2
while i < uI {
if uI % i == 0 {
isPrime = false
}
i++
}
if isPrime {
print("\(uI) is prime!”)
} else {
print("\(uI) is not prime”)
}
Related
My question is as on the title. I'm trying to print even numbers from 1 to 500 suing a while loop and break keyword. Below is my best possible answer I can think of, but this only print number 2. I've been spending hours but I wasn't able to solve it.
var number = 0
while true{
number += 2
print(number)
if number % 2 == 0 && number <= 500 {
break
}
}
You can use Stride
for evenNumber in stride(from: 0, through: 500, by: 2) {
print(evenNumber)
}
To specifically do this with while and break:
var i = 0
while true {
print(i)
i += 2
if i > 500 {
break
}
}
for i in 0...500 {
if i % 2 == 0 {
print(i)
}
}
Use below code
var numbers = 0...500
for number in numbers {
if number % 2 == 0 {
print(number)
}
}
I think it's easier to use build-in stride
let arr = Array(stride(from: 0, to: 502, by: 2))
print(arr)
//
For manually
var counter = 0
var arr = [Int]()
while counter <= 500 {
if counter % 2 == 0 {
print(counter)
arr.append(counter)
}
counter += 1
}
var number = 0
while true {
number += 2
print(number)
// ↓ Your code goes here ↓
if number > 499 {
break
}
}
I am working on Euler problem 5 which is:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
I am having trouble with my nested loops. I have a for loop within in a while loop. My logic is I
check a number (currentNumber) against 1-20 (i), if currentNumber is not a multiple of i (checked using modular arithmatic)
then it breaks out of that loop and trys the next largest number.
My issue is I cannot figure out how to jump out of only my inner loop and not my outer loop. Here is my code:
class Five {
init() {
var currentNumber = 1
while true {
for i in 1...20 {
if currentNumber % i != 0 {
currentNumber += 1
continue
}
}
break
}
print("the smallest positive number that is evenly divisible " +
"by all of the numbers from 1 to 20 is \(currentNumber)")
}
}
You already got a good and correct answer. Just as an add-on, for the
sake of completeness:
An alternative to labeled continue statements is to move the inner loop into a separate function from which you can “early return”:
func isDivisibleBy1To20(_ number: Int) -> Bool {
for j in 2...20 {
if number % j != 0 {
return false
}
}
return true
}
var currentNumber = 1
while !isDivisibleBy1To20(currentNumber) {
currentNumber += 1
}
print("solution:", currentNumber)
Using functional methods this can be simplified to
func isDivisibleBy1To20(_ number: Int) -> Bool {
return !(2...20).contains(where: { number % $0 != 0 })
}
let solution = (1...).first(where: isDivisibleBy1To20)!
print("solution:", solution)
(Remark: There are other, much faster methods to solve this problem.)
For some reason, it always gave me the wrong result. It's always isItPrime = true no matter what number was assigned to the "number" variable.
This is my code:
let number = 6
var i = 1
var isItPrime: Bool?
while i < number {
if number % i == 0 {
isItPrime = false
} else {
isItPrime = true
}
i += 1
}
print(isItPrime)
Can somebody explain to me what's wrong with my code and why the isItPrime bool outputs always true ?
Problem 1
The last iteration of your while loop
while i < number {
if number % i == 0 {
isItPrime = false
} else {
isItPrime = true
}
i += 1
}
does overwrite the result.
So you always end up with the following result
if number % (number-1) == 0 {
isItPrime = false
} else {
isItPrime = true
}
Problem 2
Finally every number can be divided by 1, so you should start i from 2.
So
let number = 6
var i = 2
var isItPrime = true
while i < number {
if number % i == 0 {
isItPrime = false
break
}
}
print(isItPrime)
Refactoring
You can write a similar logic using Functional Programming
let number = 5
let upperLimit = Int(Double(number).squareRoot())
let isPrime = !(2...upperLimit).contains { number % $0 == 0 }
Because isItPrime is overwritten in subsequent iterations, the last number which is checked, which is number - 1 will always set isItPrime to true, because number and number - 1 are coprime.
Instead of saving the value to a boolean, just end the loop when you found out that the number is not a prime:
let number = 6
var isItPrime: Bool = true
for i in 2 ..< number {
if number % i == 0 {
isItPrime = false
break // end the loop, as we know that the number is not a prime.
}
}
print(isItPrime)
When dealing with problems like this, don't be afraid to take out a piece of paper and manually see what is going on in your loop.
Your loop will go from i = 1 to number = 5 (because of the < operator.
With that in mind, we perform each iteration manually.
for i = 1, number = 6
6 mod 1 = 0, isItPrime = false
for i = 2, number = 6
6 mod 2 = 0, isItPrime = false
for i = 3, number = 6
6 mod 3 = 0, isItPrime = false
for i = 4, number = 6
6 mod 4 = 2, isItPrime = true
Last iteration of the loop, for i = 5, number = 6
6 mod 5 = 1, isItPrime = true
There we can see that the problem is that the last iteration will always have a module of 1, therefore resulting in in your else clause getting executed.
It is always returning true because your while loop isn't working the way you want. Currently, it loops until i is 1 less than number. During that final run through the loop, number % i == 0 is false, so your code sets isItPrime to true.
To fix this problem, try this code:
let number = 6
var i = 2
var isItPrime: Bool?
while (i < number || isItPrime == false) {
if number % i == 0 {
isItPrime = false
} else {
isItPrime = true
}
i += 1
}
print(isItPrime)
You may have noticed I set i to 2, because any number modulo (%) 1 is 0
I think it's worth pointing out, however, that:
You should probably make this a method
If you initially set isItPrime to true, you can dispense with the else part of your if-else statement
Hope this helps!
// MARK: - Function
func primeNo(_ num:Int,_ divisor :Int = 2){
if divisor == num{
print("Num is prime")
}else{
if num%divisor != 0{
primeNo(num, divisor + 1)
}else{
print("num is not prime")
}
}
}
// MARK: - Use
primeNo(6)
out Put
num is not prime
After hours of Googling, I'm still at a standstill. I would appreciate if someone would point out the error in my formula or coding choice. Please keep in mind I'm new to Swift. I'm not used to non C-style for loops.
if textField.text != "" {
input = Double(textField.text!)! // parse input
// return if number less than 2 entered
if input < 2 {
resultLabel.text = "Enter a number greater than or equal to 2."
return;
}
// get square root of input and parse to int
inputSquared = Int(sqrt(input));
// loop from 2 to input iterating by 1
for i in stride(from: 2, through: input, by: 1) {
if inputSquared % Int(i) == 0 {
resultLabel.text = "\(Int(input)) is not a prime number."
}
else {
resultLabel.text = "\(Int(input)) is a prime number!"
}
}
}
I didn't know the formula on how to find a prime number. After looking up multiple formulas I have sorta settled on this one. Every result is a prime number, however. So my if condition is wrong. I just don't know how to fix it.
Check my algorithm.It works.But I'm not sure this is an effective algorithm for prime number
var input:Int = 30
var isPrime:Bool = true
if(input == 2){
print("Input value 2 is prim number")
}
else if(input < 2){
print("Input value must greater than 2")
}
else{
for i in 2...input-1{
if((input%i) == 0){
isPrime = false
break;
}
}
if(isPrime){
print("Your Input Value \(input) is Prime!")
}
}
A couple of solutions that work have been posted, but none of them explain why yours doesn't. Some of the comments get close, however.
Your basic problem is that you take the square root of input, then iterate from 2 to the input checking if the integer part of the square root is divisible by i. You got that the wrong way round. You need to iterate from 2 to the square root and check that the input is divisible by i. If it is, you stop because input is not prime. If you get to the end without finding a divisor, you have a prime.
try this code in playground you will get this better idea and try to use playground when you try the swift as you are not familiar with swift playground is best.
let input = 13 // add your code that take value from textfield
var prime = 1
// throw error less than 2 entered
if input < 2 {
assertionFailure("number should be 2 or greater")
}
// loop from 2 to input iterating by 1
for i in stride(from: 2, to: input, by: 1) {
if input % i == 0{
prime = 0
}
}
if prime == 1 {
print("\(input) number is prime")
} else {
print("\(input) number is not prime")
}
How do I find all the numbers divisible by another number in swift that have a remainder of 0? This is a Fizzbuzz related question.
Lets say that...
let number = 150
And I want to do something like...
print("Fizz") // for all the numbers where the remainder of number % 3 == 0.
So if number was 15, it would print "Fizz" 5 times.
This will work
let number = 150
for num in 1...number {
if num % 3 == 0 {
print("Fizz :\(num)")
}
}
you can just loop through the number and check with your desired divisible number if the remainder is 0 then print fizz
let number = 15
for i in 0..<number {
if i % 3 == 0 {
print("\(i) Fizz")
}
}
It will print Fizz 5 times with the i value, that which number is Fizz.
Simply try this code: (You can simply replace num with any Int number and divider that is also an Int value which is used to divide all numbers till num. )
override func viewDidLoad() {
let num:Int = 15
let divider:Int = 3
var counter:Int = divider
while counter <= num {
print("Fizz")
counter += divider
}
}
func fizzbuzz(number: Int) -> String {
if number % 3 == 0 && number % 5 == 0 {
return "Fizz Buzz"
} else if number % 3 == 0 {
return "Fizz"
} else if number % 5 == 0 {
return "Buzz"
} else {
return String(number)
}
}
https://www.hackingwithswift.com/guide/ios-classic/1/3/challenge