Printing out a diceplot histogram - c++

When I complie and run my code I get the same output everytime despite having a random function. It defaults to the trial output shown on the assignment guide. I've tried to alter what's inside the print_histogram however each time I get the message in terminal that says I haven't declared "blank".
// ============================================================================
// diceplot.cpp
//
//
// ============================================================================
#include <iostream>
#include <cstdlib>
using namespace std;
// Prototype/define functions anywhere below
//loop that rolls dice and returns the dice number
int roll() {
int dice = rand() % 6 + 1;
return dice;
}
//loop that arranges the numbers and prints it out starting from index
void print_histogram(int list[], const int number_rolls){
for (int count = 0; count < number_rolls; count++){
cout << "\n" << count + 4 << ": ";
for (int index = 0; index < list[count]; index++){
cout << "X";
}
}
}
//given code
int main() {
int seed, n;
cout << "Enter a positive interger: " << endl;
cin >> seed >> n;
// Seed the pseudo-random number generator for repeatable results
srand(seed);
// Your code here
// keeps track of the outputs from the rolls
int list[21];
for (int count = 0; count < 21; count ++){
list[count] = count / 2;
}
//adds the roll of each experiment
int sum = 0;
for(int count = 0; count < n; count++) {
int dice_1 = roll();
int dice_2 = roll();
int dice_3 = roll();
int dice_4 = roll();
sum = dice_1 + dice_2 + dice_3 + dice_4;
if (sum == 21){
list[25 - 4]++;
break;
}
}
// prints out the histogram
print_histogram(list, 21);
return 0;
}

I copied the code you posted, formatted it, removed all of the comments, and then added my own comments:
#include <iostream>
#include <cstdlib>
using namespace std;
int roll() {
int dice = rand() % 6 + 1;
return dice;
}
void print_histogram(int list[], const int number_rolls) {
for (int count = 0; count < number_rolls; count++) {
cout << "\n" << count + 4 << ": ";
for (int index = 0; index < list[count]; index++) {
cout << "X";
}
}
}
int main() {
int seed, n;
cout << "Enter a positive interger: " << endl;
cin >> seed >> n;
// Here srand is called which does indeed seed the calls to rand. However,
// that doesn't change your output because your output is not showing
// anything that has to do with rand being called
srand(seed);
// This has exactly 21 elements, not n elements. Not sure if that was
// something you wrote or a default from your assignment
int list[21];
for (int count = 0; count < 21; count++) {
// This right here is what your histogram is currently showing. There
// is nothing random here, the value is the same every time
list[count] = count / 2;
}
int sum = 0;
for (int count = 0; count < n; count++) {
int dice_1 = roll();
int dice_2 = roll();
int dice_3 = roll();
int dice_4 = roll();
sum = dice_1 + dice_2 + dice_3 + dice_4;
// I don't know why the condition exists. As the code is currently
// written the dice rolls essentially have a chance to add up to 21 and
// cause the code inside the if statement to be executed
if (sum == 21) {
// 25 minus 4 is 21. Writting to index 21 is out of bounds because
// list only has 21 elements. This is undefined behavior
list[25 - 4]++;
break;
}
}
print_histogram(list, 21);
return 0;
}
I would suggest removing this section:
for (int count = 0; count < 21; count++) {
// This right here is what your histogram is currently showing. There
// is nothing random here, the value is the same every time
list[count] = count / 2;
}
... and replacing it with code that sets all elements of list to 0. Later on in the for loop responsible for rolling the four dice you can increment elements of list based on what the sum of the rolls are
Get rid of this:
if (sum == 21) {
// 25 minus 4 is 21. Writting to index 21 is out of bounds because
// list only has 21 elements. This is undefined behavior
list[25 - 4]++;
break;
}
... and replace it with code that increments the appropriate element of list regardless of what the value of sum is

Related

Getting the wrong output from arrays

