How to compare random numbers in Swift - swift

I’m a beginner in programming and playing around with the arc4random_uniform() function in Swift. The program I’m making so far generates a random number from 1-10 regenerated by a UIButton. However, I want the variable ’highest' that gets initialised to the random number to update if the next generated number is larger than the one currently held in it. For example the random number is 6 which is stored in highest and if the next number is 8 highest becomes 8. I don't know how to go about this. I have connected the UIButton to an IBAction function and have the following code:
var randomValue = arc4random_uniform(11) + 1
highest = Int(randomValue)
if (Int(randomValue) < highest) {
// Don’t know what to do
}

Initialise highest to 0
Every time you generate a new random number, replace the value of highest with the higher of the two numbers
highest = max(highest, randomValue)
The max() function is part of the Swift standard library and returns the larger of the two passed in vales.
edited to add
Here's a playground showing this with a bit more detail, including casting of types:
var highest: Int = 0
func random() -> Int {
let r = arc4random_uniform(10) + 1
return Int(r)
}
var randomValue = random()
highest = max(highest, randomValue)
You can see that multiple calls persist the highest value.

Related

how can I assign the same random number to 2 variables in swift?

I am building an app that the user selects a multiplication table. Then it gives random numbers to multiplicate with the number they select. for example, if the user selects "1". the questions shown would be "1 x 1", or "1 x 8".
The problem is that I need to assign the same random number to 2 variables. The one that will be shown on the question and the one used to calculate the result.
I thought of something like this, but the random number is different on each variable. What can I do to use the same random number generated on 2 variables?
func game() -> (String, Int) {
let randomNumber = multiplicate.randomElement()
switch selectedQuestion {
case 0:
return ("1 × \(randomNumber!)", 1 * randomNumber!)
default:
return ("", 0)
}
}
Not exactly sure what you're asking but you could do something like this:
let number = Int.random(in: 0..<10)
let number2 = number
but I don't think there is a need to create a new variable for this. The whole idea of variables is that you can save some value and then use it later so there isn't really a need to create number2 here.

How do I generate a random number not including one without using a while loop?

Let's say I want to generate a random number between 1 and 100, but I don't want to include 42. How would I do this without repeating the random method until it is not 42.
Updated for Swift 5.1
Excluding 1 value
var nums = [Int](1...100)
nums.remove(at: 42)
let random = Int(arc4random_uniform(UInt32(nums.count)))
print(nums[random])
Excluding multiple values
This extension of Range does provide a solution when you want to exclude more than 1 value.
extension ClosedRange where Element: Hashable {
func random(without excluded:[Element]) -> Element {
let valid = Set(self).subtracting(Set(excluded))
let random = Int(arc4random_uniform(UInt32(valid.count)))
return Array(valid)[random]
}
}
Example
(1...100).random(without: [40,50,60])
I believe the computation complexity of this second solution is O(n) where n is the number of elements included in the range.
The assumption here is the no more than n excluded values are provided by the caller.
appzYourLife has some great general purpose solutions, but I want to tackle the specific problem in a lightweight way.
Both of these approaches work roughly the same way: Narrow the range to the random number generator to remove the impossible answer (99 answers instead of 100), then map the result so it isn't the illegal value.
Neither approach increases the probability of an outcome relative to another outcome. That is, assuming your random number function is perfectly random the result will still be random (and no 2x chance of 43 relative to 5, for instance).
Approach 1: Addition.
Get a random number from 1 to 99. If it's greater than or equal to the number you want to avoid, add one to it.
func approach1()->Int {
var number = Int(arc4random_uniform(99)+1)
if number >= 42 {
number = number + 1
}
return number
}
As an example, trying to generate a random number from 1-5 that's not 3, take a random number from 1 to 4 and add one if it's greater than or equal to 3.
rand(1..4) produces 1, +0, = 1
rand(1..4) produces 2, +0, = 2
rand(1..4) produces 3, +1, = 4
rand(1..4) produces 4, +1, = 5
Approach 2: Avoidance.
Another simple way would be to get a number from 1 to 99. If it's exactly equal to the number you're trying to avoid, make it 100 instead.
func approach2()->Int {
var number = Int(arc4random_uniform(99)+1)
if number == 42 {
number = 100
}
return number
}
Using this algorithm and narrowing the range to 1-5 (while avoiding 3) again, we get these possible outcomes:
rand(1..4) produces 1; allowed, so Result = 1
rand(1..4) produces 2, allowed, so Result = 2
rand(1..4) produces 3; not allowed, so Result = 5
rand(1..4) produces 4, allowed, so Result = 4

