MPI: program works depending on the number of processes - c

I wrote a program which uses the MPI library (MPICH-2). The program finds all the prime number between 2 and N. It works fine if I use only two processes, but it doesn't when I specify the number of processes >2.
The program is very inefficient, as my aim is to compare performances between a program which uses MPI and the same program which doesn't.
I have a dual core machine and I'm using NetBeans 7.4 on Ubuntu 13.10. Does the problem depend on the number of cores of my machine? I knew that the scheduling is up to the OS, but I don't know what to think! Maybe have I to put an MPI_Barrier? I insert the code and the output below, as you can see some strange zeros appear when I invoke the program with more than 2 procs.
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int count(int *a, int N){
int b[N];
int i, j, n_prime;
for(i=0; i<N; i++)
b[i] = a[i];
b[0] = b[1] = 0;
for (i=2; i<N; i++) {
b[i] = 1;
for (j=2; j<i; j++)
if (i % j == 0) {
b[i] = 0;
break;
}
}
n_prime = 0;
for (j=2; j<N; j++)
if (b[j]) n_prime++;
return n_prime;
}
int main(int argc, char** argv) {
int size, rank, div;
int N;
int *array;
int i, j, k, check, n_prime, n_prime_loc;
int *sub_array, *prime, *recv_prime, *b, *prime2;
double t1, t2;
if(argc != 2){
printf("Argument error: %s not recognized as argument\n", argv[0]);
return -1;
}
N = atoi(argv[1]);
MPI_Init(NULL, NULL);
t1 = MPI_Wtime();
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
div = N/size; //elements per process
b = (int*) malloc(sizeof(int)*N);
if (b == NULL){
printf("Cannot allocate array 'b'\n");
return -1;
}
n_prime = count(b, N);
/* Dynamic allocation of the arrays */
sub_array = (int*) malloc(sizeof(int)*div);
if (sub_array == NULL){
printf("Cannot allocate array 'sub_array'\n");
return -1;
}
recv_prime = (int*) malloc(sizeof(int)*n_prime);
if (recv_prime == NULL){
printf("Cannot allocate array 'recv_prime'\n");
return -1;
}
array = (int*) malloc(sizeof(int)*N);
if (array == NULL){
printf("Cannot allocate array 'array'\n");
return -1;
}
prime = (int*) malloc(sizeof(int)*n_prime);
if (prime == NULL){
printf("Cannot allocate array 'prime'\n");
return -1;
}
/* Initialization of the array */
for (i=0; i<N; i++)
array[i] = i+1;
for(i=0; i<n_prime; i++)
prime[i] = 0;
for(i=0; i<n_prime; i++)
recv_prime[i] = 0;
/* Process 0 divides the array among the processes */
MPI_Scatter(array, div, MPI_INT, sub_array, div, MPI_INT, 0, MPI_COMM_WORLD);
check = 0; //used to check if we find a divisor
k=0;
for(i=0; i<div; i++){
check = 0;
if (sub_array[i] == 1) continue;
for(j=2; j<sub_array[i]; j++){
if(sub_array[i] % j == 0){
check = 1;
}
}
if (check == 0){ //if we don't find a divisor, the number is prime
prime[k] = sub_array[i];
k++;
}
}
n_prime_loc = 0;
for(i=0; i<n_prime; i++)
if(prime[i]!=0)
n_prime_loc++;
prime2 = (int*) malloc(sizeof(int)*n_prime_loc);
j=0;
for(i=0; i<n_prime; i++){
if(prime[i]==0) continue;
prime2[j] = prime[j];
j++;
}
/* Each process sends its computation to the root process */
MPI_Gather(prime2, n_prime_loc, MPI_INT, recv_prime, n_prime_loc, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if(rank == 0){
printf("Prime numbers: ");
for(i=0; i<n_prime; i++)
printf("%i ", recv_prime[i]);
printf("\n");
}
/* Free the allocated arrays */
free(b);
free(array);
free(recv_prime);
free(prime);
free(prime2);
free(sub_array);
t2 = MPI_Wtime();
//printf("Computation time for Process %i: %f\n", rank, t2-t1);
MPI_Finalize();
return (EXIT_SUCCESS);
}
The outputs are:
hino#hino-X51L:~/NetBeansProjects/Prime$ mpiexec -np 10 ./Prime 1000
Prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
0 0 0 0 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313
317 331 337 347 349 353 359 367 373 379 383 389 397 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521
523 541 547 557 563 569 571 577 587 593 599 450 451 452 601 607 613 617 619 631 641
643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773
787 797 649 650 485 486
hino#hino-X51L:~/NetBeansProjects/Prime$ mpiexec -np 2 ./Prime 1000
Prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331
337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457
461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599
601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877
881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997

A quick scan shows me a few things wrong here:
You need to make sure that your array of numbers divides up evenly. For instance, if you're dividing 100 numbers among 3 processes, you'll have some numbers that don't end up getting distributed correctly by the MPI_SCATTER. This isn't your problem though.
Your MPI_GATHER has an issue on the receiving side. The problem here is that you are sending n_prime_loc numbers from each process, but that value is also different for each process. For instance, rank 0 might find 10 prime numbers so its value of n_prime_loc will be 10, but on rank 1, there might be 25 prime numbers (I know these examples aren't accurate, but stick with me). The problem is that since rank 0 is the root of the MPI_GATHER operation, it's value of n_prime_loc will be used which means that if another process is sending more numbers that rank 0 is expecting, there will be an issue. You need to generate a buffer that's large enough to hold all of the possible results and gather the results appropriately. Alternatively, you could choose to not use an MPI_GATHER since the size of the buffer isn't known a priori. Instead, you could use MPI_SEND and MPI_RECV and you could use MPI_PROBE to know how big to make your buffer. You can make either one work.
Your MPI_BARRIER is useless here. For some reason, when people don't know what to do in MPI, they throw in an MPI_BARRIER. All this function does is make all of the processes wait at this point until all of the other processes reach the same point. You've already accomplished that by calling MPI_GATHER since all of the other processes are involved in that call.
It sounds like you're only running this application on one process. While you can certainly do that, you won't really get much speedup and you won't get anymore speedup than you have cores. If you have a dual core processor and you're trying to run 4 processes, you'll spend a bunch of your time just fighting for the CPU and context switching in and out. You should try not to use more MPI ranks than you have cores.

Related

Is not stack'd, malloc'd or (recently) free'd, when the amount of operations gets large

This is my code (sorry, it's long, but there is a lot of repeating code).
{Description}
Sorting algortihm testing program using pseudo randomly
generated number array. User can specify array length,
its min and max elements, the least number of repeating
values. User can also choose how many arrays to be tested.
1 /*=============================================================================
2 |
3 | Assignment: Program 12
4 |
8 | Class: Programming Basics
9 | Date: December 13th, 2017
10 |
11 | Language: GNU C (using gcc on Lenovo Y50-70, OS: Arch Linux x86_64)
12 | Version: 0.0
13 | To Compile: gcc -Wall -g -std=c11 pratybos12.c -o pratybos12
14 |
15 +-----------------------------------------------------------------------------
16 |
17 | Description: Sorting algortihm testing program using pseudo randomly
18 | generated number array. User can specify array length,
19 | its min and max elements, the least number of repeating
20 | values. User can also choose how many arrays to be tested.
21 |
22 | Input: Command line input by user
23 |
24 | Output: Prompt messages, validation errors and final results
25 | are displayed one per line to the standard output.
26 | The output is each algorithm's each iteration, with
27 | comparison and assignment counts, and also processor
28 | clock times and average completion time, in seconds.
29 | Finally, the average data of each algorithm is presented.
30 | At the end, the algorithms are sorted from best to worst
31 | by their average time.
32 |
33 | Version
34 | updates: Currently this is the intial version
35 |
36 +===========================================================================*/
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <time.h>
41
42 #include "dbg.h"
43
44 #include "helpers.h"
45 #include "test_algorithm.h"
46
47 #include "bubble_sort_a.h"
48 #include "bubble_sort_b.h"
49 #include "bubble_sort_c.h"
50 #include "bubble_sort_d.h"
51 #include "bubble_sort_e.h"
52 #include "bubble_sort_e_and_f.h"
53 #include "bubble_sort_f.h"
54 #include "bubble_sort_b_and_c.h"
55 #include "bubble_sort_b_and_e.h"
56 #include "bubble_sort_b_and_f.h"
57 #include "bubble_sort_c_and_e.h"
58 #include "bubble_sort_c_and_f.h"
59 #include "bubble_sort_b_and_e_and_f.h"
60 #include "bubble_sort_b_and_c_and_e_and_f.h"
61 #include "insertion_sort.h"
62 #include "quicksort_pivot_first.h"
63 #include "selection_sort.h"
64 #include "top_down_merge_sort.h"
65
66 #define MAX_ITER 100
67 #define MAX_ALGO 100
68
69
70 typedef struct {
71 char* pointerName;
72 int pointerMemory;
73 } PointerStats;
74
75 typedef struct {
76 PointerStats* memJournal;
77 int JournalPointerCount;
78 int memUsed;
79 int memUsedByJournal;
80 } MemoryStats;
81
82
83 typedef struct {
84 int no;
85 int is_sorted;
86 int comp_count;
87 int assign_count;
88 double clocks_total;
89 double time_spent;
90 } Iteration;
91
92 typedef struct {
93 char* type;
94 char* complexity;
95 int iter_count;
96 int rank;
97 int avg_comp;
98 int avg_assign;
99 double avg_clocks;
100 double avg_time;
101 Iteration* iterations[MAX_ITER];
102 } Algorithm;
103
104 typedef struct {
105 char* date;
106 char* arch;
107 char* compiler;
108 Algorithm* algorithms[MAX_ALGO];
109 } Results;
110
111 // a typedef creates a fake type, in this
112 // case for a sort function pointer
113 typedef int* (*sort_pointer)(int* target, int size);
114
115 // function pointer to a quicksort function
116 typedef int* (*quicksort_pointer)(int* target, int first, int last);
117
118 // function pointer to a mergesort function
119 typedef void (*mergesort_pointer)(int* target, int* working_array, int size);
120
121
122 void filldata(int* data, int size, int min, int max, int repeat);
123 void test_sort( int* data, int size, sort_pointer func, Algorithm* Algo, int no);
124 void test_quicksort( int* data, int size, quicksort_pointer func, Algorithm* Algo, int no);
125 void test_mergesort( int* data, int size, mergesort_pointer func, Algorithm* Algo, int no);
126 void print_algo(Algorithm* Algo);
127 void calculate_average(Algorithm* Algo);
128 Algorithm** rank_algorithms(Algorithm** target, int first, int last);
129
130 MemoryStats memoryStats;
131
132 int array_count;
133
134 int main(int argc, char* argv[])
135 {
136 srand(time(NULL));
137
138 Results* Res = malloc(sizeof(Results));
139
140 Res->date = "2017-12-16";
141 Res->arch = "Arch Linux x86_64";
142 Res->compiler = "gcc";
143
144 // creating algorithm structures
145 Algorithm* Algo1 = malloc(sizeof(Algorithm));
146 Algo1->type = "bubble_sort_a";
147 Algo1->complexity = "O (n^2)";
148
149 Algorithm* Algo2 = malloc(sizeof(Algorithm));
150 Algo2->type = "bubble_sort_b";
151 Algo2->complexity = "O (n^2)";
152
153 Algorithm* Algo3 = malloc(sizeof(Algorithm));
154 Algo3->type = "bubble_sort_c";
155 Algo3->complexity = "O (n^2)";
156
157 Algorithm* Algo4 = malloc(sizeof(Algorithm));
158 Algo4->type = "bubble_sort_d";
159 Algo4->complexity = "O (n^2)";
160
161 Algorithm* Algo5 = malloc(sizeof(Algorithm));
162 Algo5->type = "bubble_sort_e";
163 Algo5->complexity = "O (n^2)";
164
165 Algorithm* Algo6 = malloc(sizeof(Algorithm));
166 Algo6->type = "bubble_sort_f";
167 Algo6->complexity = "O (n^2)";
168
169 Algorithm* Algo7 = malloc(sizeof(Algorithm));
170 Algo7->type = "bubble_sort_b_and_c";
171 Algo7->complexity = "O (n^2)";
172
173 Algorithm* Algo8 = malloc(sizeof(Algorithm));
174 Algo8->type = "bubble_sort_b_and_e";
175 Algo8->complexity = "O (n^2)";
176
177 Algorithm* Algo9 = malloc(sizeof(Algorithm));
178 Algo9->type = "bubble_sort_b_and_f";
179 Algo9->complexity = "O (n^2)";
180
181 Algorithm* Algo10 = malloc(sizeof(Algorithm));
182 Algo10->type = "bubble_sort_c_and_e";
183 Algo10->complexity = "O (n^2)";
184
185 Algorithm* Algo11 = malloc(sizeof(Algorithm));
186 Algo11->type = "bubble_sort_c_and_f";
187 Algo11->complexity = "O (n^2)";
188
189 Algorithm* Algo12 = malloc(sizeof(Algorithm));
190 Algo12->type = "bubble_sort_e_and_f";
191 Algo12->complexity = "O (n^2)";
192
193 Algorithm* Algo13 = malloc(sizeof(Algorithm));
194 Algo13->type = "bubble_sort_b_and_e_and_f";
195 Algo13->complexity = "O (n^2)";
196
197 Algorithm* Algo14 = malloc(sizeof(Algorithm));
198 Algo14->type = "bubble_sort_b_and_c_and_e_and_f";
199 Algo14->complexity = "O (n^2)";
200
201 Algorithm* Algo15 = malloc(sizeof(Algorithm));
202 Algo15->type = "quicksort";
203 Algo15->complexity = "O (n logn n)";
204
205 Algorithm* Algo16 = malloc(sizeof(Algorithm));
206 Algo16->type = "insertion_sort";
207 Algo16->complexity = "O (2n)";
208
209 Algorithm* Algo17 = malloc(sizeof(Algorithm));
210 Algo17->type = "selection_sort";
211 Algo17->complexity = "O (2n)";
212
213 Algorithm* Algo18 = malloc(sizeof(Algorithm));
214 Algo18->type = "top down merge sort";
215 Algo18->complexity = "O (n log n)";
216
217 Res->algorithms[0] = Algo1;
218 Res->algorithms[1] = Algo2;
219 Res->algorithms[2] = Algo3;
220 Res->algorithms[3] = Algo4;
221 Res->algorithms[4] = Algo5;
222 Res->algorithms[5] = Algo6;
223 Res->algorithms[6] = Algo7;
224 Res->algorithms[7] = Algo8;
225 Res->algorithms[8] = Algo9;
226 Res->algorithms[9] = Algo10;
227 Res->algorithms[10] = Algo11;
228 Res->algorithms[11] = Algo12;
229 Res->algorithms[12] = Algo13;
230 Res->algorithms[13] = Algo14;
231 Res->algorithms[14] = Algo15;
232 Res->algorithms[15] = Algo16;
233 Res->algorithms[16] = Algo17;
234 Res->algorithms[17] = Algo18;
235
236 memoryStats.memJournal = malloc(10 * sizeof(int));
237
238 memoryStats.memUsedByJournal = 10;
239
240 memoryStats.JournalPointerCount = 0;
241
242 printf("Mem used total: %d\n", memoryStats.memUsed);
243
244 int size;
245 int min;
246 int max;
247 int repeat;
248
249 array_count = get_pos_num("How many arrays would you like to test? > ", 0);
250 size = get_pos_num("What is the size of each array? > ", 0);
251 min = get_pos_num("What is the minimum number in each array? > ", 0);
252 max = get_pos_num("What is the maximum number in each array? > ", 0);
253
254 while (1) {
255 printf("How many repeating values there will be AT LEAST? > ");
256 if (scanf("%d", &repeat) == 1 && repeat >= 0
257 && repeat <= (max - min + 1) && getchar() == '\n') {
258 break;
259 } else {
260 while (getchar() != '\n')
261 ;
262 printf("Please enter a positive integer or zero, which is not "
263 "greater than the "
264 "size of the array\n");
265 }
266 }
267
268 for (int i = 0; i < array_count; i++) {
269 int* data = malloc(size * sizeof(int));
270
271 filldata(data, size, min, max, repeat);
272 if (data == NULL)
273 die("Atminties problema");
274
275 printf("i: %d", i);
276 print_array(data, size, "Your generated numbers:");
277 //---------------------------USING FUNCTION POINTERS-----------------//
278
279 test_sort(data, size, &bubble_sort_a, Algo1, i + 1);
280 test_sort(data, size, &bubble_sort_b, Algo2, i + 1);
281 test_sort(data, size, &bubble_sort_c, Algo3, i + 1);
282 test_sort(data, size, &bubble_sort_d, Algo4, i + 1);
283 test_sort(data, size, &bubble_sort_e, Algo5, i + 1);
284 test_sort(data, size, &bubble_sort_f, Algo6, i + 1);
285 test_sort(data, size, &bubble_sort_b_and_c, Algo7, i + 1);
286 test_sort(data, size, &bubble_sort_b_and_e, Algo8, i + 1);
287 test_sort(data, size, &bubble_sort_b_and_f, Algo9, i + 1);
288 test_sort(data, size, &bubble_sort_c_and_e, Algo10, i + 1);
289 test_sort(data, size, &bubble_sort_c_and_f, Algo11, i + 1);
290 test_sort(data, size, &bubble_sort_e_and_f, Algo12, i + 1);
291 test_sort(data, size, &bubble_sort_b_and_e_and_f, Algo13, i + 1);
292 test_sort(data, size, &bubble_sort_b_and_c_and_e_and_f, Algo14, i + 1);
293
294 test_sort(data, size, &bubble_sort_c_and_f, Algo15, i + 1);
295 test_sort(data, size, &bubble_sort_e_and_f, Algo16, i + 1);
296 test_sort(data, size, &bubble_sort_b_and_e_and_f, Algo17, i + 1);
297 test_sort(data, size, &bubble_sort_b_and_c_and_e_and_f, Algo18, i + 1);
298
299
300 free(data);
301 }
302
303 calculate_average(Algo1);
304 calculate_average(Algo2);
305 calculate_average(Algo3);
306 calculate_average(Algo4);
307 calculate_average(Algo5);
308 calculate_average(Algo6);
309 calculate_average(Algo7);
310 calculate_average(Algo8);
311 calculate_average(Algo9);
312 calculate_average(Algo10);
313 calculate_average(Algo11);
314 calculate_average(Algo12);
315 calculate_average(Algo13);
316 calculate_average(Algo14);
317 calculate_average(Algo15);
318 calculate_average(Algo16);
319 calculate_average(Algo17);
320 calculate_average(Algo18);
321
322
323 for (int i = 0; i < 18; i++) {
324 print_algo(Res->algorithms[i]);
325 }
326
327
328 Algorithm** target = malloc(18 * sizeof(Algorithm));
329
330 target[0] = Algo1;
331 target[1] = Algo2;
332 target[2] = Algo3;
333 target[3] = Algo4;
334 target[4] = Algo5;
335 target[5] = Algo6;
336 target[6] = Algo7;
337 target[7] = Algo8;
338 target[8] = Algo9;
339 target[9] = Algo10;
340 target[10] = Algo11;
341 target[11] = Algo12;
342 target[12] = Algo13;
343 target[13] = Algo14;
344 target[14] = Algo15;
345 target[15] = Algo16;
346 target[16] = Algo17;
347 target[17] = Algo18;
348
349 target = rank_algorithms(target, 0, 17);
350
351 printf("Fastest algorithms (ranking):\n");
352 printf("=============================\n");
353
354 for (int i = 0; i < 18; i++) {
355 printf("%d. ", i + 1);
356 printf("%s\n", target[i]->type);
357 printf("Average time: %f\n", target[i]->avg_time);
358 printf("---------------------------------\n");
359 }
360
361 printf("================================\n");
362 printf("Date: %s\n", Res->date);
363 printf("Architecture: %s\n", Res->arch);
364 printf("Compiler: %s\n", Res->compiler);
365 printf("================================\n");
366
367 printf("Mem used total: %d\n", memoryStats.memUsed);
368
369
370 free(Res);
371
372
373 for (int i = 0; i < array_count; i++) {
374 free(Algo1->iterations[i]);
375 }
376 free(Algo1);
377
378 for (int i = 0; i < array_count; i++) {
379 free(Algo2->iterations[i]);
380 }
381 free(Algo2);
382
383 for (int i = 0; i < array_count; i++) {
384 free(Algo3->iterations[i]);
385 }
386 free(Algo3);
387
388 for (int i = 0; i < array_count; i++) {
389 free(Algo4->iterations[i]);
390 }
391 free(Algo4);
392
393 for (int i = 0; i < array_count; i++) {
394 free(Algo5->iterations[i]);
395 }
396 free(Algo5);
397
398 for (int i = 0; i < array_count; i++) {
399 free(Algo6->iterations[i]);
400 }
401 free(Algo6);
402
403 for (int i = 0; i < array_count; i++) {
404 free(Algo7->iterations[i]);
405 }
406 free(Algo7);
407
408 for (int i = 0; i < array_count; i++) {
409 free(Algo8->iterations[i]);
410 }
411 free(Algo8);
412
413 for (int i = 0; i < array_count; i++) {
414 free(Algo9->iterations[i]);
415 }
416 free(Algo9);
417
418 for (int i = 0; i < array_count; i++) {
419 free(Algo10->iterations[i]);
420 }
421 free(Algo10);
422
423 for (int i = 0; i < array_count; i++) {
424 free(Algo11->iterations[i]);
425 }
426 free(Algo11);
427
428 for (int i = 0; i < array_count; i++) {
429 free(Algo12->iterations[i]);
430 }
431 free(Algo12);
432
433 for (int i = 0; i < array_count; i++) {
434 free(Algo13->iterations[i]);
435 }
436 free(Algo13);
437
438 for (int i = 0; i < array_count; i++) {
439 free(Algo14->iterations[i]);
440 }
441 free(Algo14);
442
443 for (int i = 0; i < array_count; i++) {
444 free(Algo15->iterations[i]);
445 }
446 free(Algo15);
447
448 for (int i = 0; i < array_count; i++) {
449 free(Algo16->iterations[i]);
450 }
451 free(Algo16);
452
453 for (int i = 0; i < array_count; i++) {
454 free(Algo17->iterations[i]);
455 }
456 free(Algo17);
457
458 for (int i = 0; i < array_count; i++) {
459 free(Algo18->iterations[i]);
460 }
461 free(Algo18);
462
463 free(target);
464 free(memoryStats.memJournal);
465 }
466
467
468 void filldata(int* data, int size, int min, int max, int repeat)
469 {
470 int i;
471
472 for (i = 0; i < size; i++) {
473 data[i] = min + rand() % (max - min + 1);
474 }
475
476 if (repeat > 1) {
477 int repeat_value = min + rand() % (max - min + 1);
478
479 int indexes[repeat];
480
481 int x;
482
483 // Non-duplicate number generation
484
485 i = 0;
486 while (i < repeat) {
487 int index = rand() % size;
488
489 for (x = 0; x < i; x++) {
490 if (indexes[x] == index) {
491 break;
492 }
493 }
494 if (x == i) {
495 indexes[i++] = index;
496 }
497 }
498
499 for (i = 0; i < repeat; i++) {
500 data[indexes[i]] = repeat_value;
501 }
502 }
503 }
504
505
506 void test_sort(int* data, int size, sort_pointer func, Algorithm* Algo, int no)
507 {
508
509 count_ncomp = 0;
510 count_assign = 0;
511
512 begin = clock();
513
514 int* target = NULL;
515 target = malloc(size * sizeof(int));
516 if (!target)
517 die("Memory error.");
518
519 memcpy(target, data, size * sizeof(int));
520
521 Iteration* Iter = malloc(sizeof(Iteration));
522 if (Iter == NULL) {
523 exit(1);
524 }
525 Iter->no = no;
526
527 if (is_sorted(func(target, size), size)) {
528 end = clock();
529 clocks = (double)(end - begin);
530 time_spent = clocks / CLOCKS_PER_SEC;
531
532 Iter->is_sorted = 1;
533 Iter->comp_count = count_ncomp;
534 Iter->assign_count = count_assign;
535 Iter->clocks_total = clocks;
536 Iter->time_spent = time_spent;
537 } else {
538 Iter->is_sorted = 0;
539
540 };
541
542 Algo->iterations[no - 1] = Iter;
543
544 if (target == NULL) {
545 debug("Target is NULL");
546 }
547
548 free(target);
549 }
550
551
552 void print_algo(Algorithm* Algo)
553 {
554
555 printf("Algorithm type: %s\n", Algo->type);
556 printf("Time complexity: %s\n", Algo->complexity);
557 printf("----------------------------------\n");
558 for (int i = 0; i < array_count; i++) {
559 if (!Algo->iterations[i]->is_sorted) {
560 printf("Not sorted");
561 } else {
562 printf("no: %d\n", Algo->iterations[i]->no);
563 printf("is_sorted: True\n");
564 printf("comp_count: %d\n", Algo->iterations[i]->comp_count);
565 printf("assign count: %d\n", Algo->iterations[i]->assign_count);
566 printf("clocks total: %f\n", Algo->iterations[i]->clocks_total);
567 printf("time spent: %f\n", Algo->iterations[i]->time_spent);
568 }
569 printf("----------------------------------\n");
570 }
571 printf("Iteration count: %d\n", Algo->iter_count);
572 printf("Average compare count: %d\n", Algo->avg_comp);
573 printf("Average assign count: %d\n", Algo->avg_assign);
574 printf("Average clocks: %f\n", Algo->avg_clocks);
575 printf("Average time spent: %f\n", Algo->avg_time);
576
577 printf("===================================\n");
578 }
579
580 void calculate_average(Algorithm* Algo)
581 {
582 int sum_comp = 0;
583 int sum_assign = 0;
584 double sum_clocks = 0;
585 double sum_time = 0;
586 int sorted_count = array_count;
587
588 for (int i = 0; i < array_count; i++) {
589
590 debug("is sorted %d", Algo->iterations[i]->is_sorted);
591 debug("Array count: %d", i);
592
593 if (!Algo->iterations[i]->is_sorted) {
594 sorted_count--;
595 } else {
596 sum_comp += Algo->iterations[i]->comp_count;
597 sum_assign += Algo->iterations[i]->assign_count;
598 sum_clocks += Algo->iterations[i]->clocks_total;
599 sum_time += Algo->iterations[i]->time_spent;
600 }
601 }
602 if (sorted_count > 0) {
603 Algo->avg_comp = sum_comp / sorted_count;
604 Algo->avg_assign = sum_assign / sorted_count;
605 Algo->avg_clocks = (double)(sum_clocks / sorted_count);
606 Algo->avg_time = (double)(sum_time / sorted_count);
607 Algo->iter_count = sorted_count;
608 }
609 }
610
611 Algorithm** rank_algorithms(Algorithm** target, int first, int last)
612 {
613
614 Algorithm* temp;
615 int pivot, j, i;
616
617 if (first < last) {
618 pivot = first;
619 i = first;
620 j = last;
621
622 while (i < j) {
623 while (
624 target[i]->avg_time <= target[pivot]->avg_time && i < last) {
625 i++;
626 }
627 while (target[j]->avg_time > target[pivot]->avg_time) {
628 j--;
629 }
630 if (i < j) {
631 temp = target[i];
632 target[i] = target[j];
633 target[j] = temp;
634 }
635 }
636
637 temp = target[pivot];
638 target[pivot] = target[j];
639 target[j] = temp;
640
641 rank_algorithms(target, first, j - 1);
642 rank_algorithms(target, j + 1, last);
643 }
644 return target;
645 }
646
What I can successfully do (running a program):
How many arrays would you like to test? > 100
What is the size of each array? > 10
What is the minimum number in each array? > 1
What is the maximum number in each array? > 10
How many repeating values there will be AT LEAST? > 0
What I can't do:
How many arrays would you like to test? > 1000
What is the size of each array? > 10
What is the minimum number in each array? > 1
What is the maximum number in each array? > 10
How many repeating values there will be AT LEAST? > 0
The problem is when there are 1000 arrays to be tested (instead of 100).
This is the same error I get:
DEBUG pratybos12.c:590: is sorted 1
DEBUG pratybos12.c:591: Array count: 919
==5798== Invalid read of size 4
==5798== at 0x10A646: calculate_average (pratybos12.c:590)
==5798== by 0x1096F5: main (pratybos12.c:313)
==5798== Address 0x2d2d2d2d2d2d2d31 is not stack'd, malloc'd or (recently) free'd
==5798==
==5798==
==5798== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==5798== General Protection Fault
==5798== at 0x10A646: calculate_average (pratybos12.c:590)
==5798== by 0x1096F5: main (pratybos12.c:313)
The question is, how to even start debugging it, ie where the problem might be.
A few notes:
(1) When I run it with 100 arrays (first case), Valgrind reports that all memory is successfully freed, no leaks occur.
(2) I had a "double free or corruption error" in line 300:
300 free(data);
but I turned it off by setting MALLOC_CHECK_ to 0.
The size of Algorithm.iterations is MAX_ITER which is 100. And then you access Algorithm.iterations elements up to 1000th. This is undefined behavior.
Algorithm** target = malloc(18 * sizeof(Algorithm)); is wrong for sure. The type of target should be Algorithm *.

Generate Unique Values

I want to create a C program to generate numbers from 0 to 999999, keeping in mind that the number generated should not have any digits that are repetitive within it. For example, "123" is an acceptable value but not "121" as the '1' is repeated. I have sourced other program codes that check if an integer has repeated digits:
Check if integer has repeating digits. No string methods or arrays
What is the fastest way to check for duplicate digits of a number?
However these do not really solve my problem and they are very inefficient solutions if I were to perform the check for 1,000,000 different values. Moreover, the solution provided is for int and not char[] and char *, which I use in my program. Below is my code thus far. As you can see I have no problems handling values of up to "012", however the possibilities for values with 3 digits and above are too many to list and too inefficient to code. Would appreciate some help.
int i, j;
char genNext[7] = "0";
printf("%s\n", genNext);
// loop through to return next pass in sequence
while (1) {
for (i = 0; i < sizeof(genNext) / sizeof(char); i++) {
if (genNext[i] == '9') {
char * thisPass = strndup(genNext, sizeof(genNext));
int countDigit = (int) strlen(thisPass);
switch (countDigit) {
case 1:
genNext = "01";
break;
case 2:
if (strcmp(genNext, "98")) {
if (i == 0) {
genNext[1] += 1;
} else {
genNext[0] += 1;
genNext[1] == '0';
}
} else {
genNext = "012";
}
break;
case 3:
if (strcmp(genNext, "987")) {
// code to handle all cases
} else {
genNext = "0123";
}
break;
case 4:
case 5:
case 6:
// insert code here
}
break;
} else if (genNext[i] == '\0') {
break;
} else if (genNext[i+1] == '\0') {
genNext[i] += 1;
for (j = 0; j < i; j++) {
if (genNext[i] == genNext[j]) {
genNext[i] += 1;
}
}
} else {
continue;
}
}
printf("%s\n", genNext);
if (strcmp(genNext, "987654") == 0) {
break;
}
}
The main problem that I am facing is the cases when '9' is part of the value that is being tested. For example, the next value in the sequence after "897" is "901" and after "067895" comes "067912" based on the rules of non-repetitiveness as well as sequential returning of the result.
A desired output would be as follows:
0
1
2
3
...
8
9
01
02
03
...
09
10
12
13
...
97
98
012
013
014
...
098
102
103
...
985
986
987
0123
0124
...
etc etc.
Any assistance is appreciated, and if any part of my question was unclear, feel free to clarify. Thanks!
EDIT: How do I generate all permutations of a list of numbers? does not solve my question as the increment from "120398" to "120435" as the next "legal" value in the sequence.
EDIT 2: Updated question to include desired output
There are three variant algorithms below. Adapt variant 3 to suit your requirements.
Variant 1
This is one way to do it. It implements a minor variant of the initialize a table of 10 digit counts to 0; scan the digits, increment the count for each digit encountered, then check whether any of the digit counts is more than 1 algorithm I suggested in a comment. The test function returns as soon as a duplicate digit is spotted.
#include <stdio.h>
#include <stdbool.h>
enum { MAX_ITERATION = 1000000 };
static bool duplicate_digits_1(int value)
{
char buffer[12];
snprintf(buffer, sizeof(buffer), "%d", value);
char digits[10] = { 0 };
char *ptr = buffer;
char c;
while ((c = *ptr++) != '\0')
{
if (++digits[c - '0'] > 1)
return true;
}
return false;
}
int main(void)
{
int count = 0;
for (int i = 0; i < MAX_ITERATION; i++)
{
if (!duplicate_digits_1(i))
{
count += printf(" %d", i);
if (count > 72)
{
putchar('\n');
count = 0;
}
}
}
putchar('\n');
return 0;
}
When run, it produces 168,571 values between 0 and 1,000,000, starting:
0 1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29
30 31 32 34 35 36 37 38 39 40 41 42 43 45 46 47 48 49 50 51 52 53 54 56 57
58 59 60 61 62 63 64 65 67 68 69 70 71 72 73 74 75 76 78 79 80 81 82 83 84
85 86 87 89 90 91 92 93 94 95 96 97 98 102 103 104 105 106 107 108 109 120
123 124 125 126 127 128 129 130 132 134 135 136 137 138 139 140 142 143 145
146 147 148 149 150 152 153 154 156 157 158 159 160 162 163 164 165 167 168
169 170 172 173 174 175 176 178 179 180 182 183 184 185 186 187 189 190 192
193 194 195 196 197 198 201 203 204 205 206 207 208 209 210 213 214 215 216
217 218 219 230 231 234 235 236 237 238 239 240 241 243 245 246 247 248 249
250 251 253 254 256 257 258 259 260 261 263 264 265 267 268 269 270 271 273
…
987340 987341 987342 987345 987346 987350 987351 987352 987354 987356 987360
987361 987362 987364 987365 987401 987402 987403 987405 987406 987410 987412
987413 987415 987416 987420 987421 987423 987425 987426 987430 987431 987432
987435 987436 987450 987451 987452 987453 987456 987460 987461 987462 987463
987465 987501 987502 987503 987504 987506 987510 987512 987513 987514 987516
987520 987521 987523 987524 987526 987530 987531 987532 987534 987536 987540
987541 987542 987543 987546 987560 987561 987562 987563 987564 987601 987602
987603 987604 987605 987610 987612 987613 987614 987615 987620 987621 987623
987624 987625 987630 987631 987632 987634 987635 987640 987641 987642 987643
987645 987650 987651 987652 987653 987654
Before you decide this is 'not efficient', measure it. Are you really exercising it often enough that the performance is a real problem?
Variant 2
Creating the alternative version I suggested in the comments: use strchr() iteratively, checking whether the first digit appears in the tail, and if not whether the second digit appears in the tail, and so on is very easy to implement given the framework of the first answer:
static bool duplicate_digits_2(int value)
{
char buffer[12];
snprintf(buffer, sizeof(buffer), "%d", value);
char *ptr = buffer;
char c;
while ((c = *ptr++) != '\0')
{
if (strchr(ptr, c) != NULL)
return true;
}
return false;
}
When the times are compared I got these results (ng41 uses duplicate_digits_1() and ng43 uses duplicate_digits_2().
$ time ng41 > /dev/null
real 0m0.175s
user 0m0.169s
sys 0m0.002s
$ time ng43 > /dev/null
real 0m0.201s
user 0m0.193s
sys 0m0.003s
$
Repeated timings generally showed similar results, but sometimes I got ng43 running faster than ng41 — the timing on just one set of one million numbers isn't clear cut (so YMMV — your mileage may vary!).
Variant 3
You could also use this technique, which is analogous to 'count digits' but without the conversion to string first (so it should be quicker).
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
enum { MAX_ITERATION = 1000000 };
static bool duplicate_digits_3(int value)
{
char digits[10] = { 0 };
while (value > 0)
{
if (++digits[value % 10] > 1)
return true;
value /= 10;
}
return false;
}
int main(void)
{
int count = 0;
const char *pad = "";
for (int i = 0; i < MAX_ITERATION; i++)
{
if (!duplicate_digits_3(i))
{
count += printf("%s%d", pad, i);
pad = " ";
if (count > 72)
{
putchar('\n');
count = 0;
pad = "";
}
}
}
putchar('\n');
return 0;
}
Because it avoids conversions to strings, it is much faster. The slowest timing I got from a series of 3 runs was:
real 0m0.063s
user 0m0.060s
sys 0m0.001s
which is roughly three times as fast as either of the other two.
Extra timing
I also changed the value of MAX_ITERATION to 10,000,000 and ran timing. There are many more rejected outputs, of course.
$ time ng41 >/dev/null
real 0m1.721s
user 0m1.707s
sys 0m0.006s
$ time ng43 >/dev/null
real 0m1.958s
user 0m1.942s
sys 0m0.008s
$ time ng47 >/dev/null
real 0m0.463s
user 0m0.454s
sys 0m0.004s
$ ng41 | wc
69237 712891 5495951
$ ng43 | wc
69237 712891 5495951
$ ng47 | wc
69237 712891 5495951
$ cmp <(ng41) <(ng43)
$ cmp <(ng41) <(ng47)
$ cmp <(ng43) <(ng47)
$
These timings were more stable; variant 1 (ng41) was always quicker than variant 2 (ng43), but variant 3 (ng47) beats both by a significant margin.
JFTR: testing was done on macOS Sierra 10.12.1 with GCC 6.2.0 on an old 17" MacBook Pro — Early 2011, 2.3GHz Intel Core i7 with 16 GB 1333 MHz DDR3 RAM — not that memory is an issue with this code. The program numbers are consecutive 2-digit primes, in case you're wondering.
Leading zeros too
This code generates the sequence of numbers you want (though it is only configured to run up to 100,000 — the change for 1,000,000 is trivial). It's fun in a masochistic sort of way.
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
enum { MAX_ITERATIONS = 100000 };
/* lz = 1 or 0 - consider that the number has a leading zero or not */
static bool has_duplicate_digits(int value, int lz)
{
assert(value >= 0 && value < MAX_ITERATIONS + 1);
assert(lz == 0 || lz == 1);
char digits[10] = { [0] = lz };
while (value > 0)
{
if (++digits[value % 10] > 1)
return true;
value /= 10;
}
return false;
}
int main(void)
{
int lz = 0;
int p10 = 1;
int log_p10 = 0; /* log10(0) is -infinity - but 0 works better */
int linelen = 0;
const char *pad = "";
/* The + 1 allows the cycle to reset for the leading zero pass */
for (int i = 0; i < MAX_ITERATIONS + 1; i++)
{
if (i >= 10 * p10 && lz == 0)
{
/* Passed through range p10 .. (10*p10-1) once without leading zeros */
/* Repeat, adding leading zeros this time */
lz = 1;
i = p10;
}
else if (i >= 10 * p10)
{
/* Passed through range p10 .. (10*p10-1) without and with leading zeros */
/* Continue through next range, without leading zeros to start with */
p10 *= 10;
log_p10++;
lz = 0;
}
if (!has_duplicate_digits(i, lz))
{
/* Adds a leading zero if lz == 1; otherwise, it doesn't */
linelen += printf("%s%.*d", pad, log_p10 + lz + 1, i);
pad = " ";
if (linelen > 72)
{
putchar('\n');
pad = "";
linelen = 0;
}
}
}
putchar('\n');
return 0;
}
Sample output (to 100,000):
0 1 2 3 4 5 6 7 8 9 01 02 03 04 05 06 07 08 09 10 12 13 14 15 16 17 18 19
20 21 23 24 25 26 27 28 29 30 31 32 34 35 36 37 38 39 40 41 42 43 45 46 47
48 49 50 51 52 53 54 56 57 58 59 60 61 62 63 64 65 67 68 69 70 71 72 73 74
75 76 78 79 80 81 82 83 84 85 86 87 89 90 91 92 93 94 95 96 97 98 012 013
014 015 016 017 018 019 021 023 024 025 026 027 028 029 031 032 034 035 036
037 038 039 041 042 043 045 046 047 048 049 051 052 053 054 056 057 058 059
061 062 063 064 065 067 068 069 071 072 073 074 075 076 078 079 081 082 083
084 085 086 087 089 091 092 093 094 095 096 097 098 102 103 104 105 106 107
108 109 120 123 124 125 126 127 128 129 130 132 134 135 136 137 138 139 140
…
901 902 903 904 905 906 907 908 910 912 913 914 915 916 917 918 920 921 923
924 925 926 927 928 930 931 932 934 935 936 937 938 940 941 942 943 945 946
947 948 950 951 952 953 954 956 957 958 960 961 962 963 964 965 967 968 970
971 972 973 974 975 976 978 980 981 982 983 984 985 986 987 0123 0124 0125
0126 0127 0128 0129 0132 0134 0135 0136 0137 0138 0139 0142 0143 0145 0146
0147 0148 0149 0152 0153 0154 0156 0157 0158 0159 0162 0163 0164 0165 0167
…
0917 0918 0921 0923 0924 0925 0926 0927 0928 0931 0932 0934 0935 0936 0937
0938 0941 0942 0943 0945 0946 0947 0948 0951 0952 0953 0954 0956 0957 0958
0961 0962 0963 0964 0965 0967 0968 0971 0972 0973 0974 0975 0976 0978 0981
0982 0983 0984 0985 0986 0987 1023 1024 1025 1026 1027 1028 1029 1032 1034
1035 1036 1037 1038 1039 1042 1043 1045 1046 1047 1048 1049 1052 1053 1054
1056 1057 1058 1059 1062 1063 1064 1065 1067 1068 1069 1072 1073 1074 1075
…
9820 9821 9823 9824 9825 9826 9827 9830 9831 9832 9834 9835 9836 9837 9840
9841 9842 9843 9845 9846 9847 9850 9851 9852 9853 9854 9856 9857 9860 9861
9862 9863 9864 9865 9867 9870 9871 9872 9873 9874 9875 9876 01234 01235 01236
01237 01238 01239 01243 01245 01246 01247 01248 01249 01253 01254 01256 01257
01258 01259 01263 01264 01265 01267 01268 01269 01273 01274 01275 01276 01278
01279 01283 01284 01285 01286 01287 01289 01293 01294 01295 01296 01297 01298
…
09827 09831 09832 09834 09835 09836 09837 09841 09842 09843 09845 09846 09847
09851 09852 09853 09854 09856 09857 09861 09862 09863 09864 09865 09867 09871
09872 09873 09874 09875 09876 10234 10235 10236 10237 10238 10239 10243 10245
10246 10247 10248 10249 10253 10254 10256 10257 10258 10259 10263 10264 10265
…
98705 98706 98710 98712 98713 98714 98715 98716 98720 98721 98723 98724 98725
98726 98730 98731 98732 98734 98735 98736 98740 98741 98742 98743 98745 98746
98750 98751 98752 98753 98754 98756 98760 98761 98762 98763 98764 98765 012345
012346 012347 012348 012349 012354 012356 012357 012358 012359 012364 012365
012367 012368 012369 012374 012375 012376 012378 012379 012384 012385 012386
…
098653 098654 098657 098671 098672 098673 098674 098675 098712 098713 098714
098715 098716 098721 098723 098724 098725 098726 098731 098732 098734 098735
098736 098741 098742 098743 098745 098746 098751 098752 098753 098754 098756
098761 098762 098763 098764 098765
Using a loop (from 0 to 999,999, inclusive), and rejecting values with repeating digits sounds like the most straightforward implementation to me.
The reject-if-duplicate-digits function can be made to be pretty fast. Consider, for example,
int has_duplicate_digits(unsigned int value)
{
unsigned int digit_mask = 0U;
do {
/* (value % 10U) is the value of the rightmost
decimal digit of (value).
1U << (value % 10U) refers to the value of
the corresponding bit -- bit 0 to bit 9. */
const unsigned int mask = 1U << (value % 10U);
/* If the bit is already set in digit_mask,
we have a duplicate digit in value. */
if (mask & digit_mask)
return 1;
/* Mark this digit as seen in the digit_mask. */
digit_mask |= mask;
/* Drop the rightmost digit off value.
Note that this is integer division. */
value /= 10U;
/* If we have additional digits, repeat loop. */
} while (value);
/* No duplicate digits found. */
return 0;
}
This is actually a classical combinatorial problem. Below is a proof of concept implementation using Algorithm L in TAOCP 7.2.1.2 and Algorithm T in TAOCP 7.2.1.3. There might be some errors. Refer to the algorithms for details.
Here is a bit of explanation. Let t be the number of digits. For t == 10, the problem is to generate all t! permutations of the set {0,1,2,...,9} in lexicographic order (Algorithm L).
For t > 0 and t < 10, this breaks down to 1) Generate all combinations of t digits from the 10 possible digits. 2). For each combination, generate all t! permutations.
Last, you can sort all 10! + 10! / 2 + 10! / 3! + .. + 10 results. The sorting might look expensive at first. But first, the combination generating is already in lexical order. Second, the permutation generating is also in lexical order. So the sequence is actually highly regular. A QSort is not really too bad here.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static inline int compare_str(const void *a, const void *b)
{
return strcmp(a, b);
}
static inline int compare_char(const void *a, const void *b)
{
char ca = *((char *) a);
char cb = *((char *) b);
if (ca < cb)
return -1;
if (ca > cb)
return 1;
return 0;
}
// Algorithm L in TAOCP 7.2.1.2
static inline char *algorithm_l(int n, const char *c, char *r)
{
char a[n + 1];
memcpy(a, c, n);
a[n] = '\0';
qsort(a, n, 1, compare_char);
while (1) {
// L1. [Visit]
memcpy(r, a, n + 1);
r += n + 1;
// L2. [Find j]
int j = n - 1;
while (j > 0 && a[j - 1] >= a[j])
--j;
if (j == 0)
break;
// L3. [Increase a[j - 1]]
int l = n;
while (l >= 0 && a[j - 1] >= a[l - 1])
--l;
char tmp = a[j - 1];
a[j - 1] = a[l - 1];
a[l - 1] = tmp;
// L4. [Reverse a[j]...a[n-1]]
int k = j + 1;
l = n;
while (k < l) {
char tmp = a[k - 1];
a[k - 1] = a[l - 1];
a[l - 1] = tmp;
++k;
--l;
}
}
return r;
}
// Algorithm T in TAOCP 7.2.1.2
static inline void algorithm_t(int t, char *r)
{
assert(t > 0);
assert(t < 10);
// Algorithm T in TAOCP 7.2.1.3
// T1. [Initialize]
char c[12]; // the digits
for (int i = 0; i < t; ++i)
c[i] = '0' + i;
c[t] = '9' + 1;
c[t + 1] = '0';
char j = t;
char x = '0';
while (1) {
// T2. [Visit]
r = algorithm_l(t, c, r);
if (j > 0) {
x = '0' + j;
} else {
// T3. [Easy case?]
if (c[0] + 1 < c[1]) {
++c[0];
continue;
}
j = 2;
// T4. [Find j]
while (1) {
c[j - 2] = '0' + j - 2;
x = c[j - 1] + 1;
if (x != c[j])
break;
++j;
}
// T5. [Done?]
if (j > t)
break;
}
// T6. [Increase c[j - 1]]
c[j - 1] = x;
--j;
}
}
static inline void generate(int t)
{
assert(t >= 0 && t <= 10);
if (t == 0)
return;
int n = 1;
int k = 10;
for (int i = 1; i <= t; ++i, --k)
n *= k;
char *r = (char *) malloc((t + 1) * n);
if (t == 10) {
algorithm_l(10, "0123456789", r);
} else {
algorithm_t(t, r);
}
qsort(r, n, t + 1, strcmpv);
for (int i = 0; i < n; ++i, r += t + 1)
printf("%s\n", r);
}
int main()
{
for (int t = 1; t <= 10; ++t)
generate(t);
}
Efficiency: This is implementation is not very efficient. It is a direct translation from the algorithm, for easier understanding. However it is still a lot more efficient than iterating over 10^10 numbers. It takes about 2.5 seconds to generate all numbers from 0 to 9876543210. This includes the time of writing them to a file, a 94MB output file, with one number a line. For up to 6 digits, it takes about 0.05 seconds.
If you want these numbers come in the order you want in program, it might be better to generate the numbers as above to prepare a table and use the table later. Even for the table from 0 to 9876543210, there are less than ten million numbers, which is not a really big number in today's computers. In your case, up to six digits, there are only less than one million numbers.

I need to find the prime numbers from 1 to 300 using C. I am using the following code

I know that there is mistake in second for loop but I am not able to figure out. I think after if the continue will take it to to for loop if a%i ==0 and if a%i!=0 than it should print a which would be an prime number , but instead it is printing all the numbers from 2 to 300. Please help!!
The continue and break instructions both instruct the inner i loop. So whatever happens, your code prints every value of a in the outer loop.
#include <stdio.h>
int main(void) {
int a, i;
for (a=1; a<=300; a++) {
for (i=2; i<a; i++) { // changed from the clumsy i<=a-1
if (a % i == 0)
break; // end loop if i is a divisor
}
if (i == a) // if the loop completed
printf ("%d\t", a);
}
return 0;
}
Program output:
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293
It's also a rather crude way to figure out primes, but first things first.
Better try this:
#include<stdio.h>
int main()
{
int i,j,isPrime;
for(i=2;i<300;i++)
{
isPrime = 1; //Firstly we assume that the number is prime;
for(j=2;j<i-1;j++) // you can also use i/2 or sqrt(i) for checking
{
if(i%j==0) //This condition only evaluates to true when j is factor of i
{
isPrime = 0;
break; //Now as we have a factor we are sure its not prime,So break the loop;
}
}
if(isPrime == 1) printf("%d\t",i);
}
return 0;
}
In your inner loop, you do either a break or a continue. But this merely breaks or continues the inner loop, and the printf will be executed irrespective of which is chosen. If you'd pasted the code as text, I might have fixed it for you!

Detect end of line in C

This is the code which read a matrix 10x10 from a file "F1.txt"
#include <stdio.h>
int main( int argc, char ** argv ) {
FILE * fr;
fr = fopen("F1.txt","r");
int i, j;
int matrix[10][10] = {0.0};
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
fscanf(fr, "%d",&matrix[i][j]);
printf("%d\n", matrix[i][j]);
}
}
getchar();
return 0;
}
"F1.txt" looks like this:
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 4 34 56 43 32 124 52 212 3
32 343 34 544 43 32 7 52 456 98
It works without problems but the output is:
12
343
34
544
43
32
124
52
212
3
12
343
34
544
43
32
124
52
212
..........
etc....
I have to detect the end of line to make my input the same like in F1.txt
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 343 34 544 43 32 124 52 212 3
12 4 34 56 43 32 124 52 212 3
32 343 34 544 43 32 7 52 456 98
.
Rewrite the loops the following way
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
fscanf(fr, "%d",&matrix[i][j]);
printf("%3d ", matrix[i][j]);
}
printf( "\n" );
}
You are reading the data correctly, but you are not printing it right. Your program inserts '\n' after each character, that's why you see so many lines.
Change your program like this to see the output that you expect:
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
fscanf(fr, "%d",&matrix[i][j]);
printf("%d ", matrix[i][j]); // <<== Replace \n with a single space
}
printf("\n"); // <<== Add this line
}
Or if you just want your input formatted, you can write your end of line in the outer loop on i.
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
fscanf(fr, "%d",&matrix[i][j]);
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
For your knowledge, EOL is usually a LF character or combination of CR-LF characters. In C they are represented by \n or \r\n respectively.
A possible solution is that you can use fgets to read a complete line at once (fgets will read one line only by itself). Then read out the integers from that string using sscanf or strtok.
I suggest you to use sscanf if you know number of integers in every line.
Otherwise, if a line can contain any amount of numbers then you can use strtok with " " (space) as the delimitter.
You can read more about these functions here: sscanf , strtok
fscanf(fr, "%d",&matrix[i][j]);
printf("%d", matrix[i][j]);
if(j < 10-1)
printf(" ");
else
printf("\n");

