Why did index go out of range - swift

Hello i'm doing the simple FizzBuzz challenge. I figured out a solution to the problem. But I don't understand why my first attempt went out of range or what is happening behind the scenes.
To stop it from going out of range I changed
array.remove(at: i)
to
array.remove(at: i - 1)
Below is my entire project.
First attempt
var array = [String]()
for i in 1...100{
array.append("\(i)")
if i % 3 == 0 && i % 5 == 0 {
array.remove(at: i)
array.append("FizzBuzz")
}else if i % 3 == 0{
array.remove(at: i)
array.append("Fizz")
} else if i % 5 == 0{
array.remove(at: i)
array.append("Buzz")
}
}
print(array)
Second attempt
var array = [String]()
for i in 1...100{
array.append("\(i)")
if i % 3 == 0 && i % 5 == 0 {
array.remove(at: i - 1 )
array.append("FizzBuzz")
}else if i % 3 == 0{
array.remove(at: i - 1)
array.append("Fizz")
} else if i % 5 == 0{
array.remove(at: i - 1)
array.append("Buzz")
}
}
print(array)

Because arrays are zero index and you're starting at 1 in your for loop, so when you get to three and try to retrieve the third element (which indicates they're four elements in the array) swift will throw an error. The simple solution will be to start at 0
for i in 0...100{
print(i)
array.append("\(i)")
if i % 3 == 0 && i % 5 == 0 {
array.remove(at: i)
array.append("FizzBuzz")
}else if i % 3 == 0{
array.remove(at: i)
array.append("Fizz")
} else if i % 5 == 0{
array.remove(at: i)
array.append("Buzz")
}
}
print(array)
}

The remove(at:) function removes the element at the specified position. For example, if I have an array like [1,2,3,4] and I call array.remove(at: 2) the resulting array would be [1,2,4].
It is important to understand that the function removes the element at the specified INDEX location. Not the values itself. Swift arrays are zero indexed meaning, the first element is at location 0.
Now with this knowledge, I suggest you go ahead and debug your first code with some print statements and you be able to quickly understand why your code is going out of range. Hopefully through this experiment you can understand some basic concepts.
Good luck!