#include <iostream>
const int turns = 2022;
int processing(int array[], int number, int index);
int main()
{
int numLine[turns]; //actual number line
//int counter = 0; //turns since last refference??
int previousNumber;
for (int i = 0; i < 7; i++) //for seven turns
{
std::cout << "Seed Number " << i+1 << ": "; //Seed Numer 1,2,3... :
std::cin >> numLine[i]; //input number
std::cout << std::endl; // endline
}
for (int i = 7; i < turns; i++) //for the entire length of the turns after 7
{
previousNumber = numLine[i - 1];
numLine[i] = processing(numLine, previousNumber, i-2); //set the current element of numLine to the processed number
std::cout << numLine[i] << " ";
}
}
int processing(int array[], int number, int index) //processing seeded with int number
{
int counter = -1; // number of turns since last referrence
for (int i = index; i >= 0; i--) //searches down from index to 0
{
if (array[i] == number) {
counter = i; //times since its been said
}
}
if (counter == -1)
{
return 0;
}
else
return counter;
//has been seen before so return the count
}
// 13,16,10,12,1,5,8 (seed numbers)
This is my code, this is the prompt that I was given to design my program: http://cis.scc.losrios.edu/~TownJ/dinosaur/memory.html
When inputting the seed numbers required for the prompt, the output I receive is 9 (for the 2022nd element of the array, this code outputs all the elements) but when putting that into the website, it is incorrect, as is the number before it. I can't see what I am doing wrong, could someone with more experience tell me what I messed up?
Thank you to everyone for your help, the following is my code and commented within is an explanation of such, the list of changes I made was big.
#include <iostream>
const int turns = 2022;
int processing(int array[], int number, int index);
int main()
{
int numLine[turns]; //actual number line
int previousNumber;
for (int i = 0; i < 7; i++) //for seven turns
{
std::cout << "Seed Number " << i+1 << ": "; //Seed Numer 1,2,3... :
std::cin >> numLine[i]; //input number
std::cout << std::endl; // endline
}
for (int i = 7; i < turns; i++) //for the entire length of the turns after 7
{
previousNumber = numLine[i - 1];
numLine[i] = processing(numLine, previousNumber, i); //set the current element of numLine to the processed number
std::cout << numLine[i] << " "; //displays current value with space
}
}
int processing(int array[], int number, int index) //processing seeded with array, previous value
//on numLine and index position of the for loop (which mirrors the array element index)
{
int counter = 0; //
for (int i = 0; i < index-1; i++) //loop starting at 0 and moving up to the position we are at in the array
{
if (array[i] == number) { //if the array element value at loop iteration i is the same as the previous number, then:
counter = index - i - 1; //set counter to the index position passed, minus the search loop iteration, minus 1
}
}
return counter; //return the current value of counter
}
// 13,16,10,12,1,5,8 (seed numbers)

Save first n prime numbers in an array without overwriting it