Finding all combinations of a^2 + b^2 in C

I'm trying to find all combinations of x, where x = a^2 + b^2, and x is between 100 and 999.
So far i've got:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[] = {0};
for (int a=0; a <= MAX; a++){
for (int b=0; b <= MAX; b++){
if (a*a + b*b >= 100 && a*a + b*b <= 999){
poss_n[i] = a*a + b*b;
printf("%i\n", poss_n[i]);
i++;
}
}
}
}
However it's giving only partially correct output, and also prematurely ends with segmentation fault 11:
100
1380405074
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729
784
841
900
961
101
122
145
170
197
226
257
290
325
362
401
442
485
530
577
626
677
730
785
842
901
962
104
125
148
173
200
229
260
293
328
365
404
445
488
533
580
629
680
733
788
845
904
965
109
130
153
178
205
234
265
298
333
370
409
450
493
538
585
634
685
738
793
850
909
970
116
137
160
185
212
241
272
305
340
377
416
457
500
545
592
641
692
745
800
857
916
977
106
125
146
169
194
221
250
281
314
349
386
425
466
509
554
601
650
701
754
809
866
925
986
100
117
136
157
180
205
232
261
292
325
360
397
436
477
520
Segmentation fault: 11
What modifications should I make to my code?
UPDATE
Other than the the array issue, is there anything else wrong with my code? for instance it's still printing 100 as the first value which doesn't appear to be any combination of a^2 + b^2, even when b = 0.
UPDATE 2
Never mind, forgot a = 10, b = 0, which would be 100.
Try:
int poss_n[(MAX + 1) * (MAX + 1)] = {0};
This way you allocate enough memory to store your answers.
Your error is that you don't allocate place to save you results.
try this:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[(MAX + 1) * (MAX + 1)] = {0}; //<<- Give it a size
int result; //<<- Using this to reduce calculation of the value multiple times.
for (int a=0; a <= MAX; a++){
for (int b=0; b <= MAX; b++){
result = a*a + b*b;
if (result >= 100 && result <= 999){
poss_n[i] = result ;
printf("%i\n", result);
i++;
}
}
}
}
int poss_n[] = {0};
This will define array holding one element, leading to Segfault later when you will try to access element with index > 1
Try this , it will work
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[301];
int a,b;
for (a=0; a <= MAX; a++){
for (b=0; b <= MAX; b++){
if (a*a + b*b >= 100 && a*a + b*b <= 999){
poss_n[i] = a*a + b*b;
printf("%i\t i = %d , a = %d , b = %d\n", poss_n[i],i,a,b);
i++;
}
}
}
}
Lots of answers here, but none quite accurate.
Ff we assume that only unique output is printed out, loop should look like this (as Roee Gavirel stated):
for (int a=0; a <= MAX; a++){
for (int b=a; b <= MAX; b++){
poss_n will hold this number of elements: (32+(32-1)+(32-2)+..+1)=1/2*32*(32+1)
So it should be defined as:
int elements = MAX+1;
int *poss_n = (int*)malloc ((1/2)*(elements)*(elements+1));
It will have more elements because of rule 100< value <999, but without that rule it will hold exact number of elements.
As others already said you allocate too few space on stack. Stack goes from high addresses decreasing. So at first You overwrite the stack data corrupting it and then You reach the end of the stack and You try to write to a memory space not allocated to You, or not allocated at all. The CPU generates an exception and that's why the Segmentation fault error occurs.
Also You could allocate some memory with malloc(3) on the heap and not on the stack, and when You found more result You can extend using realloc. It uses more system CPU resources, but reduces the memory overallocation.
On some un*ces You can also dynamically allocate memory on stack, using the alloca(3) function. It behaves very similar then some_type array[some_value], but some_value can be calculated runtime and not compile time.
Also You can use C++ STL containers, like vector and list and You can push the found elements. The allocate memory segments automatically on the heap.
Some comments:
Addition can be used instead of multiplication counting squares. (a+1)^2 - a^2 = 2a + 1. So add (a<<1) + 1 to a temp variable starting from 0. Similar can be applied to b.
Also from the inner loop can be jumped with break if the sum is over 999. You do not need to check the remaining values.
The value b could start from (int)sqrt(100-a*a) (or use a temp varible to keep track of the first b value) to reduce the number of inner loops.

Resources