I am facing a problem right now and can't seem to solve it. Whenever I start my code I get a segmentation fault. My aim is to roll two dice. The value is generated by a random number. I want to roll 10000 times and save the values within an array, so I can create a little chart at the end which will show the diced the values. I appreciate any help and hints on how to solve the problem. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DICE 2
#define DICEEYES (DICE * 6) -DICE +1
#define COUNT 10000
int diceRoll(int dice);
int main(void)
{
srand(time(0));
int valuesOfRoll[DICEEYES] = { 0 };
for(int i = 0; i < COUNT; i++)
{
int index = diceRoll(DICE) - DICE;
valuesOfRoll[index]++;
}
for(int i = 0; i < DICEEYES; i++)
{
if(valuesOfRoll[i] < 1) continue;
printf("The number %2d was rolled %4d times\r\n", i + DICE, valuesOfRoll[i]);
}
return 0;
}
int diceRoll(int dice)
{
int sum;
for(int i = 0; i < dice; i++)
{
sum += rand() % 6 + 1;
}
return sum;
}
You should initialize sum in the function diceRoll(),
/* always return value between [dice..dice*6]*/
int diceRoll(int dice)
{
int sum=0;
for(int i = 0; i < dice; i++)
{
sum += rand() % 6 + 1;
}
return sum;
}
Since sum could have any value (on the stack), you were using an index value that could fall outside the ValuesOfRoll[] array. One way to avoid is to use the modulus operator to limit the returned index to a valid range.
int main(void)
{
srand(time(0));
int valuesOfRoll[DICEEYES] = { 0 };
for(int i = 0; i < COUNT; i++)
{
int index = diceRoll(DICE) - DICE;
/* limit index to [0..DICEEYES] */
index %= DICEEYES;
valuesOfRoll[index]++;
}
for(int i = 0; i < DICEEYES; i++)
{
if(valuesOfRoll[i] < 1) continue;
printf("The number %d was rolled %4d times", i + DICE, valuesOfRoll[i]);
}
return 0;
}
Initialise the value of sum in your function (preferably to 0), otherwise it will hold some garbage value.
int diceRoll(int dice)
{
int sum;
for(int i = 0; i < dice; i++)
{
sum += rand() % 6 + 1;
}
return sum;
}
The garbage value may be a very large number, and so will be the returned value of the function. So, when the returned value is used in this line:
int index = diceRoll(DICE) - DICE;
then the array will have an index of that large number, valuesOfRoll[some_large_integer]++;. This causes an out-of-array-bound situation, and causes seg-fault.
Slightly belatedly, the faults are not initialising sum, and DICEEYES.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DICE 2
#define DICEEYES (DICE * 6)
#define COUNT 10000
int diceRoll(int dice)
{
int i, sum = 0; // need to initialise!
for(i = 0; i < dice; i++)
sum += rand() % 6 + 1;
return sum;
}
int main(void)
{
int i;
int valuesOfRoll[DICEEYS+1] = { 0 }; // size of array
srand((unsigned)time(0));
for(i = 0; i < COUNT; i++)
valuesOfRoll[diceRoll(DICE)]++;
for(i = DICE; i <= DICEEYES; i++)
printf("The number %2d was rolled %4d times\n", i, valuesOfRoll[i]);
return 0;
}
Program output:
The number 2 was rolled 264 times
The number 3 was rolled 573 times
The number 4 was rolled 798 times
The number 5 was rolled 1145 times
The number 6 was rolled 1373 times
The number 7 was rolled 1697 times
The number 8 was rolled 1385 times
The number 9 was rolled 1143 times
The number 10 was rolled 835 times
The number 11 was rolled 528 times
The number 12 was rolled 259 times
the following code
1) cleanly compiles
2) has corrections to the output formatting
3) properly initializes values (good case for always initialize all values)
4) outputs the proper data
5) does not try to fiddle offset/indexes, etc
6) uses meaningful #define names, function parameter names, etc
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_DICE (2)
#define NUM_ROLLS (10000)
#define MIN_DICEROLL_VALUE (2)
#define MAX_DICEROLL_VALUE (12)
int diceRoll(int numDice);
int main(void)
{
srand(time(NULL));
int valuesOfRoll[MAX_DICEROLL_VALUE+1] = { 0 }; // notice the +1
for(int i = 0; i < NUM_ROLLS; i++)
{
int index = diceRoll(NUM_DICE);
valuesOfRoll[index]++;
}
for(int i = MIN_DICEROLL_VALUE; i <= MAX_DICEROLL_VALUE; i++)
{
// 2d for values 2...12 5d for values 0...10000 \n so each output on anew line
printf("The number %2d was rolled %5d times\n", i, valuesOfRoll[i]);
}
return 0;
} // end function: main
int diceRoll(int numDice)
{
int sum = 0; // be sure to initialize value
for(int i = 0; i < numDice; i++)
{
sum += (rand() % 6) + 1;
}
return sum;
} // end of function: diceRoll
Related
Good afternoon, and I have one question to ask about programming lottery in C language.
The requirements are:
Calculate each number's chance when if there are 46 balls labeled in each number in the box and there are 10K chances to pick one ball.
Then, print the number and number's chance on each item. The printed form must be like:
Number 45: 251 times
Find six of the most found numbers and print them out. The printed form must be like:
The most found were 45, 27, 8, 10, 12, 15
So my code was:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10000
#define ballamount 6
int main(void)
{
int fq[SIZE] = {0};
int i, max = 0, maximum1 = 0, temp = 0;
for (int i = 0; i < SIZE i++)
{
++fq[rand() % 45 + 1];
}
for (i = 0; i < 45; i++)
{
printf("number %d: %d times\n", i + 1, fq[i]);
}
for (i = 0; i < ballamount i++)
{
for (int j = 0; j < 45; j++)
{
fq[j] = fq[0];
if (fq[j] > temp)
{
temp = fq[j];
max = j;
}
}
fq[i] = max;
fq[max] = 0;
printf("Maximum number is %d.\n", max);
}
return 0;
}
I cannot find the path to solve this stuff. How can I solve it? Thanks in advance.
You're almost there, fq contains the number of times a given index is randomly selected, you already have that, you just have to select the six largest values in the array, minor tweaks to your code will render you the correct result.
Your code fixed, including ; typos, in the for loops, with comments:
Live demo
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // for the seed
#define SIZE 10000
#define ballamount 6
int main(void)
{
srand(time(NULL)); // add a seed for your random number generator
int fq[46] = {0}; // the array only needs 46 elements
int max = 0;
int temp = 0;
for (int i = 0; i < SIZE; i++) // was missing ;
{
++fq[rand() % 46]; // if it's from 1 to 46, use index 0 to 45
}
for (int i = 0; i < 46; i++) // index 0 to 45
{
printf("number %d: %d times\n", i + 1, fq[i]);
}
printf("The most found balls were: ");
for (int i = 0; i < ballamount; i++) // was missing ;
{
for (int j = 0; j < 46; j++)
{
if (fq[j] > temp)
{
temp = fq[j];
max = j;
}
}
printf("%d ", max + 1); // adding 1, index starts at 0
fq[max] = 0;
temp = 0; // reset temp after the loop
}
}
Possible output:
number 1: 194 times
number 2: 187 times
...
...
The most found balls were: 28 30 43 5 29 12
Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>
how can i write a program which going to give all prime no of given range WITHOUT using ANY conditions (using just loops!) in c language. i tried many different options but non of them works properly...
for instance:
what i have already tried:
#include <stdlib.h>
#include <stdio.h>
#define UNTIL 1000
#define NOT_INCLUDED 2
int main()
{
int prime =1, i =1,factor=0;
for(prime=1;UNTIL>=prime ;prime++)
{
for( i=1;i<=prime;i++)
{
for(;prime%i==0;)
{
factor++;
}
}
for(;factor==2;factor=0)
{
printf("prime number: %d \n",prime);
}
}
return 0;
}
Challenge accepted: no conditions, hidden or otherwise
#include <stdio.h>
#include <stdlib.h> // atoi
int main(void) {
const char *p = "2 3 5 7 11 13 17 19 23 29\0\0\0\0\0"; /* extend at will */
for (;;) {
p += printf("%d ", atoi(p));
fflush(stdout);
int z = 42 / *p;
(void)z; /* unused warning */
}
return 0;
}
see code running on ideone.com
To check if N is prime, iterate through all the numbers from 2 to N to see if N is divisible by any other number. Every number is divisible by 1, so when you are testing numbers for prime, start testing against 2.
Example
#include <stdio.h>
int is_prime(int N)
{
//0 and 1 are not primes
if (N < 2)
return 0;
//start testing against 2
for(int i = 2; i < N; i++)
if(N % i == 0)
return 0; //not a prime
return 1; //prime
}
int main()
{
printf("Primes from 0 to 1000:\n");
for(int i = 0; i < 1000; i++)
if(is_prime(i))
printf("%d, ", i);
printf("\n");
return 0;
}
You can optimize the loop by changing the range to N/2.
for(int i = 2; i <= N/2; i++)
if(N % i == 0)
return 0; //not a prime
return 1;//prime
#include "stdio.h"
int main() {
int max = 1000;
for (int i = 0; i < max; ++i) {
printf("%d", i);
}
return 0;
}
If max is 1000 then this will print in the format shown below
0123 up to 1000
But I would like to print 4 values per line as shown below:
0123
4567
...
I would like to see the numbers not the just the digits. for a single digit numbers, it should be like this: 0123 for two digit numbers, it should be like this: 11121314 for a three digit numbers, it should be like this: 111112113114 up to 996997998999 up to 1000.
For your loop to print upto and including 1000 for max.size = 1000, you must use the <= operator.
Here is a modified version that will format the output with a maximum of 4 characters per line:
#include <stdio.h>
#include <limits.h>
int main(void) {
struct { int size; } max = { 1000 };
if (max.size >= 0) {
for (int col = 0, i = 0;; i++) {
char buf[2 + sizeof(int) * CHAR_BIT / 3];
int n = snprintf(buf, sizeof buf, "%d", i);
for (int j = 0; j < n; j++) {
putchar(buf[j]);
if (++col == 4) {
putchar('\n');
col = 0;
}
}
if (i == max.size) {
if (col > 0) {
putchar('\n');
}
break;
}
}
}
return 0;
}
It will print:
0123
4567
8910
1112
1718
...
6997
9989
9910
00
EDIT
From your updated question, it is actually much simpler: print a linefeed character after every 4th number, using the modulo operator %.
#include <stdio.h>
int main(void) {
int max = 1000;
for (int i = 0; i < max; ++i) {
printf("%d", i);
if (i % 4 == 3)
putchar('\n');
}
return 0;
}
Just check whether i+1 is divisible by 4 or not. Whenever it is divisible by 4, print a newline.
for (int i = 0; i < max.size; ++i) {
printf("%d", i);
if((i+1)%4 == 0)
printf("\n");
}
You can also do this without using a buffer:
#include <stdio.h>
void print_digit(int number);
int main(void) {
putchar('0');
int i;
for(i = 1; i <= 1000; i++) {
print_digit(i);
}
}
void print_digit(int number) {
static int digit_count = 1; // a zero is already printed
int i;
for(i = 1; i <= number; i *= 10);
for(i /= 10; i; i /= 10) {
putchar('0' + number % (i * 10) / i);
digit_count++;
if(digit_count == 4) {
digit_count = 0;
putchar('\n');
}
}
}
However, I have to admit that this code has nothing to do with elegance, because I don't know how to make print_digit consistent with zero.
int i,j,vec[15]={0};
srand (time(NULL));
for (i=0;i<15;i++){
vec[i]=rand() % 25+1;
for (j=0;j<15;j++){
if (i!=j){
while(vec[i]==vec[j]){
vec[i]=rand() % 25+1;
}
}
}
printf("%d\n",vec[i]);
}
return 0;
}
the code still gives me repeated numbers
EXAMPLE:
24
3
7
20
18
10
12
17
9
7
4
25
13
15
21
I cant figure out what to do with it
You have your loops mixed up. The logic is: Generate a random number until you have found one that isn't in the list.
The way you do it, you generate a new number inside the checking loop. But that doesn't work. Say you're generating the 4th number and find it is equal to the third. Then you generate a new one which might well be equal to any you have already checked against.
You also check uninitialised elements when j > i. Your inner loop should only run up to i.
So:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int vec[15] = { 0 };
int i, j;
srand(time(NULL));
for (i = 0; i < 15; i++) {
int okay = 0;
while (!okay) {
vec[i] = rand() % 25 + 1;
okay = 1;
for (j = 0; j < i; j++) {
if (vec[i] == vec[j]) okay = 0;
}
}
printf("%d\n", vec[i]);
}
return 0;
}
That still looks a bit awkward with that okay variable. In my opinion, checking for duplicates should be a separate function:
int contains(int arr[], int n, int x)
{
while (n--) {
if (arr[n] == x) return 1;
}
return 0;
}
int main()
{
// snip ...
for (i = 0; i < 15; i++) {
do {
vec[i] = rand() % 25 + 1;
} while (contains(vec, i, vec[i]));
printf("%d\n", vec[i]);
}
// snip ...
}
In your case the range of possible numbers isn't mich bigger than the number of array elements. You could also create an ordered array {1, 2, 3, ..., 25}, then shuffle it and use only the first 15 elements.
Reset j in the while loop:
for (j=0;j<i;j++){ //Use j<i
if (i!=j){
while(vec[i]==vec[j]){
vec[i]=rand() % 25+1;
j=-1;//-1 because in the next iteration,j will start from 0
}
}
}
Are you actually trying to shuffle the numbers, rather than fill the array with randoms? (It looks like you want an array with numbers from 1 to 25, but in random order.) rand() can give you duplicate numbers (they're random, after all!)
Try this:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int
main( int argc, char **argv )
{
int i, vec[25];
for (i = 0; i < 25; ++i) vec[i] = i + 1;
/* Shuffle entries */
srand( time( 0 ) );
for (i = 0; i < 1000; ++i) {
int a = rand( ) % 25;
int b = rand( ) % 25;
if (a != b) {
int tmp = vec[a];
vec[a] = vec[b];
vec[b] = tmp;
}
}
/* Print shuffled array */
for (i = 0; i < 25; ++i) printf( "%d: %d\n", i, vec[i] );
return 0;
}
#include<stdio.h>
#include<stdlib.h>
int inArray(int, int, int*);
int main()
{
int i,j,vec[15]={0};
int temp;
srand (time(NULL));
for (i=0;i<15;i++){
temp =rand() % 25+1;
while(inArray(i+1,temp, vec) == 1){
temp = rand() % 25+1;
}
vec[i] = temp;
printf("VECT[%d] \t= %d\n",i,vec[i]);
}
return 0;
}
int inArray(int count, int input, int* array){
int i = 0;
for(i=0; i<count; i++){
if(input == array[i]){
return 1;
}
}
return 0;
}
Gave an output:
VECT[0] = 24
VECT[1] = 19
VECT[2] = 1
VECT[3] = 25
VECT[4] = 22
VECT[5] = 18
VECT[6] = 7
VECT[7] = 8
VECT[8] = 12
VECT[9] = 21
VECT[10] = 11
VECT[11] = 6
VECT[12] = 23
VECT[13] = 20
VECT[14] = 15
The checking was off, you would change and not break allowing it to be changed to a previous value.
You can use an array
int randNumbers[25]; // fill it starting 0 to 25 then
randomize the number in a range between 0 and 25 after swap the number in the randomized index with the last number in your array
randomize 0 to 23
and so on....
int main(int argc, char **argv) {
static const int size = 25;
int numbers[size];
for( int i = 0; i < size; i++ ){
numbers[i] = i;
}
srand (time(NULL));
for( int i = 0; i < size; i++ ){
int rIndex = rand()%(size - i);
int rNum = numbers[rIndex];
numbers[rIndex] = numbers[size-i];
printf("%d ", rNum);
}
return 0;
}
O(n) complexity...