How do I randomize these numbers? - c++

So my homework assignment is to create a looping function to print only even numbers from 0 – 200. I need to create 100 random and even numbers(only 10 numbers can print per line). I'm having trouble randomizing the numbers. This is what I have so far:
// Loop from 0 to 200
for (i = 2, j = 1; i <= 200; i++, j++)
{
// Print even numbers(divisible by 2)
if (i % 2 == 0)
{
cout << i;
}
// Create new line after printing 10 numbers
if (j == 20)
{
j = 0;
ofs << '\n';
}
}

#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h>
int main()
{
srand (time(NULL));
int even = rand() % 200;
if (even % 2 == 0)
{
cout<<even;
}
}

Here is some quick code that prints 100 even numbers [0..200] in a random order without repeating them:
#define PRIME 7879 /* Some big prime number (>> 100) */
#define NUMS 100 /* Number of values to process */
#define PRINT_GROUP 10 /* Number of values printed on a line */
int main()
{
int number = rand() % NUMS;
int i;
for (i = 0; i < NUMS; i++) {
printf("%d%c", 2*number, (i + 1) % PRINT_GROUP == 0 ? '\n' : ' ');
number = (number + PRIME) % NUMS;
}
return 0;
}

Apart from that, your code is a little off the way.
Here are some things that may be confusing to other coders (.. anyways if you feel comfortable with your style that's really ok)
"for (i = 2, j = 1; i <= 200; i++, j++)" 2 Variables are a little bit wierd,
try to use only one variable. .. Just make it something like this:
int j = 1;
for (i = 2; i <= 200; i++) {
j++;
//Code
if (j == 20) {
j = 0; //etc.
}
}
Beside that "J" looks familliar to "I" so that could confuse others.. try to call it "count", that's pretty standard.

Related

Unıque Random Number Check form Array c++

#include <iostream>
#include<ctime>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
int main()
{
bool cont = false;
string str;
int num, num2;
cin >> str >> num;
int arr[10];
int a = pow(10, num);
int b = pow(10, (num - 1));
srand(static_cast<int>(time(NULL)));
do {
num2 = rand() % (a - b) + b;
int r;
int i = 0;
int cpy = num2;
while (cpy != 0) {
r = cpy % 10;
arr[i] = r;
i++;
cpy = cpy / 10;
}
for (int m = 0; m < num; m++)
{
for (int j = 0; j < m; j++) {
if (m != j) {
if (arr[m] == arr[j]) {
break;
}
else {
cont = true;
}
}
}
}
cout << num2 << endl;
} while (!cont);
return 0;
}
I want to take a number from the user and produce such a random number.
For example, if the user entered 8, an 8-digit random number.This number must be unique, so each number must be different from each other,for example:
user enter 5
random number=11225(invalid so take new number)
random number =12345(valid so output)
To do this, I divided the number into its digits and threw it into the array and checked whether it was unique. The Program takes random numbers from the user and throws them into the array.It's all right until this part.But my function to check if this number is unique using the for loop does not work.
Because you need your digits to be unique, it's easier to guarantee the uniqueness up front and then mix it around. The problem-solving principle at play here is to start where you are the most constrained. For you, it's repeating digits, so we ensure that will never happen. It's a lot easier than verifying if we did or not.
This code example will print the unique number to the screen. If you need to actually store it in an int, then there's extra work to be done.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>
int main() {
std::vector<int> digits(10);
std::iota(digits.begin(), digits.end(), 0);
std::shuffle(digits.begin(), digits.end(), std::mt19937(std::random_device{}()));
int x;
std::cout << "Number: ";
std::cin >> x;
for (auto it = digits.begin(); it != digits.begin() + x; ++it) {
std::cout << *it;
}
std::cout << '\n';
}
A few sample runs:
Number: 7
6253079
Number: 3
893
Number: 6
170352
The vector digits holds the digits 0-9, each only appearing once. I then shuffle them around. And based on the number that's input by the user, I then print the first x single digits.
The one downside to this code is that it's possible for 0 to be the first digit, and that may or may not fit in with your rules. If it doesn't, you'd be restricted to a 9-digit number, and the starting value in std::iota would be 1.
First I'm going to recommend you make better choices in naming your variables. You do this:
bool cont = false;
string str;
int num, num2;
cin >> str >> num;
What are num and num2? Give them better names. Why are you cin >> str? I can't even see how you're using it later. But I presume that num is the number of digits you want.
It's also not at all clear what you're using a and b for. Now, I presume this next bit of code is an attempt to create a number. If you're going to blindly try and then when done, see if it's okay, why are you making this so complicated. Instead of this:
num2 = rand() % (a - b) + b;
int r;
int i = 0;
int cpy = num2;
while (cpy != 0) {
r = cpy % 10;
arr[i] = r;
i++;
cpy = cpy / 10;
}
You can do this:
for(int index = 0; index < numberOfDesiredDigits; ++index) {
arr[index] = rand() % 10;
}
I'm not sure why you went for so much more complicated.
I think this is your code where you validate:
// So you iterate the entire array
for (int m = 0; m < num; m++)
{
// And then you check all the values less than the current spot.
for (int j = 0; j < m; j++) {
// This if not needed as j is always less than m.
if (m != j) {
// This if-else is flawed
if (arr[m] == arr[j]) {
break;
}
else {
cont = true;
}
}
}
}
You're trying to make sure you have no duplicates. You're setting cont == true if the first and second digit are different, and you're breaking as soon as you find a dup. I think you need to rethink that.
bool areAllUnique = true;
for (int m = 1; allAreUnique && m < num; m++) {
for (int j = 0; allAreUnique && j < m; ++j) {
allAreUnique = arr[m] != arr[j];
}
}
As soon as we encounter a duplicate, allAreUnique becomes false and we break out of both for-loops.
Then you can check it.
Note that I also start the first loop at 1 instead of 0. There's no reason to start the outer loop at 0, because then the inner loop becomes a no-op.
A better way is to keep a set of valid digits -- initialized with 1 to 10. Then grab a random number within the size of the set and grabbing the n'th digit from the set and remove it from the set. You'll get a valid result the first time.

Why is this code not working for big number?

I'm doing question 4.11 in Bjarne Stroustrup Programming-Principles and Practice Using C++.
Create a program to find all prime numbers in the range from 1 to max using a vector of primes in order(prime[2,3,5,...]). Here is my solution:
#include <iostream>
#include <string>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
bool check_prime(vector<int> &prime, int n) {
int count = 0;
for (int i = 0; prime[i] <= n || i <= prime.size() - 1; ++i) {
if (n % prime[i] == 0) {
count++;
break;
}
}
bool result = 0;
if (count == 0)
result = 1;
else
result = 0;
return result;
}
int main() {
vector<int> prime{2};
int max;
cout << "Please enter a max value:";
cin >> max;
for (int i = 2; i <= max; ++i) {
if (check_prime(prime, i))
prime.push_back(i);
}
for (int i = 0; i <= prime.size() - 1; ++i) {
cout << prime[i];
if (i <= prime.size() - 2)
cout << ',';
}
}
My code is working for numbers smaller than 23 but fail to work for anything bigger. If I open the program in Windows 10 the largest working number increase to 47, anything bigger than that fail to work.
This condition
prime[i]<=n||i<=prime.size()-1
makes the loop continue as long as at least one of them is true, and you're accessing prime[i] without checking the value of i.
This will cause undefined behaviour as soon as i == prime.size().
This means that anything can happen, and that you're experiencing that any specific values are working is just an unfortunate coincidence.
You need to check the boundary first, and you should only continue for as long as both conditions are true:
i <= prime.size() - 1 && prime[i] <= n
which is more idiomatically written
i < prime.size() && prime[i] <= n
(It's never too soon to get comfortable with the conventional half-open intervals.)
You check prime[i]<=n before i<=prime.size()-1. Then, if it's true (even if i>prime.size()-1, which is random behaviour), you work on it, generating wrong results.

Improving optimization of nested loop

I'm making a simple program to calculate the number of pairs in an array that are divisible by 3 array length and values are user determined.
Now my code is perfectly fine. However, I just want to check if there is a faster way to calculate it which results in less compiling time?
As the length of the array is 10^4 or less compiler takes less than 100ms. However, as it gets more to 10^5 it spikes up to 1000ms so why is this? and how to improve speed?
#include <iostream>
using namespace std;
int main()
{
int N, i, b;
b = 0;
cin >> N;
unsigned int j = 0;
std::vector<unsigned int> a(N);
for (j = 0; j < N; j++) {
cin >> a[j];
if (j == 0) {
}
else {
for (i = j - 1; i >= 0; i = i - 1) {
if ((a[j] + a[i]) % 3 == 0) {
b++;
}
}
}
}
cout << b;
return 0;
}
Your algorithm has O(N^2) complexity. There is a faster way.
(a[i] + a[j]) % 3 == ((a[i] % 3) + (a[j] % 3)) % 3
Thus, you need not know the exact numbers, you need to know their remainders of division by three only. Zero remainder of the sum can be received with two numbers with zero remainders (0 + 0) and with two numbers with remainders 1 and 2 (1 + 2).
The result will be equal to r[1]*r[2] + r[0]*(r[0]-1)/2 where r[i] is the quantity of numbers with remainder equal to i.
int r[3] = {};
for (int i : a) {
r[i % 3]++;
}
std::cout << r[1]*r[2] + (r[0]*(r[0]-1)) / 2;
The complexity of this algorithm is O(N).
I've encountered this problem before, and while I don't find my particular solution, you could improve running times by hashing.
The code would look something like this:
// A C++ program to check if arr[0..n-1] can be divided
// in pairs such that every pair is divisible by k.
#include <bits/stdc++.h>
using namespace std;
// Returns true if arr[0..n-1] can be divided into pairs
// with sum divisible by k.
bool canPairs(int arr[], int n, int k)
{
// An odd length array cannot be divided into pairs
if (n & 1)
return false;
// Create a frequency array to count occurrences
// of all remainders when divided by k.
map<int, int> freq;
// Count occurrences of all remainders
for (int i = 0; i < n; i++)
freq[arr[i] % k]++;
// Traverse input array and use freq[] to decide
// if given array can be divided in pairs
for (int i = 0; i < n; i++)
{
// Remainder of current element
int rem = arr[i] % k;
// If remainder with current element divides
// k into two halves.
if (2*rem == k)
{
// Then there must be even occurrences of
// such remainder
if (freq[rem] % 2 != 0)
return false;
}
// If remainder is 0, then there must be two
// elements with 0 remainder
else if (rem == 0)
{
if (freq[rem] & 1)
return false;
}
// Else number of occurrences of remainder
// must be equal to number of occurrences of
// k - remainder
else if (freq[rem] != freq[k - rem])
return false;
}
return true;
}
/* Driver program to test above function */
int main()
{
int arr[] = {92, 75, 65, 48, 45, 35};
int k = 10;
int n = sizeof(arr)/sizeof(arr[0]);
canPairs(arr, n, k)? cout << "True": cout << "False";
return 0;
}
That works for a k (in your case 3)
But then again, this is not my code, but the code you can find in the following link. with a proper explanation. I didn't just paste the link since it's bad practice I think.

Armstrong numbers. print armstrong numbers

I kindly request those who think this question have been asked earlier, read on first.
I need to print all armstrong numbers between 1 and 10000. My problem is that whenever my program is run and reaches 150, it does
(1^3) + ((5^3)-1) + (0^3)
instead of
(1^3) + (5^3) + (0^3).
Thus it does not print 153 (which is an Armstrong number), of course because the sum results in 152. I do not know if some other numbers are also doing this. But i do have checked untill 200 and there is no problem with other numbers except that in 150–160 range.
Is this a compiler error. Should i re-install my compiler? Currently i am using codeblocks.
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
for(int i = 0;i <= 10000;++i)
{
int r = i;
int dig = 0;
while(r != 0)
{
dig++;
r /= 10;
}
int n = i, sum = 0;
while(n != 0)
{
int d = n % 10;
sum += pow(d, dig);
n /= 10;
}
if(sum == i)
cout << i << ' ';
}
cout << "\n\n\n";
return 0;
}
You should run your code in the debugger. Also your code does not compile for me (GCC 6) because you use cout without std:: or using namespace std;. So how does it compile on your system? You are also using math.h, in C++ you should rather use cmath.
After fixing this, I get the following output on my Fedora 24 with g++ in version 6.4.1:
0 1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474
The 153 is included in there, so either your compiler has an error or your program has undefined behavior and therefore the error ensues.
I have looked at the definition for Armstrong numbers and did a really short Python implementation:
# Copyright © 2017 Martin Ueding <dev#martin-ueding.de>
# Licensed under the MIT/Expat license.
def is_armstrong(number):
digits = [int(letter) for letter in str(number)]
score = sum(digit**len(digits) for digit in digits)
return score == number
armstrong = list(filter(is_armstrong, range(10000)))
print(' '.join(map(str, armstrong)))
The output matches your C++ program on my machine exactly:
0 1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474
Looking through your code I cannot spot undefined behavior, it looks sensible. First you count the number of digits, then you build up the sum. Perhaps you should try with other compilers like GCC, LLVM, or Ideone. Does Code Blocks ship their own compiler or do they use a system compiler? What operating system are you running?
You said that you are just learning to program. That's cool to hear! I hope you have a good C++ book or other resource. For C++, there is a lot of bad advice on the internet. Also make sure that you have a book that has at least C++11, everything else is badly outdated.
I have changed your program and created some short functions that do just one task such that it is easier to read and reason about. I am not sure whether you already know about functions, so don't worry if that seems to complicated for now :-).
#include <cmath>
#include <iostream>
int get_digit_count(int const number) {
int digits = 0;
int remainder = number;
while (remainder > 0) {
++digits;
remainder /= 10;
}
return digits;
}
bool is_armstrong_number(int const number) {
int const digit_count = get_digit_count(number);
int remainder = number;
int sum = 0;
while (remainder > 0) {
int const last_digit = remainder % 10;
sum += std::pow(last_digit, digit_count);
remainder /= 10;
}
return number == sum;
}
int main() {
for (int i = 0; i <= 10000; ++i) {
if (is_armstrong_number(i)) {
std::cout << i << ' ';
}
}
std::cout << std::endl;
}
This algorithm generates and prints out Armstrong numbers to 999, but can easily be expanded to any length using the same methodology.
n = 1; %initialize n, the global loop counter, to 1
for i = 1 : 10 %start i loop
for j = 1 : 10 %start j loop
for k = 1 : 10 %start k loop
rightnum = mod(n, 10); %isolate rightmost digit
midnum = mod(fix((n/10)), 10); %isolate middle digit
leftnum = fix(n/100); %isolate leftmost digit
if ((n < 10)) %calulate an for single-digit n's
an = rightnum;
end
if ((n > 9) & (n < 100)) %calculate an for 2-digit n's
an = fix(rightnum^2 + midnum^2);
end
if ((n > 99) & (n < 1000)) %calculate an for 3-digit n's
an = fix(leftnum^3 + midnum^3 + rightnum^3);
end
if (n == an) %if n = an display n and an
armstrongmatrix = [n an];
disp(armstrongmatrix);
end
n = n + 1; %increment the global loop counter and continue
end
end
end
You can use arrays:
#include<iostream>
using namespace std;
int pow(int, int);
int checkArm(int);
int main() {
int range;
cout<<"Enter the limit: ";
cin>>range;
for(int i{};i<=range;i++){
if(checkArm(i))
cout<<i<<endl;
}
return 0;
}
int pow(int base, int exp){
int i{0};
int temp{base};
if(exp!=0)
for(i;i<exp-1;i++)
base = base * temp;
else
base=1;
return base;
}
int checkArm(int num) {
int ar[10], ctr{0};
int tempDigits{num};
while(tempDigits>0){
tempDigits/=10;
ctr++;
}
int tempArr{num}, tempCtr{ctr};
for(int i{0};i<=ctr;i++){
ar[i] = tempArr / pow(10,tempCtr-1);
tempArr = tempArr % pow(10,tempCtr-1);
tempCtr--;
}
int sum{};
for(int k{};k<ctr;k++){
sum+=pow(ar[k],ctr);
}
if(sum==num)
return 1;
else
return 0;
}

Duplicates in X element array

I have an interval (m,n) and there I have to print out all the numbers which have different digits. I wrote this, but it only works for 2 digit numbers. I simply do not know how to make it work for anything but 2 digit numbers. I imagine that, if I added as much for loops as the digits of my number it would work, but the interval(m,n) isn't specified so it has to be something reliable. I've been trying to solve this problem on my own for 6 damn hours and I'm absolutely fed up.
Input 97,113;
Output 97,98,102,103,104,105,106,107,108,109
Numbers 99,100,101,110+ don't get printed, because they have 2 digits that are
the same.
#include<conio.h>
#include<math.h>
#include<stdio.h>
int main()
{
int m,n,test,checker=0;
scanf("%d%d",&m,&n);
if(m>n)
{
int holder=n;
n=m;
m=holder;
}
for(int start=m;start<=n;start++)
{
int itemCount=floor(log10(abs(start)))+1;
int nums[itemCount];
int index=0;
test=start;
do
{
int nextVal = test % 10;
nums[index++]=nextVal;
test = test / 10;
}while(test>0);
for (int i = 0; i < itemCount - 1; i++)
{ // read comment by #nbro
for (int j = i + 1; j < itemCount; j++)
{
if (nums[i] == nums[j])
{
checker++;
}
}
if(checker==0)printf("%d ",start);
}
checker=0;
}
}
Since you tagged this as C++, here is a very simple solution using simple modulus and division in a loop. No conversion to string is done.
#include <iostream>
#include <bitset>
bool is_unique_digits(int num)
{
std::bitset<10> numset = 0;
while (num > 0)
{
// get last digit
int val = num % 10;
// if bit is on, then this digit is unique
if (numset[val])
return false;
// turn bit on and remove last digit from number
numset.set(val);
num /= 10;
}
return true;
}
int main()
{
for (int i = 97; i <= 113; ++i)
{
if (is_unique_digits(i))
std::cout << i << "\n";
}
}
The is_unique_digit function simply takes the number and repeatedly extracts the digits from it by taking the last digit in the number. Then this digit is tested to see if the same digit appears in the bitset. If the number already exists, false is immediately returned.
If the number is not in the bitset, then the bit that corresponds to that digit is turned "on" and the number is divided by 10 (effectively removing the last digit from the number). If the loop completes, then true is returned.
Live Example
As an idea for a design:
print the number to a string, if it isn't a string already;
declare an array of int d[10]; and set it to all zeroes
for each ascii digit c of the string,
if (d[c-'0']==1) return 0; // this digit exists already in the number
else d[c-'0']= 1;
just put if(checker==0)printf("%d ",start); outside of second loop the loop
like this
for (int i = 0; i < itemCount - 1; i++)
{
for (int j = i + 1; j < itemCount; j++)
{
if (nums[i] == nums[j])
{
checker++;
break;
}
}
}
if(checker==0)
printf("%d ",start);
checker=0;
However instead of using two nested for loop you can use count array which is more efficient
to check 1 number, you can do
X=10; //number to analyze
char counts[10]; for int i=0;i<10;i++) counts[i]=0;
char number[10];
sprintf(&number,"%s",X); bool bad=false;
for(int i=0;i<strlen(number);i++)
{
if(++counts[number[i]-'0']>1) {bad=true;break;}
}`