You are saying
for i in 1...100{
But array indices start at 0. So on every loop the item you just added has index i-1. There is no item with index i yet.
To put it another way, consider this part of your code:
if i % 3 == 0 && i % 5 == 0 {
array.remove(at: i)
Here you are prevaricating on the meaning of i. In the first line, it is what number i is. But in the second line, it is what index i is at. And because you started with 1, those two numbers are apart by 1. For example, the first time thru the loop, i is 1, but the value 1 is at index 0.

Related

Prime numbers print from range 2...100

I have been assigned with a task to print prime numbers from a range 2...100. I've managed to get most of the prime numbers but can't figure out how to get rid of 9 and 15, basically multiples of 3 and 5. Please give me your suggestion on how can I fix this.
for n in 2...20 {
if n % 2 == 0 && n < 3{
print(n)
} else if n % 2 == 1 {
print(n)
} else if n % 3 == 0 && n > 6 {
}
}
This what it prints so far:
2
3
5
7
9
11
13
15
17
19
One of effective algorithms to find prime numbers is Sieve of Eratosthenes. It is based on idea that you have sorted array of all numbers in given range and you go from the beginning and you remove all numbers after current number divisible by this number which is prime number. You repeat this until you check last element in the array.
There is my algorithm which should do what I described above:
func primes(upTo rangeEndNumber: Int) -> [Int] {
let firstPrime = 2
guard rangeEndNumber >= firstPrime else {
fatalError("End of range has to be greater than or equal to \(firstPrime)!")
}
var numbers = Array(firstPrime...rangeEndNumber)
// Index of current prime in numbers array, at the beginning it is 0 so number is 2
var currentPrimeIndex = 0
// Check if there is any number left which could be prime
while currentPrimeIndex < numbers.count {
// Number at currentPrimeIndex is next prime
let currentPrime = numbers[currentPrimeIndex]
// Create array with numbers after current prime and remove all that are divisible by this prime
var numbersAfterPrime = numbers.suffix(from: currentPrimeIndex + 1)
numbersAfterPrime.removeAll(where: { $0 % currentPrime == 0 })
// Set numbers as current numbers up to current prime + numbers after prime without numbers divisible by current prime
numbers = numbers.prefix(currentPrimeIndex + 1) + Array(numbersAfterPrime)
// Increase index for current prime
currentPrimeIndex += 1
}
return numbers
}
print(primes(upTo: 100)) // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
print(primes(upTo: 2)) // [2]
print(primes(upTo: 1)) // Fatal error: End of range has to be greater than or equal to 2!
what is the Prime num : Prime numbers are the positive integers having only two factors, 1 and the integer itself,
//Funtion Call
findPrimeNumberlist(fromNumber: 1, toNumber: 100)
//You can print any range Prime number using this fucntion.
func findPrimeNumberlist(fromNumber:Int, toNumber: Int)
{
for i in fromNumber...toNumber
{
var isPrime = true
if i <= 1 { // number must be positive integer
isPrime = false
}
else if i <= 3 {
isPrime = true
}
else {
for j in 2...i/2 // here i am using loop from 2 to i/2 because it will reduces the iteration.
{
if i%j == 0 { // number must have only 1 factor except 1. so use break: no need to check further
isPrime = false
break
}
}
}
if isPrime {
print(i)
}
}
}
func getPrimeNumbers(rangeOfNum: Int) -> [Int]{
var numArr = [Int]()
var primeNumArr = [Int]()
var currentNum = 0
for i in 0...rangeOfNum{
currentNum = i
var counter = 0
if currentNum > 1{
numArr.append(currentNum)
for j in numArr{
if currentNum % j == 0{
counter += 1
}
}
if counter == 1{
primeNumArr.append(currentNum)
}
}
}
print(primeNumArr)
print(primeNumArr.count)
return primeNumArr
}
Then just call the function with the max limit using this
getPrimeNumbers(rangeOfNum: 100)
What is happening in above code:
The numArr is created to keep track of what numbers have been used
Any number that is prime number is added/appended to primeNumArr
Current number shows the number that is being used at the moment
We start from 0 ... upto our range where we need prime numbers upto (with little modification it can be changed if the range starts from other number beside 0)
Remember, for a number to be Prime it should have 2 divisor means should be only completely divisible by 2 numbers. First is 1 and second is itself. (Completely divisible means having remainder 0)
The counter variable is used to keep count of how many numbers divide the current number being worked on.
Since 1 is only has 1 Divisor itself hence its not a Prime number so we start from number > 1.
First as soon as we get in, we add the current number being checked into the number array to keep track of numbers being used
We run for loop to on number array and check if the Current Number (which in our case will always be New and Greater then previous ones) when divided by numbers in numArr leaves a remainder of 0.
If Remainder is 0, we add 1 to the counter.
Since we are already ignoring 1, the max number of counter for a prime number should be 1 which means only divisible by itself (only because we are ignoring it being divisible by 1)
Hence if counter is equal to 1, it confirms that the number is prime and we add it to the primeNumArr
And that's it. This will give you all prime numbers within your range.
PS: This code is written on current version of swift
Optimised with less number of loops
Considered below conditions
Even Number can not be prime number expect 2 so started top loop form 3 adding 2
Any prime number can not multiplier of even number expect 2 so started inner loop form 3 adding 2
Maximum multiplier of any number if half that number
var primeNumbers:[Int] = [2]
for index in stride(from: 3, to: 100, by: 2) {
var count = 0
for indexJ in stride(from: 3, to: index/2, by: 2) {
if index % indexJ == 0 {
count += 1
}
if count == 1 {
break
}
}
if count == 0 {
primeNumbers.append(index)
}
}
print("primeNumbers ===", primeNumbers)
I finally figured it out lol, It might be not pretty but it works haha, Thanks for everyone's answer. I'll post what I came up with if maybe it will help anyone else.
for n in 2...100 {
if n % 2 == 0 && n < 3{
print(n)
} else if n % 3 == 0 && n > 6 {
} else if n % 5 == 0 && n > 5 {
} else if n % 7 == 0 && n > 7{
} else if n % 2 == 1 {
print(n)
}
}

Random number generators for a skiplist implementation

Most skiplists guides I see use an LCG random number generator and the following formula to generate the node heights.
random.generate().trailingZeroBitCount + 1
But LCGs have bad randomness in the lower order bits. Is this a problem, and if so what’s a good random number generator for skiplists?
If you are using trailingZeroBitCount then you are going for a specific distribution. In a random sample, we'd expect half of the numbers (the odd ones) to have trailingZeroBitCount == 0. We'd expect 1/4 of them to have 1 and so on.
I put this in a playground and got that distribution:
let randos = (1..<100000).map { _ in return arc4random() }
let zeroZeros = randos.filter{ i in i % 2 == 1 }
zeroZeros.count
let oneOrMoreZeros = randos.filter{ i in i % 2 == 0 }.map { $0 / 2 }
let oneZero = oneOrMoreZeros.filter{ i in i % 2 == 1 }
oneZero.count
let twoOrMoreZeros = oneOrMoreZeros.filter{ i in i % 2 == 0 }.map { $0 / 2 }
let twoZero = twoOrMoreZeros.filter{ i in i % 2 == 1 }
twoZero.count
I used arc4random because I don't know what you are using. Use this code to check your random number generator gets this kind of distribution.

Prime Numbers Swift 3

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")
}

Sum of Printed For Loop in Swift

For a project, I'm trying to find the sum of the multiples of both 3 and 5 under 10,000 using Swift. Insert NoobJokes.
Printing the multiples of both 3 and 5 was fairly easy using a ForLoop, but I'm wondering how I can..."sum" all of the items that I printed.
for i in 0...10000 {
if i % 3 == 0 || i % 5 == 0 {
print(i)
}
}
(468 individual numbers printed; how can they be summed?)
Just a little walk through about the process. First you will need a variable which can hold the value of your sum, whenever loop will get execute. You can define an optional variable of type Int or initialize it with a default value same as I have done in the first line. Every time the loop will execute, i which is either multiple of 3 or 5 will be added to the totalSum and after last iteration you ll get your result.
var totalSum = 0
for i in 0...10000 {
if i % 3 == 0 || i % 5 == 0
{
print(i)
totalSum = totalSum + i
}
}
print (totalSum)
In Swift you can do it without a repeat loop:
let numberOfDivisiblesBy3And5 = (0...10000).filter{ $0 % 3 == 0 || $0 % 5 == 0 }.count
Or to get the sum of the items:
let sumOfDivisiblesBy3And5 = (0...10000).filter{ $0 % 3 == 0 || $0 % 5 == 0 }.reduce(0, {$0 + $1})
range : to specify the range of numbers for operation to act on.
here we are using filter method to filter out numbers that are multiple of 3 and 5 and then sum the filtered values.
(reduce(0,+) does the job)
let sum = (3...n).filter({($0 % 3) * ($0 % 5) == 0}).reduce(0,+)
You just need to sum the resulting i like below
var sum = 0
for i in 0...10000 {
if i % 3 == 0 || i % 5 == 0 {
sum = sum + i
print(i)
}
}
Now sum contains the Sum of the values
Try this:
var sum = 0
for i in 0...10000 {
if i % 3 == 0 || i % 5 == 0 {
sum = sum + i
print(i)
}
}
print(sum)
In the Bottom line, this should to be working.
var sum = 0
for i in 0...10000 {
if i % 3 == 0 || i % 5 == 0 {
sum += i
print(i)
}
}
print(sum)

ios how to check if division remainder is integer

any of you knows how can I check if the division remainder is integer or zero?
if ( integer ( 3/2))
You should use the modulo operator like this
// a,b are ints
if ( a % b == 0) {
// remainder 0
} else
{
// b does not divide a evenly
}
It sounds like what you are looking for is the modulo operator %, which will give you the remainder of an operation.
3 % 2 // yields 1
3 % 1 // yields 0
3 % 4 // yields 1
However, if you want to actually perform the division first, you may need something a bit more complex, such as the following:
//Perform the division, then take the remainder modulo 1, which will
//yield any decimal values, which then you can compare to 0 to determine if it is
//an integer
if((a / b) % 1 > 0))
{
//All non-integer values go here
}
else
{
//All integer values go here
}
Walkthrough
(3 / 2) // yields 1.5
1.5 % 1 // yields 0.5
0.5 > 0 // true
swift 3:
if a.truncatingRemainder(dividingBy: b) == 0 {
//All integer values go here
}else{
//All non-integer values go here
}
You can use the below code to know which type of instance it is.
var val = 3/2
var integerType = Mirror(reflecting: val)
if integerType.subjectType == Int.self {
print("Yes, the value is an integer")
}else{
print("No, the value is not an integer")
}
let me know if the above was useful.
Swift 5
if numberOne.isMultiple(of: numberTwo) { ... }
Swift 4 or less
if numberOne % numberTwo == 0 { ... }
Swift 2.0
print(Int(Float(9) % Float(4))) // result 1