swift programming language tuple

I'm relatively new to the programming scene (my only experience was C++ in first year engineering) and I'm trying to teach myself Swift language. I have the Swift Programming Language e-book from the App Store and came across the Function and Closure section regarding Tuples and am currently confused. The code they provide as an example is:
func calculateStatistics(scores:[Int]) -> (min:Int, max:Int, sum:Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
if score > max {
max = score
} else if score < min {
min = score
}
sum += score
}
return (min, max, sum)
}
let calculateStatistics([5, 3, 100, 3, 9])
and it'll output (3, 100, 120).
I'm just not sure about the process of how they get those values via the For-Loop and if-statement.
If any one of you can kindly walk me through whats exactly is happening in this if-statement that would be greatly appreciated!! My thinking is obviously wrong but the way I viewed it was that the min and max value is "5" by the initial variable declaration. But what is the initial value of "score" and how do you determine if score is > or < the max and min?
Tuples are just a group of values. The function is declared to return a tuple of three ints. At the end of the function there's a return statements where the resulting tuple is created from existing variables.
As for the loops and ifs, they just go through the list given as the parameter to the function, and find the highest and lowest values in the list, like this:
max is initialized to be the first value in the list. (It has to have an initial values so that it can be compared against other values with < and >.)
Go through every int in the list with for score in scores (score is initialized to be the next value in the list with each iteration: first it's 5, then 3, then 100, etc.).
If an int is found to be greater than max, max is updated to that value.
After going through every int in the list, max will have the value of the greatest int in that list.
And same for min.
Edit: In the Swift Programming Language e-book, a few pages before Functions and Closures, there's an explanation on the for-in loop structure. Check it out.

How do you generate a random number in swift? [duplicate]

This question already has answers here:
How to generate a random number in Swift?
(26 answers)
Closed 8 years ago.
tl:dr; How do I generate a random number, because the method in the book picks the same numbers every time.
This seems to be the way in Swift to generate a random number, based on the book released from Apple.
protocol RandomNumberGenerator {
func random() -> Double
}
class LinearCongruentialGenerator: RandomNumberGenerator {
var lastRandom = 42.0
let m = 139968.0
let a = 3877.0
let c = 29573.0
func random() -> Double {
lastRandom = ((lastRandom * a + c) % m)
return lastRandom / m
}
}
let generator = LinearCongruentialGenerator()
for _ in 1..10 {
// Generate "random" number from 1-10
println(Int(generator.random() * 10)+1)
}
The problem is that in that for loop I put at the bottom, the output looks like this:
4
8
7
8
6
2
6
4
1
The output is the same every time, no matter how many times I run it.
The random number generator you created is not truly random, it's psueodorandom.
With a psuedorandom random number generator, the sequence depends on the seed. Change the seed, you change the sequence.
One common usage is to set the seed as the current time, which usually makes it random enough.
You can also use the standard libraries: arc4random(). Don't forget to import Foundation.
Pseudorandom number generators need a "seed" value. In your case, if you change lastRandom with any number, you'll get a different sequence.

choose random value

I am new to iPhone programming. I have 10 number say (1,2,3,4,5,6,7,8,9,10). I want to choose randomly 1 number from the above 10 numbers. How can I choose a random number from a set of numbers?
If you simply want a value between 1 and 10, you can use the standard C rand() method. This returns an integer between zero and RAND_MAX.
To get a value between 0 and 9 you can use the % operator. So to get a value between 1 and 10 you can use:
rand()%10 + 1
If you don't want the same series of pseudo random numbers each time, you'll need to use srand to seed the random number generator. A good value to seed it with would be the current time.
If you're asking about choosing a number from a list of arbitrary (and possibly non consecutive) numbers, you could use the following.
int numbers[] = {2,3,5,7,11,13,17,19,23,29};
int randomChoice = numbers[rand()%10];
To generate a random number you should use random() function. But if you call it twice it gives you two equal answers. Before calling random(), call srand(time()) to get fresh new random number. if you want to use for(int i = 0; ...) to create numbers,
use srand(time() + i).
Something like this:
- (IBAction)generate:(id)sender
{
// Generate a number between 1 and 10 inclusive
int generated;
generated = (random() % 10) + 1;
}