I'm trying to save first 20 prime numbers that are greater or equal than entered number.
Right now the output is 20 times 997 because values overwrite previous ones. I can't figure out what to do to limit them. When the array is full stop the loop or something so the overwriting won't happen?
bool is_prime(int num) {
if (num < 2) {
return false;
}
for (int i = 2; i <= num / 2; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
void fillArr(int arr[20], int num) {
for (int index = num; index <= 1000; index++) { //don't know how to set up
//2nd condition, depends on entered number
if (is_prime(index)) {
//save first 20 prime numbers that are >= num into an array
//Code fills the array with every prime it finds, setting it for all
//values and overwriting any previous primes it has found. Right now
//output would be the same 20 prime numbers closest to index 1000,
//based on second condition
for (int i = 0; i < 20; i++) {
arr[i] = index;
}
}
}
//print test
for (int i = 0; i < 20; i++) {
std::cout << arr[i] << "\t";
}
}
int main() {
int arr[20];
int num;
std::cout << "Enter number: ";
std::cin >> num;
fillArr(arr, num);
return 0;
}
In your code, initialize i to 0 at the beginning. Each time you encounter a prime, add it to your array and increment i. Break when i >= 20.
void fillArr(int arr[20], int num) {
int i = 0;
for (int index = num; index <= 1000 && i < 20; index++) {
if (is_prime(index)) {
arr[i++] = index;
}
}
//print test
for (int i = 0; i < 20; i++) {
std::cout << arr[i] << "\t";
}
}
Also note that this is not the most optimal way to find primes. For finding whether a given number is prime, you only need to check for whether it is divisible by primes uptil square root of the number (and not till n/2). You may also want to read about the Seive of Eratosthenes.
As also specified in the comments, it's better to use std::vector or std::array rather than raw arrays. In that case, you'd simply want to push_back(index) and break when vector's size >= 20.

Number of time the iterative function is called

Would like to seek a bit of help from StackOverflow. I am trying to print out the sequence of Fibonacci number and also the number of time the iterative function is called which is supposed to be 5 if the input is 5.
However, I am only getting 4199371 as a count which is a huge number and I am trying to solve the problem since four hours. Hope anyone who could spot some mistake could give a hint.
#include <iostream>
using namespace std;
int fibIterative(int);
int main()
{
int num, c1;
cout << "Please enter the number of term of fibonacci number to be displayed: ";
cin >> num;
for (int x = 0; x <= num; x++)
{
cout << fibIterative(x);
if (fibIterative(x) != 0) {
c1++;
}
}
cout << endl << "Number of time the iterative function is called: " << c1 << endl;
}
int fibIterative(int n)
{
int i = 1;
int j = 0;
for(int k = 1; k <= n; k++) {
j = i + j;
i = j - i;
}
return j;
}
First, initialize the variable
c1 = 0;
so that you will not get any garbage value get printed.
Secondly this:
if (fibIterative(x) != 0)
{
c1++;
}
will make 2*count - 1 your count. You don't need that.
Edit: I have noticed that you have removed extra c1++; from your first revision. Hence, the above problem is not more valid. However, you are calling the function fibIterative() again to have a check, which is not a good idea. You could have simply print c1-1 at the end, to show the count.
Thirdly,
for (int x = 0; x <= num; x++)
you are starting from 0 till equal to x that means 0,1,2,3,4,5 total of 6 iterations; not 5.
If you meant to start from x = 1, you need this:
for (int x = 1; x <= num; x++)
{ ^
cout << fibIterative(x) << " ";
c1++;
}

Sum of two arrays, carry over operation C++

Beginner here, and I'm stuck. The main program is provided to us, and we're supposed to write 3 functions. readBig(), addBig(), and printBig(). I'm stuck on the addBig() function. It's supposed to sum two arrays, and perform the carry operation. I cannot figure out where I'm going wrong. The carry operation is working out for me.
Any help/direction is appreciated.
#include <iostream>
using namespace std;
//This program will test three functions capable of reading, adding,
//and printing 100-digit numbers.
// Do not change these function prototypes:
void readBig(int[]);
void printBig(int[]);
void addBig(int[], int[], int[]);
// This constant should be 100 when the program is finished.
const int MAX_DIGITS = 100;
//There should be no changes made to the main program when you turn it
in.
int main(){
// Declare the three numbers, the first, second and the sum:
int num1[MAX_DIGITS], num2[MAX_DIGITS], sum[MAX_DIGITS];
bool done = false;
char response;
while (not done)
{
cout << "Please enter a number up to "<<MAX_DIGITS<< " digits: ";
readBig(num1);
cout << "Please enter a number up to "<<MAX_DIGITS<< " digits: ";
readBig(num2);
addBig(num1, num2, sum);
printBig(num1);
cout << "\n+\n";
printBig(num2);
cout << "\n=\n";
printBig(sum);
cout << "\n";
cout <<"test again?";
cin>>response;
cin.ignore(900,'\n');
done = toupper(response)!='Y';
}
return 0;
}
//ReadBig will read a number as a string,
//It then converts each element of the string to an integer and stores
it in an integer array.
//Finally, it reverses the elements of the array so that the ones digit
is in element zero,
//the tens digit is in element 1, the hundreds digit is in element 2,
etc.
void readBig(int num[])
{
for(int i = 0; i < MAX_DIGITS; i++){
num[i] = 0;
}
string numStr;
getline(cin,numStr);
string temp;
//store into array
for (int i = 0; i < numStr.length(); i++){
temp = numStr.at(i);
num[i] = stoi(temp);
}
int arrayLength = MAX_DIGITS;
int temp2;
for (int i = 0; i < (arrayLength/2); i++){
temp2 = num[i];
num[i] = num[(arrayLength - 1) - i];
num[(arrayLength - 1) - i] = temp2;
}
}
//AddBig adds the corresponding digits of the first two arrays and
stores the answer in the third.
//In a second loop, it performs the carry operation.
void addBig(int num1[], int num2[], int sum[])
{
for (int i = 0; i < MAX_DIGITS; i++){
sum[i] = num1[i] + num2[i];
if (sum[i] > 9){
sum[i] = sum[i] - 10;
sum[i+1] = sum[i+1] + 10;
}
}
}
//PrintBig uses a while loop to skip leading zeros and then uses a for
loop to print the number.
void printBig(int array[])
{
int i = 0;
while (array[i] == 0){
i++;
}
for (int j = i; j < MAX_DIGITS;j++){
cout << array[j] << endl;
}
}
Looks like readBig function isn't correct, it stores least significiant digit into num[numStr.length()-1], after reversing it became num[MAX_DIGITS -1 - ( numStr.length()-1], but addNum assumes last digit is num[0].
Correct variant:
void readBig(int num[])
{
//clear num, read numStr...
//store into array
int count = 0;
for (int i = numStr.length()-1; i >= 0; --i){
temp = numStr.at(i);
num[count++] = stoi(temp);
}
|
So this
sum[i] = sum[i] - 10;
sum[i+1] = sum[i+1] + 10;
should most likely be this
sum[i] = sum[i] - 10;
sum[i+1] = sum[i+1] + 1;
Since its the next decimal place it shouldnt be incremented by 10
Also when you get to the last cell in your array
sum[i+1] = sum[i+1] + 1;
this will be out of bounds, so depending on the requirments you will want to change this

C++ Birthday Probability

I am trying to teach myself C++ in preparation for graduate school this coming fall but I am having some trouble with this birthday paradox problem. My code seems to run ok but I am not getting the correct output. If anyone has any suggestions please let me know.
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
const int trials = 100000;
int birthdays[50];
int numMatches;
for(int i = 2; i <= 50; i++)
{
numMatches = 0;
for(int j = 1; j <= trials; j++)
{
for(int k = 1; k <= i; k++)
{
birthdays[k] = (rand() % 365) + 1;
}
int m = 1;
bool matched = false;
while(m < i && !matched){
int n = m + 1;
while(n <= i && !matched){
if(birthdays[m] == birthdays[n]){
numMatches++;
matched = true;
}
n++;
}
m++;
}
}
cout << "Probability of " << i << " people in a room sharing a birthday is \t"
<< ( float(numMatches) / float(trials) ) << endl;
}
}
Your code is not computing the probability of two people in a room of 50 sharing a birthday. There's several bugs, mostly with indexing, but here's the biggest issue:
for(int j = 1; j <= trials; j++) {
// assigns a random birthday to the first i people (should be 0 indexed)
for(k = 1; k <= i; k++)
birthdays[k] = (rand() % 365) + 1;
// Does *exactly* the same thing as the previous loop, overwriting what
// the initial loop did. Useless code
for(m = 1; m <= i; m++)
birthdays[m] = (rand() % 365) + 1;
// At this point, m = k = i + 1. Here you check if
// the i + 1st array value has the same b-day. It will, because they're
// the same thing. Note you never set the i + 1st value so the loops
// above did nothing
if(birthdays[k] == birthdays[m])
++numMatches;
}
So what you've got here is something like:
Perform 48 iterations of the following (from your first loop which goes from 2 to 50: no idea where those values came from)
For each of those 48 iterations, perform 10k iterations of:
assign a bunch of random stuff to an array overwriting stuff
Ignore the values you wrote in the array, do a comparison that's always true and increment numMatches by 1
Consider what's going on here:
for(int j = 1; j <= trials; j++) {
for(k = 1; k <= i; k++)
birthdays[k] = (rand() % 365) + 1;
for(m = 1; m <= i; m++)
birthdays[m] = (rand() % 365) + 1;
if(birthdays[k] == birthdays[m])
++numMatches;
}
You go through i birthdays and assign a random number, then you go through the same i birthdays and assign them a new random number. Then you try to find a match for just one value of k and m (which both happen to equal i+1, which isn't one of the values set!).
My suggestion is to break the problem down into smaller units that will make it easier to figure out how to code - here are the functions I would try to write.
/* randomizeBirthdays()
* Put n random birthdays into the pre-allocated array birthdays.
* birthdays must of course be of length <= n.
*/
void randomizeBirthdays(int * birthdays, int n);
/* hasMatchingBirthdays()
* Check if birthdays array has two people with the same birthday
* in the first n entries.
* Return value is boolean.
*/
bool hasMatchingBirthdays(int * const birthdays, int n);
/* probabilityOfMatch()
* Calculate the probability that at least 2 out of n people will
* have the same birthday, using nTrials number of trials.
* Return value is double.
*/
double probabilityOfMatch(int n, int nTrials);
If you break it down like this it becomes easier to write and easier to troubleshoot.
As I said in comments already:
I think your aim is to test if 2 people in room of 2-50 people share
birthday, not if 2-50 people share birthday as you say in output. And
that's 2 people out of 23 have 50.7%, not 24.
I completely reworked your code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
#define DAYS_IN_YEAR 365
#define TRIALS 10000
void clearArray (bool * array)
{
for (int i = 0; i < DAYS_IN_YEAR; i++)
array[i] = false;
}
int main()
{
srand(time(NULL));
bool birthdays[DAYS_IN_YEAR]; //we are trying to hit same day in year twice
int r, numMatches;
for(int i = 2; i < 50; i++)
{
numMatches = 0;
for(int j = 0; j < TRIALS; j++)
{
clearArray(birthdays);
for(int k = 0; k < i; k++)
{
r = rand() % DAYS_IN_YEAR; // == 0-364
if (birthdays[r])
{
numMatches++;
break; // 2 people already have same birthdays here
}
birthdays[r] = true;
}
}
cout << "Probability of 2 people having same birthday in room of " << i << " people is "
<< (float)numMatches / TRIALS << endl;
}
}
Output:
Probability of 2 people having same birthday in room of 23 people is 0.516
I think the code must be something like this.
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
int main() {
srand(time(NULL));
int birthdays[10000][50];
int numMatches;
int trials=10000,check;
for(int n=0;n<trials;n++)
{
for(int j=0;j<50;j++)
{
birthdays[n][j]=rand()%365+1;
}
}
for(int i=2;i<=50;i++)
{
numMatches=0;
for(int n=0;n<trials;n++)
{
check=1;
for(int j=0;j<i;j++)
{
for(int k=j+1;k<=i;k++)
{
if(birthdays[n][j]==birthdays[n][k]&&check)
{
numMatches++;
check=0;
}
}
}
}
cout << "Probability of " << i << " people in a room sharing a birthday is \t" <<
(static_cast<float>(numMatches) / (trials)) << endl;
}
}