I have written this piece of code which is supposed to simulate throwing dice many many times and counting that how many times each face is up. I have attached the output down there and as you can see it looks kind of strange. For example face 5 comes up exactly 10 times, faces 2, 3, 4 are about the same and face 6 comes zero in two rounds. The only face which acts about normal is 1.
Can anyone explain this to me? Is this normal? Am I doing something wrong or is it something related to my system?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
unsigned long int freq1, freq2, freq3, freq4, freq5, freq6;
unsigned long int L00p = 1;
unsigned short int DF;
while (L00p <= 6e7){
srand (time(NULL));
DF = 1 + (rand ()%6);
switch (DF)
{
case 1:
++freq1;
break;
case 2:
++freq2;
break;
case 3:
++freq3;
break;
case 4:
++freq4;
break;
case 5:
++freq5;
break;
case 6:
++freq6;
break;
default:
break;}
++L00p;
}
printf ("%s%25s\n", "Dice's Face", "Face Frequency");
printf ("1%25lu\n", freq1);
printf ("2%25lu\n", freq2);
printf ("3%25lu\n", freq3);
printf ("4%25lu\n", freq4);
printf ("5%25lu\n", freq5);
printf ("6%25lu\n", freq6);
return 0;
}
and here is the program's output after four times running it:
You don't initialize the frequency counters, so they'll likely contain garbage from the stack. (So yes, you were getting randomness, but not the randomness you want.)
You don't want to call srand() in the loop, but only once before it. Calling srand() with the same number (and time(NULL) will quite inevitably return the same second in a tight loop) will reset the rand() generator to return the same sequence of numbers, and since you only ever call rand() once before calling srand() again, you'll get a whole bunch of the same number.
The following version works fine, but you'd have a better time with an array.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
unsigned long int freq1 = 0, freq2 = 0, freq3 = 0, freq4 = 0, freq5 = 0,
freq6 = 0;
srand(time(NULL));
for (int loop = 0; loop < 1000; loop++) {
int DF = 1 + (rand() % 6);
switch (DF) {
case 1:
++freq1;
break;
case 2:
++freq2;
break;
case 3:
++freq3;
break;
case 4:
++freq4;
break;
case 5:
++freq5;
break;
case 6:
++freq6;
break;
default:
break;
}
}
printf("%s%25s\n", "Dice's Face", "Face Frequency");
printf("1%25lu\n", freq1);
printf("2%25lu\n", freq2);
printf("3%25lu\n", freq3);
printf("4%25lu\n", freq4);
printf("5%25lu\n", freq5);
printf("6%25lu\n", freq6);
return 0;
}
Example output:
Dice's Face Face Frequency
1 177
2 160
3 166
4 169
5 155
6 173
For reference, a version using an array of 6 ints:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
unsigned long int freqs[6] = {0};
srand(time(NULL));
for (int loop = 0; loop < 1000; loop++) {
freqs[rand() % 6] ++;
}
printf("%s%25s\n", "Dice's Face", "Face Frequency");
for(int face = 0; face < 6; face++) {
printf("%d%25lu\n", face + 1, freqs[face]);
}
return 0;
}
Here is an annotated adaptation of your code for educational purposes. You've learned about "loops", so here is an application for a do/while() loop.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Global variables are frowned upon because as the code grows more complex
// it is difficult or impossible to see where a value may be changed (inappropriately)
// For a tiny program like this that is unlikely to grow
// this proves the global variables are, by default, initialised to zero.
unsigned long int freq1, freq2, freq3, freq4, freq5, freq6;
int main() {
unsigned long int L00p = 0; // "local" var initialised. Good!
srand( time( NULL ) ); // called once at start of program.
do {
switch( ( rand() % 6 ) ) { // braces consistent with your main()
case 1: ++freq1; break; // get used to base-0 counting
case 2: ++freq2; break;
case 3: ++freq3; break;
case 4: ++freq4; break;
case 5: ++freq5; break;
case 0: ++freq6; break; // Ha-ha!! modulo!!!
default: printf( "A miracle has happened!!\n" );
break;
} // DO NOT hide that closing brace as you did. Prominent!
} while( ++L00p < 6e3 ); // increment counter after each loop done
// Swapped your output columns
// Using one format specifier for header and one for counts
// Notice how easy to modify only one instance?
char *tFmt = "%9s : %s Loops = %d\n";
char *oFmt = "%9lu : %d\n";
printf( tFmt, "Frequency", "Face", L00p );
// and... why not???
for( L00p = 0; L00p < 6; L00p++ ) {
int n; // not init'd because used immediately
switch( L00p ) {
case 1: n = freq1; break;
case 2: n = freq2; break;
case 3: n = freq3; break;
case 4: n = freq4; break;
case 5: n = freq5; break;
case 0: n = freq6; break;
}
printf( oFmt, n, L00p + 1 );
}
return 0;
}
Output
Frequency : Face Loops = 6000
958 : 1
1038 : 2
1018 : 3
1031 : 4
956 : 5
999 : 6
Again, for a simple, small piece of code like this, being able to see the entire switch block and compare values at a glance, concatenating statements can AID in writing bug-free code.
Related
This might be a silly question, but I am unable to find the solution. Function mat is not being called after giving input to variable n.
#include <stdio.h>
#include <stdlib.h>
int mat(int n)
{
printf("hello");
int temp = n, count = 0;
while (temp != 0)
{
temp = n % 10;
switch (temp)
{
case 1:
count += 2;
break;
case 7:
count += 3;
break;
case 4:
count += 4;
break;
case 2:
case 3:
case 5:
count += 5;
break;
case 6:
case 0:
case 9:
count += 6;
break;
case 8:
count += 7;
break;
}
}
return count;
}
int main(void)
{
int t, n, h;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
h = mat(n);
printf("%d\n", h);
}
}
I think something is wrong with scanf but don't know what it is.
this program was to give the output for number of matches being used for particular number.
Forgive me. A common mistake of beginners is to "get into the weeds" without properly considering the nature of a problem. Lines and lines of code are written that fiddle with particular micro-aspects of the problem.
From the OP code, it appears you want to sum various amounts to a total based on the digits found in the user's number. Since 0-9 are "contiguous", a contiguous array of those values (with duplicates) can serve and reduce the amount of code that is copy/paste/adapted. You will spend many more hours READING code than writing code. Try to make the code as simple to understand (and reliable) as possible. Potential bugs will LEAP OFF THE SCREEN when you do this and your code will be appreciated by others.
#include <stdio.h>
#include <stdlib.h>
int mat( int n ) {
printf( "hello\n" );
// contiguous array of 10 values (some repeated)
int incr[] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 };
int count = 0;
// sum from array values based on digits of value received
do {
count += incr[ n % 10 ];
} while( n /= 10 );
return count;
}
int main( void ) {
int t = 0; // ALWAYS initiaialise variables
scanf( "%d", &t );
while( t-- ) {
int n = 0; // declare variables close to use
scanf( "%d", &n );
// No need for 'h'. print returned value directly.
printf( "%d ==> %d\n", n, mat( n ) );
}
}
ive recently started reading a book about C and came across this exercise. Make a program that reads 100 integers and outputs the number that has been entered the most consecutive times without the use of arrays. Now the way i solved this is probably the dumbest one there is. I basically "use an array" without having it be an actual array and i have to do everything the hard way. Is there a better way to do this without actual arrays? Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int zero, one, two, three ,four,
five, six, seven, eight, nine;
int i,j,num,prev = -1;
srand(time(NULL));
for(i=0;i<100;i++){
num = rand()%10;
printf("%d\n", num);
if(num==prev){
switch(num){
case 0: zero++;
case 1: one++;
case 2: two++;
case 3: three++;
case 4: four++;
case 5: five++;
case 6: six++;
case 7: seven++;
case 8: eight++;
case 9: nine++;
}
}
prev = num;
}
num = 0;
//comparing the number of times of each number
if(num<zero){
num=zero;
j=0;
}
if(num<one){
num=one;
j=1;
}
if(num<two){
num=two;
j=2;
}
if(num<three){
num=three;
j=3;
}
if(num<four){
num=four;
j=4;
}
if(num<five){
num=five;
j=5;
}
if(num<six){
num=six;
j=6;
}
if(num<seven){
num=seven;
j=7;
}
if(num<eight){
num=eight;
j=8;
}
if(num<nine){
num=nine;
j=9;
}
printf("Number is %d", j);
return 0;
}
Im writing a program to give the user options whether they want to:
Add random numbers to an array
Print array
Search for an element in an array
Left shift array
These have to be in separate functions and it needs to b recursive and until the user wants to finish it keeps running my code is:
int main()
{
int array[M][N];
int ans;
puts("Please enter what you would like to do:\n
1: Create an array with random values\n
2: Print Array\n
3: Search for a number in an array\n
4: Shift each value to the left");
scanf("%d",&ans);
switch(ans) {
case 1:
PopulateRandom2D(array);
break;
case 2:
PrintArray(array);
break;
case 3:
LinearSearch2D(array);
break;
case 4:
LeftShift(array);
break;
default:
puts("Goodybye");
return 0;
}
main();
return 0;
}
void PopulateRandom2D(int array[][N])
{
int r,c;
srand(time(NULL));
for(r = 0; r < M; r++) {
for(c = 0; c < N; c++) {
array[r][c] = 1 + (rand() % (M * N));
}
}
}
After i call the function i need the user to enter another command and call a different function from the user input. Ive been experimenting by first hitting 1 so it fills the array with numbers and then hitting 2 so it will hopefully print out that array but all i get are huge numbers in the array. I don't think the function is editing the array in main correctly so main doesn't get the array with random values but how do i fix this?
The code below works:
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
const int M = 10;
const int N = 20;
void PrintArray(int array[][N]) {}
void LinearSearch2D(int array[][N]) {}
void LeftShift(int array[][N]) {}
void PopulateRandom2D(int array[][N])
{
int r, c;
srand(time(NULL));
for (r = 0; r < M; r++) {
for (c = 0; c < N; c++) {
array[r][c] = 1 + (rand() % (M * N));
}
}
}
int main()
{
int array[M][N];
int ans;
while (true)
{
puts("Please enter what you would like to do:"
"\n1: Create an array with random values"
"\n2: Print Array"
"\n3: Search for a number in an array"
"\n4: Shift each value to the left"
"\n5: Quit");
scanf("%d", &ans);
switch (ans) {
case 1:
PopulateRandom2D(array);
break;
case 2:
PrintArray(array);
break;
case 3:
LinearSearch2D(array);
break;
case 4:
LeftShift(array);
break;
default:
puts("Goodybye");
return 0;
}
}
return 0;
}
I leave it to you to fill in the other functions.
You're currently recursively calling main(). In each iteration of calling main(), you'll create a new array on the stack.
This isn't what you want.
Instead, wrap your code in a while(true) { ... } loop. It would look something like this:
#include <stdbool.h>
int main()
{
int array[M][N];
int ans;
while (true) {
puts("Please enter what you would like to do:\n
1: Create an array with random values\n
2: Print Array\n
3: Search for a number in an array\n
4: Shift each value to the left");
scanf("%d",&ans);
switch(ans) {
case 1:
PopulateRandom2D(array);
break;
case 2:
PrintArray(array);
break;
case 3:
LinearSearch2D(array);
break;
case 4:
LeftShift(array);
break;
default:
puts("Goodybye");
return 0;
}
}
return 0;
}
Despite having set srand() only once as pointed by similar Q/A about rand()
I think the following rand does not return a value for my customized random function.
Anyway my purpose was to generate a few random numbers and right after their appearance to count +1 at an array (to calculate their frequency later on)
One represents (5x)+1 at freq[] array
I have read documentation about rand()/srand but I cant figure out the error.
Thanks for your patience!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 1000
int RandomInteger(int low , int high);
main()
{
int freq[9]={0},i,j,number,div;
srand((int)time(NULL));
for(i=0;i<N;i++)
number=RandomInteger(1,9);
switch(number){
case 1:
freq[0]+=1;
break;
case 2:
freq[1]+=1;
break;
case 3:
freq[2]+=1;
break;
case 4:
freq[3]+=1;
break;
case 5:
freq[4]+=1;
break;
case 6:
freq[5]+=1;
break;
case 7:
freq[6]+=1;
break;
case 8:
freq[7]+=1;
break;
case 9:
freq[8]+=1;
break;
default:
;
}
for(i=0;i<9;i++){
div=freq[i]/5;
printf("%d|",div);
for(j=0;j<div;j++)
printf("*");
printf("\n");
}
}
int RandomInteger(int low , int high)
{
int k;
double d;
d=(double)rand()/((double)RAND_MAX+1);
k=(int)(d*(high-low+1));
return low+k;
}
You problem is this:
for(i=0;i<N;i++)
number=RandomInteger(1,9);
It should have
for(i=0;i<N;i++) {
number=RandomInteger(1,9);
..
..
}
Otherwise it runs it N times (same line), but never goes to the switch until it finishes the loop
In your code high is set to 1 and low is set to 9 this will result in a negative k. The return will be outside of the range of your cases and will fall to default.
I'm learning C and find rand() very strange:
I've the following game:
I have played the game several times and the correct answer was something near 47.
For example:
between 1 and 100 it would be 47
between 1 and 500 it would be 247 or 347.
between 1 and 1000 it would be 347.
I don't want the number to be easily guessed after the third time.
Is there any problem? how can I modify this code to do the job?
#include<stdio.h>
#include<stdlib.h>
void main()
{int n,l,c,tries;
char yn;
first:
n=0,c=0,l=0,tries=0;
do{
printf(" 1: Easy\n 2:Medium\n 3:hard\n");
scanf("%d",&l);
}while(l<1 || l>3);
switch(l)
{
case 1:
n = rand % 100 +1;
printf("I picked a number between 1 and 100\n");
break;
case 2:
n = rand()%500 + 1;
printf("I picked a number between 1 and 500\n");
break;
case 3:
n = rand()%1000 + 1;
printf("I picked a number between 1 and 1000\n");
break;
}
do
{
tries++;
printf("Enter your guess: \t");
scanf("%d",&c);
if(c == n)
printf("You Won\n number of gusses= %d\n", tries);
else
{
if(c > n)
printf("High\n");
else
printf("Low\n");
}
}while(c !=n);
printf("Try Again \?(Y/N)\n");
scanf(" %c",&yn);
if(yn == 'Y' || yn == 'y')
goto first;
}
If you reboot your pc you'll see that the results will be different.
Random is not clever as you expect, and, to tell you the truth, is not properly random! (:
By the way, to provide a different seed to the random alghoritm, you have to call, only one time:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
srand(time(0));
Take a look to the documentation!
edit
To improve your code:
int randN = 100;
switch (l) {
case 1:
break;
case 2:
randN = 500;
break;
case 3:
randN= 1000;
break;
default:
randN = rand() % 1000 + 1;
break;
}
n = rand() % randN + 1;
printf("I picked a number between 1 and %i.\n", randN);
use srand and then use rand i.e
int main()
{
srand(time(0)); // use current time as seed for random generator
int random_variable = rand();
printf("Random Value= %d",random_variable);
return 0;
}