The intention here is to write a C code for 2 dices rolling simulator.
It has to write the answer in a form of histogram (10 results by line).
Calculate and give the minimum, maximum, and the average of dice rolls. As well as the duplicates. I have to admit I am stuck right now. Any help would be appreciated.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 100
void initarray(int d[]);
void printarray(int d[]);
void printstar(int n);
void fancyprint(int d[]);
int roll(void);
int main(int argc, char* argv[]) {
{
int roll();
int d[13]; /* 2-12 hold num of rolls */
int i; /* variable de la boucle */
int starttime = time(NULL); /* temps horloge*/
srand(1020);
printf("Simulation de 100 lancees de 2 des");
for (i = 0; i < N; i++)
d[roll() + roll()]++;
printarray(d);
fancyprint(d);
printf("Elapsed time: %ld seconds\n",
time(NULL) - starttime);
return 0;
}
/* initarray: initialize statistic array */
void initarray(int d[]){
int i;
for (i = 2; i < 13; i++)
d[i] = 0;
}
/* printarray: print each num of rolls */
void printarray(int d[]){
int i;
double e[] = {0, 0,
1.0/36.0, 2.0/36.0, 3.0/36.0, 4.0/36.0,
5.0/36.0, 6.0/36.0, 5.0/36.0, 4.0/36.0,
3.0/36.0, 2.0/36.0, 1.0/36.0};
printf("Sum Times Frequency");
printf(" Exact Diff\n\n");
for (i = 2; i < 13; i++)
printf("%2d %7d %11.7f %10.7f %8.4f\n",
i,
d[i],
(double)d[i]/N*100.0,
e[i]*100.0,
((double)(d[i]) -
e[i]*N)/N*100.0);
}
/* printstar: print n stars */
void printstar(int n) {
while (n > 0) {
printf("*");
n--;
}
}
/* fancyprint: print bar graph */
void fancyprint(int d[]){
int i;
printf("\n");
for (i = 2; i < 13; i++) {
printf("Sum:%3d |", i);
printstar(300*d[i]/N);
printf("\n");
}
printf("\n");
}
/* roll: simulate rolling a die */
int roll() {
return (int) (6.0*(rand()/(double)RAND_MAX)
+ 1.0);
return 0;
}
}
OP's roll() generates a 7 once in a while: when rand() == RAND_MAX.
int roll(void) {
// return (int) (6.0*(rand()/(double)RAND_MAX) + 1.0);
return (int) (6.0*(rand()/((double)RAND_MAX + 1) + 1.0);
}
The above will have trouble if (double)RAND_MAX is not exact.
It also still has a small bias.
Consider other approaches that do not use floating point. Such as: https://stackoverflow.com/a/17554531/2410359
Possible other issues.
Related
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define LIMIT 30000
void CreateArray(int *p, int N) {
int i;
p = (int *)malloc(N * sizeof(int));
srand((long)210);
for (i = 0; i < N; i++)
*(p + i) = rand() % LIMIT;
for (i = 0; i < N; i++)
printf("%d ", p[i]);
}
void Search(int *p, int N, int key) {
int comparisons = 0, success_search = 0;
int i;
clock_t start, end;
double elapsed;
start = clock();
for (i = 0; i < N; i++) {
if (key == p[i]) {
comparisons++;
success_search++;
printf("\nFound!");
break;
} else {
comparisons++;
printf("\nNot found!");
}
}
end = clock();
elapsed = ((double)(end - start)) / CLOCKS_PER_SEC;
printf("\nTotal comparisons: %d \n", comparisons);
printf("Time elapsed: %f \n", elapsed);
printf("Successful comparisons: %d \n\n", success_search);
}
int main() {
int N, i, p, key;
key = 1;
CreateArray(&p, N = 7);
Search(&p, N, key);
}
I'm trying to create a pseudo-random array and then try to search for a specific number in it and keep track of the total comparisons made and the total time needed to complete the search. I have manually inserted a number that is not in the array and it keeps saying that the number was found after 3 comparisons. Also the time elapsed always appears to be zero. I can't figure out what's wrong.
Make the following changes.
1) You need to allocate array and pass it to different functions. So "n" should be a pointer.
int *n = NULL;
2) You want CreateArray() to allocate memory and pass the pointer.
void CreateArray (int **p, int N)
3) You have to pass pointer to Search(). So call from main() becomes
Search(p, N, key);
I think it should work fine as expected now.
For time elapsed, you refer to Weather Vane's comment in your question.
There are multiple problems in your code:
CreateArray should return the pointer to the allocated space. Passing it a pointer to a local int in main() makes no sense.
you should test for malloc potential failure.
Search should get the pointer to the allocated array, not the address of a local int.
Search should print the Not found message just once at the end of the scan phase.
If you want to count the number of successful comparisons, you should not break from the loop when you find the first one, but then the total number of comparisons is N.
for better timing accuracy, you should avoid using printf inside the timed fragment.
you should free the memory before exiting the program.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LIMIT 30000
void CreateArray(int N) {
int i;
int *p = (int *)malloc(N * sizeof(int));
if (p != NULL) {
srand((long)210);
for (i = 0; i < N; i++)
*(p + i) = rand() % LIMIT;
for (i = 0; i < N; i++)
printf("%d ", p[i]);
}
return p;
}
void Search(int *p, int N, int key) {
int comparisons = 0, success_search = 0;
int i;
clock_t start, end;
double elapsed;
start = clock();
for (i = 0; i < N; i++) {
comparisons++;
if (key == p[i])
success_search++;
}
end = clock();
elapsed = ((double)(end - start)) / CLOCKS_PER_SEC;
if (success_search)
printf("Found!\n");
else
printf("Not found!\n");
printf("Total comparisons: %d\n", comparisons);
printf("Successful comparisons: %d\n\n", success_search);
printf("Time elapsed: %f\n", elapsed);
}
int main() {
int N, i, key;
int *p;
key = 1;
N = 7;
p = CreateArray(N);
if (p == NULL) {
fprintf(stderr, "cannot allocate memory for %d elements\n", N);
return 1;
}
Search(p, N, key);
free(p);
return 0;
}
I am completely new to C, so excuse me for my lack of knowledge. I am trying to make 4 threads that will each generate a number between 100-199 200-299 300-399 and 400-499 for each of the threads respectively. However when I pass my parameter interv which is a struct type with two int values, I get something completely different on the other side. For example when I send in 100 and 199, I get 0 instead of 199 and -13216 instead of 100. I am not sure where exactly the problem is, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 4
int sum; /* global variable shared by thread(s) */
pthread_mutex_t counter_lock = PTHREAD_MUTEX_INITIALIZER;
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
typedef struct interval {
int min;
int max;
} interval;
void *runner(struct interval *param); /* threads call this function */
/*
*
*/
int main(int argc, char *argv[]) {
pthread_t workers[NUM_THREADS];
interval *interv;
interv->max = 199;
interv->min = 100;
/* create the thread */
printf("min = %d max = %d \n",interv->min,interv->max);
for (int i = 0; i < NUM_THREADS; i++) {
printf("min = %d max = %d \n",interv->min,interv->max);
pthread_create(&workers[i],NULL,runner,&interv);
interv->min += 100;
interv->max += 100;
/* wait for the thread to exit */
pthread_join(&workers[i],NULL);
}
printf("sum = %d\n",sum);
return (0);
}
/* The thread will begin control in this function */
void *runner(struct interval *param) {
int n, array[100], list_sum, counter;
printf("min = %d max = %d \n",param->min,param->max);
for (int i; i < 100; i++) {
n = rand() % (param->max + 1 - param->min) + param->min;
array[i] = n;
list_sum += n;
}
qsort(array, 100, sizeof(int), cmpfunc);
for (int i; i < 100; i++) {
counter += 1;
if (counter == 10) {
counter = 0;
}
}
pthread_mutex_lock(&counter_lock);
sum += list_sum;
pthread_mutex_unlock(&counter_lock);
pthread_exit(0);
}
UPDATED:
So I did not get the result I expected when the program compiled, so I re-wrote most of my code. Although now, again, I am getting some strange behavior and I am not sure why.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 1
#define NUM_ELEMENTS 10
//Sum computed buy the background thread
int total = 0;
int counter = 0;
struct sum_runner_struct {
int min;
int max;
int array[NUM_ELEMENTS];
int answer;
};
//Thread function to generate a sum of 0 to N
void* runner(void* arg) {
struct sum_runner_struct *arg_struct = (struct sum_runner_struct*) arg;
int n, sum;
for (int i = 0; i<NUM_ELEMENTS; i++) {
n = rand()%(arg_struct->max + 1 - arg_struct->min) + arg_struct->min;
printf("%d ",n);
arg_struct->array[i] = n;
}
printf("\n");
for (int i = 0; i<NUM_ELEMENTS; i++) {
sum = sum + arg_struct->array[i];
printf("%d ", arg_struct->array[i]);
counter += 1;
if (counter == 10) {
printf("\n");
counter = 0;
}
}
printf("Sum: %d\n",sum);
arg_struct->answer = sum;
pthread_exit(0);
}
int main(int argc, char **argv) {
int INTERVALS[4][2] = {{100,199},{200,299},{300,399},{400,499}};
struct sum_runner_struct args[NUM_THREADS];
// Launch threads
pthread_t tids[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
args[i].min = INTERVALS[i][0];
args[i].max = INTERVALS[i][1];
//Create attributes
pthread_attr_t attr;
pthread_attr_init(&attr);
//Create Thread
pthread_create(&tids[i], &attr, runner, &args[i]);
}
//Wait until thread is done its work
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(tids[i], NULL);
printf("Sum of thread %d is %d\n", i, args[i].answer);
total += args[i].answer;
}
printf("Sum is %d\n", total);
}
Before you comment on my random number generator, I know that it is not the best solution as of now, but that is not my issue. My issue is when I add the numbers in the array for a thread I get a number that is bigger by 6 integers. I am not sure why this happens.
For example when I run the program with a single thread to generate 10 elements I would get something like this:
133 143 162 129 100 108 152 156 156 119
133 143 162 129 100 108 152 156 156 119
Sum: 1364
Sum of thread 0 is 1364
Sum is 1364
RUN SUCCESSFUL (total time: 57ms)
Note that I printed the array twice hence why there are two lines of the same array. As you can see (I think I added them up right) if you add the numbers in the array you would get 1358, not 1364. I am not sure what causes this.
Okay I found the issue, I am not sure exactly why, but when I initialize
int n, sum;
for some reason sum value is initialized to 6. Can anyone explain why this happens?
This question already has answers here:
Prime Number Algorithm
(7 answers)
Closed 8 years ago.
This is my code for finding 10000th prime number but it is really slow, it takes 7 seconds to calculate.
#include <stdio.h>
#include <stdlib.h>
long int prime (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int i=2,counter=0;
while(1)
{
if(prime(i))
counter++;
if(counter==10000)
break;
i++;
}
printf("10000th prime number is: %d",i);
}
It is brute force method so that's probably reason why it's so slow.
I think problem may be that it has to call function so many times. So what do you think can it be optimised or it's better to find some math formula for this.
You can reduce the time substantially by making the following changes to prime():
Stopping at sqrt(n).
Starting at i=3, and incrementing i by 2.
Here's a program that contains both versions and the time taken by each.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
int is_prime1 (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it1(int max)
{
clock_t start = clock();
clock_t end;
int i=2,counter=0;
while(1)
{
if(is_prime1(i))
counter++;
if(counter==max)
break;
i++;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int is_prime2 (int n)
{
int i;
int stop = sqrt(n);
for(i=3;i<=stop;i+=2)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it2(int max)
{
clock_t start = clock();
clock_t end;
int i=3,counter=1;
while(1)
{
if(is_prime2(i))
counter++;
if(counter==max)
break;
i += 2;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int main(int argc, char** argv)
{
int max = atoi(argv[1]);
do_it1(max);
do_it2(max);
}
Sample execution:
./test 10000
Sample output:
10000th prime number is: 104729
Time taken: 9.469000
10000th prime number is: 104729
Time taken: 0.078000
To optimized your code a little bit (changes are made based on comments):
long int prime (int n)
{
int i;
int e = (int)sqrt(n);
for(i=2; i<=e;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int *prime;
int prime_n;
void make_prime_table(int n){
prime = malloc(sizeof(int) * n / 2);
prime_n =0;
prime[prime_n++] = 2;
prime[prime_n++] = 3;
int i, j;
for(i = 5; i <= n; i +=2){
bool is_prime = true;
for(j = 1; j < prime_n ; ++j){
int t = prime[j];
if(t * t > i)
break;
if(i % t == 0){
is_prime = false;
break;
}
}
if(is_prime)
prime[prime_n++] = i;
}
}
int main(void){
int n = 105000;
make_prime_table(n);
if(prime_n >= 10000)
printf("10000th prime number is: %d\n", prime[9999]);
free(prime);
return 0;
}
I want to make a programm that takes the dimension and numbers of vectors to be sorted based on their length.
Most of the code works but the sort part of the program doesnt.
Basically what I want to do there is: compare the output from the bereken_lengte function from 2 places in the array w. But nothing seems to happen.
Also in the function bereken_lengte, I cant take the roots of the sum after the loop ended.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double bereken_lengte(double *array, int dim)
{
int i, j;
double sum = 0.0;
for(i=0; i<dim; ++i)
sum += pow(array[i],2);
return sum;
}
void swap(double **p, double **q)
{
double *tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
void sort_vector(double *w[] , int num , int dik )
{
int i,dim,j;
dim = dik;
for(i=0;i<num;++i)
for(j = 1+i;j<num;++j)
{
if(bereken_lengte(w[i],dim) > bereken_lengte(w[j],dim) )
swap(&w[i], &w[j]);
}
}
int main (void)
{
int dim, num;
int i, j,k,l;
double **w;
scanf ("%d %d", &dim, &num); /* read N and M */
w = calloc (num, sizeof (double *)); /* allocate array of M pointers */
for (i = 0; i < num; i++)
{
/* allocate space for N dimensional vector */
w[i] = calloc (dim, sizeof (double));
/* read the vector */
for (j = 0; j < dim; j++)
{
scanf ("%lf", &w[i][j]);
}
}
sort_vector(w,num,dim);
for(k=0; k<num; ++k)
{
printf("\n");
for(l=0; l<dim; ++l)
printf("%f ", w[k][l]);
}
return 0;
}
double bereken_lengte(double *array, int dim)
{
unsigned int i;
double sum =0.0;
for(i=0; i<dim; ++i)
sum += pow(array[i],2);
return sum;
}
Just initialise the sum to zero before summing.
BTW I changed i to unsigned. It is IMnsvHO a good habit to use unsigned types for index && size variables (they won't underflow, and if the do, you'll notice it)
UPDATE:
This tries to avoid the int indices and sized, and uses qsort. (rather ugly, because the compare function takes only two elements; don't try this in a multithreaded program ...) Note, I may have rows and columns interchanged, but thats a way of life... gewoon, omdat het kan!:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double bereken_lengte(double *array, size_t dim)
{
size_t i;
double sum=0.0;
for(i=0; i<dim; ++i)
sum += pow(array[i],2);
return sum;
}
/* this is ugly: qsort only allows only two arguments */
static size_t ze_third_argument=0;
int srt_pdbl(void *l, void *r)
{
double **dl = l, **dr = r;
double diff;
diff = bereken_lengte( *dl, ze_third_argument) - bereken_lengte( *dr, ze_third_argument) ;
return (int) diff;
}
void sort_vector(double *w[] , size_t num , size_t dik )
{
ze_third_argument = dik;
qsort(w, num, sizeof *w, srt_pdbl );
}
int main (void)
{
size_t dim, num;
size_t i, j,k,l;
double **w;
scanf ("%zu %zu", &dim, &num); /* read N and M */
w = calloc (num, sizeof *w); /* allocate array of M pointers */
for (i = 0; i < num; i++)
{
/* allocate space for N dimensional vector */
w[i] = calloc (dim, sizeof *w[i] );
/* read the vector */
for (j = 0; j < dim; j++)
{
scanf ("%lf", &w[i][j]);
}
}
sort_vector(w,num,dim);
for(k=0; k<num; ++k)
{
printf("\n");
for(l=0; l<dim; ++l)
printf("%f ", w[k][l]);
}
return 0;
}
I updated my main and sequetialSearch and now it crashes when it runs. It compiles okay, but then crashes.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "percentage.h"
#include "sequentialSearch.h"
#define searchAmount 100
int main(int argc, char *argv[])
{
int numbers[100];
int searches[searchAmount];
int testAmounts[searchAmount];
int i;
int where;
int searchSuccess;
int searchUnsuccess;
int percent;
int looker;
int sum;
int average;
srand(time(NULL));
for (i = 0; i < 100; i++){
numbers[i] = rand() % 200;
}
for (i = 0; i < searchAmount; i++){
searches[i] = rand() % 200;
}
searchUnsuccess = 0;
searchSuccess = 0;
sum = 0;
for(i = 0; i < searchAmount; i++){
if(seqSearch(numbers, 100, searches[i], &where, &looker)){
searchSuccess++;
testAmounts[i] = looker;
}else{
searchUnsuccess++;
testAmounts[i] = looker;
}
}
for(i = 0; i < searchAmount; i++){
sum = sum + testAmounts[i];
}
average = sum / searchAmount;
percent = percentRate(searchSuccess, searchAmount);
printf("Total number of searches: %d\n", searchAmount);
printf("Total successful searches: %d\n", searchSuccess);
printf("Success Rate: %d%%\n", percent);
printf("Total number of tests ran: %d\n", average);
system("PAUSE");
return 0;
}
sequentialSearch.h
bool seqSearch (int list[], int last, int target, int* locn, int* looker){
*looker = 0;
while(*looker < last && target != list[*looker]){
*looker++;
}
*locn = *looker;
return(target == list[*looker]);
}
Pass looker in by reference, so that you can access its value from the caller.
int looker;
...
for(i = 0; i < searchAmount; i++){
if(seqSearch(numbers, 100, searches[i], &where, &looker)){
searches[i] += looker;
searchSuccess++;
}else{
searchUnsuccess++;
}
}
bool seqSearch (int list[], int last, int target, int* locn, int *looker){
*looker = 0;
while(*looker < last && target != list[*looker]){
(*looker)++;
}
*locn = *looker;
return(target == list[*looker]);
}
By the way, you may wish to reconsider defining functions in your header file; this could cause problems with duplicate symbol when linking if you have more than one c file including this file.
Why not just pass looker in as an int*, use it essentially as you have been, look at the value after seqSearch(...) returns, and add it to a running total back in main()?
One problem is that the increment of looker in seqSearch is incrementing the pointer rather than the value. It should probably be:
(*looker)++;