if statement or loop - if-statement

I am trying to figure out if I need to use if statement or loop in my code. If random2 equals random1 then I want the random2 to generate another random number. If second time around random2 is again equal to random1, I want the code to keep running until it generates a different number from random1. Some guidance would be much appreciated.
public void generate(View view) {
Random randomGenerator = new Random();
int random1 = randomGenerator.nextInt(10);
int random2 = randomGenerator.nextInt(10);

You should use a loop. Create a new random number until they differ:
Random randomGenerator = new Random();
int random1 = randomGenerator.nextInt(10);
int random2;
do {
random2 = randomGenerator.nextInt(10);
} while(random1 == random2);

I would go for a loop:
Random rng = new Random();
int r1 = rng.nextInt(10);
int r2;
do {
r2 = rng.nextInt(10);
while (r1 == r2);

Related

Is this code fully recursive? If not, how do I make it so?

Problem
Consider a currency system in which there are notes of six denominations, namely, Rs. 1, Rs. 2, Rs. 5, Rs. 10, Rs. 50, Rs. 100.
If the sum of Rs. N is input, write a program to compute the smallest number of notes that will combine to give Rs. N.
Input
The first line contains an integer T, the total number of test cases. Then follow T lines, each line contains an integer N.
Output
For each test case, display the smallest number of notes that will combine to give N, in a new line.
#include <iostream>
using namespace std;
int main() {
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int count = 0;
while(n>0){
if(n>=100){
count = count + n/100;
n = n %100;
}
else if(n>=50){
count = count + n/50;
n = n%50;
}
else if(n>=10){
count = count + n/10;
n = n%10;
}
else if(n>=5){
count = count + n/5;
n = n%5;
}
else if(n>=2){
count = count + n/2;
n = n%2;
}
else if(n>=1){
count = count + n/1;
n = n%1;
}
}
cout<<count<<endl;
}
return 0;
}
As pointed out you don't do any recursion, you don't do any function calls at all.
There is also a code smell.
If you remove all the else the while loop becomes obsolete.
if(n>=100){
count = count + n/100;
n = n %100;
}
if(n>=50){
count = count + n/50;
n = n%50;
}
if(n>=10){
count = count + n/10;
n = n%10;
}
if(n>=5){
count = count + n/5;
n = n%5;
}
if(n>=2){
count = count + n/2;
n = n%2;
}
if(n>=1){
count = count + n/1;
n = n%1;
}
And you can remove all the if as well to get the same result without branching. Which might actually be faster:
count = count + n/100;
n = n %100;
count = count + n/50;
n = n%50;
count = count + n/10;
n = n%10;
count = count + n/5;
n = n%5;
count = count + n/2;
n = n%2;
count = count + n/1;
n = n%1;
The code is very repetitive. If you put the currency nominations in an array this can be written neater:
// outside of main
constexpr std::array coins = {100, 50, 10, 5, 2, 1};
// count coins
int count = 0;
for (const auto & coin : coins) {
count += n / coin;
n %= coin;
}
Now isn't that much better?
There's no recursion in this code. Recursion is where a function calls itself (directly of indirectly).
It's actually illegal for main to call itself, so to make this code recursive you are going to have to add at least one function. Where you see a loop that's where you should think recursion. So see the while loop, turn that into a function (don't worry about recursion yet). Then when you have that working see if you can replace the while loop part, instead of looping the function just calls itself (recursively).

Calculating percent chance

So my objective is to create a random password generator of length n (n >= 5 && n <= 15) that adds in only two numbers at random locations.
(e.g. 7S4js 86dJxD h6Zqs9K)
I have this working... or so I want to believe. What I want to know is will my code ALWAYS work at determining whether or not a number should be inserted.
'newPassword': Returns a string of length 'len', using 'nums' numbers.
std::string newPassword(int len, int nums)
{
std::string password = "";
// Required numbers
int req = nums;
for (int i = 0; i < len; i++)
{
bool needNum = req > 0;
bool chance = rand() % len > req;
bool useNum = needNum && chance;
if (useNum)
req--;
char c = nextChar(useNum);
password += c;
}
return password;
}
'nextChar': Returns a random character. The character will be a number if 'isNum' is true.
char nextChar(bool isNum)
{
char c;
if (!isNum)
{
// 50% chance to decide upper or lower case
if (rand() % 100 < 50)
{
c = 'a' + rand() % 26;
}
else
{
c = 'A' + rand() % 26;
}
}
else
{
// Random number 0-9
c = '0' + rand() % 10;
}
return c;
}
So specifically, will the 'chance' variable in 'newPassword' work all the time?
rand() is an obsolete and terrible way to generate random numbers. The c++11 <random> header provides much higher quality facilities for dealing with all kinds of random stuff.
Your way of choosing the letter or a digit will not always work. I would approach it in a different way: generate the needed number of letters and digits and then shuffle the string. It might not be the most efficient way, but given your requirements for password length, I'd value code clarity more.
#include <string>
#include <random>
#include <algorithm>
std::string generatePassword(int length, int nDigits)
{
std::string password;
password.resize(length);
std::mt19937 generator{std::random_device{}()};
// Generate capital/lowercase letters
std::uniform_int_distribution<char> letterGen(0, 2 * 26 - 1);
auto digitsBeginIter = std::generate_n(password.begin(), length - nDigits,
[&letterGen, &generator]() {
auto l = letterGen(generator);
return l < 26 ? 'a' + l : 'A' + (l - 26);
});
// Generate the digits
std::uniform_int_distribution<char> digitGen('0', '9');
std::generate_n(digitsBeginIter, nDigits,
[&digitGen, &generator]() { return digitGen(generator); });
// Shuffle the string
std::shuffle(password.begin(), password.end(), generator);
return password;
}

rand() doesn't work even with srand( time(NULL) )

So I'm trying to generate random integers inside functions, but it returns the same numbers. NUM_SOURCES == 5 and for all 5 repetitions it gives the same number despite srand(time(0)) being called. I tried the same without std::, but the result did not change.
Any suggestions?
std::srand(time(0)); //setting seed
...
for (int i = 0; i < NUM_SOURCES; i++)
{
if (sourceDeq->at(i)->getCurrentBid() == NULL) // If the source is empty, generate a new order
{
sourceDeq->at(i)->setCurrentBid(sourceDeq->at(i)->generateBid(systemTime));
}
}
...
Bid* Source::generateBid(int sysTime)
{
bidAmount = bidAmount + 1;
return new Bid(bidAmount, generateTimeCreation(sysTime), 0, 0, 0, getNumber());
}
...
int Source::generateTimeCreation(int sysTime)
{
srand(0);
if (sLaw == UNIFORM)
return (sysTime + std::rand() % 10);
if (sLaw == EXPONENTIAL)
return(sysTime + round((1 - exp(-(std::rand() % 100))) * 10));
}
srand(0); initializes the random number generator again, so it will have the same results, every time... Don't do it.
The whole point of calling with time(NULL) is to provide a random seed.

Generate unique multiple random numbers

I want to generate unique random numbers and add item in function of these random numbers. Here is my code :
The problem is when i verify if the number generated exist in the array with the code results.contains(randomNb) :
int nbRandom = ui->randoomNumberSpinBox->value();
//nbRandom is the number of the random numbers we want
int i = 1;
int results[1000];
while ( i < nbRandom ){
int randomNb = qrand() % ((nbPepoles + 1) - 1) + 1;
if(!results.contains(randomNb)){
//if randomNb generated is not in the array...
ui->resultsListWidget->addItem(pepoles[randomNb]);
results[i] = randomNb;
//We add the new randomNb in the array
i++;
}
}
results is an array. That's a built-in C++ type. It's not a class type and doesn't have methods. So this can't work:
results.contains(randomNb)
You probably want to use a QList instead. Like:
QList<int> results;
Add elements to it with:
results << randomNb;
Also, you have an off-by-one error in the code. You start counting from 1 (i = 1) instead of 0. This will result in missing the last number. You should change the i initialization to:
int i = 0;
With the changes, your code would become:
int nbRandom = ui->randoomNumberSpinBox->value();
//nbRandom is the number of the random numbers we want
int i = 0;
QList<int> results;
while ( i < nbRandom ){
int randomNb = qrand() % ((nbPepoles + 1) - 1) + 1;
if(!results.contains(randomNb)){
//if randomNb generated is not in the array...
ui->resultsListWidget->addItem(pepoles[randomNb]);
results << randomNb;
//We add the new randomNb in the array
i++;
}
}

How do I generate a random number between two variables that I have stored? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Generating random integer from a range
I am trying to create a program where the computer guesses a number the user has in his/her mind. The only user input required is whether the guess was too high, too low, or correct. I'm having a problem generating a random number between two variables that store the min and max based on previous guesses. Here is my code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast <unsigned int> (time(0)));
int compGuess = rand() % 100 +1; //Generates number between 1 - 100
int highestNumber = 100;
int lowestNumber = 1;
char ready;
char highLowSuccess;
bool success;
int tries = 0;
cout << "Please pick a number between 1 - 100. I will guess your number. Don't tell me what it is!\n\n";
do
{
cout << "Are you ready? (y/n)\n\n";
cin >> ready;
if (ready == 'y')
{
do
{
cout << "Is your number " << compGuess << "?\n\n";
cout << "High, Low or Success?";
++tries;
cin >> highLowSuccess; //User input telling the computer whether its too high, too low, or a success
if (highLowSuccess == 'h') //Executes code if number guessed was too high.
{
highestNumber = compGuess - 1; //Stores variable indicating the highest possible number based on user input
compGuess = rand() % highestNumber +1; //Generates a new random number between 1 and the new highest possible number
success = false;
}
else if (highLowSuccess == 'l') //Executes code if number guessed was too low.
{
lowestNumber = compGuess + 1;//Stores variable indicating the lowest possible number based on user input
compGuess = (rand() % highestNumber - lowestNumber + 1) + lowestNumber // <---- Not producing the desired result
success = false;
}
else if (highLowSuccess == 's') //Executes code if the computer's guess was correct.
{
cout << "I guessed your number! It only took me " << tries << " tries!";
success = true;
}
} while (success != true);
}
else
{
continue;
}
} while (ready != 'y');
return 0;
}
highestNumber is what the max should be and lowestNumber is what the min should be. I need an equation that lets me generate a random number while taking the highest and lowest possible numbers into account.
Forgive me if the answer is really simple, I'm a noob programmer. xD
To generate a random number between min and max, use:
int randNum = rand()%(max-min + 1) + min;
(Includes max and min)
Really fast, really easy:
srand(time(NULL)); // Seed the time
int finalNum = rand()%(max-min+1)+min; // Generate the number, assign to variable.
And that is it. However, this is biased towards the lower end, but if you are using C++ TR1/C++11 you can do it using the random header to avoid that bias like so:
#include <random>
std::mt19937 rng(seed);
std::uniform_int_distribution<int> gen(min, max); // uniform, unbiased
int r = gen(rng);
But you can also remove the bias in normal C++ like this:
int rangeRandomAlg2 (int min, int max){
int n = max - min + 1;
int remainder = RAND_MAX % n;
int x;
do{
x = rand();
}while (x >= RAND_MAX - remainder);
return min + x % n;
}
and that was gotten from this post.
If you have a C++11 compiler you can prepare yourself for the future by using c++'s pseudo random number faculties:
//make sure to include the random number generators and such
#include <random>
//the random device that will seed the generator
std::random_device seeder;
//then make a mersenne twister engine
std::mt19937 engine(seeder());
//then the easy part... the distribution
std::uniform_int_distribution<int> dist(min, max);
//then just generate the integer like this:
int compGuess = dist(engine);
That might be slightly easier to grasp, being you don't have to do anything involving modulos and crap... although it requires more code, it's always nice to know some new C++ stuff...
Hope this helps
- Luke
rand() % ((highestNumber - lowestNumber) + 1) + lowestNumber