How to treat negative indices in C? - c

I have been trying to use all possible combinations but I always get segmentation fault
my first guess was to use int *ary = &storage[0] but it doesn't work :( can someone explain me what it is that I'm doing wrong?(Im beginner in C)
thank you!
This is the problem
#include <stdio.h>
#define MINN -50
#define MAXN 50
int main() {
int storage[MAXN - MINN + 1] = {0};
int *ary = &storage[0];
for (int i = MINN; i <= MAXN; i++)
ary[i] = i;
for (int i = MINN; i <= MAXN; i++)
printf("%d ", ary[i]);
The output should be "-50, -49,-48 ... 49, 50"
I have to be doing something wrong here
int *ary = &storage[0]

Arrays always start with index 0.
You have to use an offset to ensure accessing the array accordingly.
Your MINN is useable for that.
Though I recommend to define the macro constants in a more paranoid way, because macro expansion can do weird things with operators.
#include <stdio.h>
#define MINN (-50)
#define MAXN (50)
int main(void) {
int storage[MAXN - MINN + 1] = {0};
int *ary = &storage[0];
for (int i = MINN; i <= MAXN; i++)
ary[i-MINN] = i;
for (int i = MINN; i <= MAXN; i++)
printf("%d ", ary[i-MINN]);
}
Output (from https://www.tutorialspoint.com/compile_c_online.php):
-50 -49 -48 -47 -46 -45 -44 -43 -42 -41 -40 -39 -38 -37 -36 -35 -34 -33 -32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

Don't mix up array sizes and the values you store in them. In this case you wish to store 50 + 50 + 1 numbers in an array. So make a separate constant for its size, for example:
#define ARR_SIZE (-MINN + MAXN + 1)
int storage [ARR_SIZE] = ...;
Now we don't have to worry about what values those other constants have nor do any arithmetic involving them. Simply use ARR_SIZE. Same thing in the loop, don't mix up array indices with array values:
int val = MINN;
for(size_t i=0; i<ARR_SIZE; i++)
{
arr[i] = val;
val++;
}
Overall keep it simple and there will be no bugs.

With no defines (but malloc), and no parallel counter (but a formula) it could be:
#include <stdio.h>
#include <stdlib.h>
const int AMPL = 50;
/* Store and print numbers from -AMPL to AMPL */
void main(void) {
extern const int AMPL; // not needed
const int SZ = 2*AMPL + 1;
int *ary = malloc(SZ * sizeof *ary);
for (int i = 0; i < SZ; i++) {
ary[i] = i - AMPL;
printf("%d ", ary[i]);
}
}
This is only for symmetric series of course. What exactly are you trying?

Related

Project Euler #2 (Even Fibonacci numbers): O(1) solution

Project Euler #2 Even Fibonacci Numbers
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... By considering the terms in the
Fibonacci sequence whose values do not exceed four million, find the
sum of the even-valued terms.
Question: Is it possible to solve this in constant time?
Here is a hand-wavy O(1)-ish solution to PE-2, see comment by #harold :( above. My solution is psuedo-mathematical and not rigorous but hey, it works!
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... By considering the terms in the
Fibonacci sequence whose values do not exceed four million, find the
sum of the even-valued terms.
Some building blocks:
Binet's formula allows us to compute Fn instantly
There is another well-known formula for the sum of the first n fibonacci number i.e. F0 + F1 + ... + Fn = Fn+2 - 1
We need a formula for computing the sum of first k even numbers of the fibonacci sequence. Let En denote the n-th even number in the sequence so E1 = 2. It is well-known that En = 4En-1 - En-2. Many solutions to this problem utilise this very formula. Doing a bit of math (proof in appendix), you can see that
E1 + E2 + ... + Ek = (Ek+2 - 3Ek+1 - 2) ÷ 4 = (F3(k+2) - 3F3(k+1) - 2) ÷ 4 since En = F3n
We can compute the above using Binet's formula. The only question that remains is given a bound X what should k be? We invert Binet's formula to solve for n and we get
Rather the ceiling, we floor to get the index n of the fibonacci number below X. Then we only have to count how many even numbers there are in {F0, ..., Fn} and use the formula in Point 3.
C Implementation:
I tested it against brute force solutions. Seems to be working fine.
#include <stdio.h>
#include <math.h>
// Input N
// Output N'th term of fibonacci
unsigned long long binet(int N)
{
long double phi = (1.0 + sqrt(5)) / 2.0;
return floor((pow(phi, N) / sqrt(5)) + 0.5);
}
int find_fib_n(unsigned long long F_n)
{
return round(log(sqrt(5) * F_n) / log((1.0 + sqrt(5)) / 2.0));
}
// Input N
// Count of even numbers in the first N fib nums
int count_even_in_fib_seq(int N)
{
if (N <= 3)
return 0;
int tmp = N;
tmp -= 4;
return 1 + floor(tmp / 3);
}
#define bound 4000000
int main(void)
{
int fib_approx_index = find_fib_n(bound);
printf("%d %llu %d\n", fib_approx_index, binet(fib_approx_index), bound);
// Number of even numbers below bound
int K = count_even_in_fib_seq(fib_approx_index + 1);
printf("count %d\n", K);
unsigned long long result = (-3 * binet(3 * (K + 1)) + binet(3 * (K + 2)) - 2) / 4;
printf("%llu", result);
}
Appendix: Formula for sum of the first k even fibonacci numbers
After surfacing the web for a while I found some other people who came up with similar solution. Check out these links for more information:
https://www.xarg.org/puzzle/project-euler/problem-2/
https://brokensandals.net/technical/programming-challenges/projecteuler-2/
Thanks for reading
OEIS also gives a constant solution:
a(n) = (-10 + (5 - 3*sqrt(5))*(2 - sqrt(5))^n + (2 + sqrt(5))^n*(5 + 3*sqrt(5)))/20
-- Colin Barker, Nov 26 2016
Tested in Java:
public class Main {
// https://oeis.org/A099919
static long a(int n) {
double sqrt5 = Math.sqrt(5.0);
return (long)(-10 + (5 - 3 * sqrt5) * Math.pow(2 - sqrt5, n) + Math.pow(2 + sqrt5, n)*(5 + 3*sqrt5))/20;
}
public static void main(String[] args) {
for (int n = 0; n < 20; n++) {
System.out.println(a(n));
}
}
}
prints:
0
2
10
44
188
798
3382
14328
60696
257114
1089154
4613732
19544084
82790070
350704366
1485607536
6293134512
26658145586
112925716858
478361013020
Is it possible to solve this in constant time?
The goal implies using an O(1) equation to calculate the sum rather than a simple puts("4613732");
Given the limit "terms in the Fibonacci sequence whose values do not exceed four million", we only need to deal with Fibonacci(0) to Fibonacci(38) (3,524,578). Note that such a small table is easy to make at compile time with the compiler calculating the values - so no run time cost.
An O(1) equation is demonstrated by others using floating point math (FP).
A problem with a floating point solution is that this is an integer problem that deserves an integer solution. Floating point math has many rounding and inexact computations that render FP approaches questionable for an exact correct answer, especially as N grows large.
It is not enough to simply code some math formula in C using FP math for an integer problem. We need to assess it and determine when do the wheels fall off.
I do not have a better than O(n) integer solution, yet the following can serve as a test harness and reference for those seeking to validate higher value N solutions.
It would be interesting to see how far a FP solution can go before it generates incorrect answers.
#include <assert.h>
#include <math.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#if 0
typedef uint64_t fib_t;
#define FIB_MAX ULLONG_MAX
#define FIB_BASE10_LEN 20
#define FIBONACCI_INDEX_MAX 93
#else
typedef unsigned __int128 fib_t;
#define FIB_MAX ((fib_t) -1)
#define FIB_BASE10_LEN 39
#define FIBONACCI_INDEX_MAX 186
#endif
#define FIB_STR_N (sizeof(fib_t)*CHAR_BIT + 1)
// v--compound literal--v
#define FIB_STR(x) fibonacci_to_string((char [FIB_STR_N]){""}, (x), 10)
char* fibonacci_to_string(char buf[FIB_STR_N], fib_t i, int base) {
assert(base >= 2 && base <= 36);
unsigned ubase = (unsigned) base;
char *s = &buf[FIB_STR_N - 1];
*s = '\0';
do {
s--;
unsigned digit = (unsigned) (i % ubase);
*s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[digit];
i /= ubase;
} while (i);
return s;
}
fib_t fibonacci(unsigned index) {
static fib_t f[FIBONACCI_INDEX_MAX + 1];
static unsigned index_size = 0;
if (index >= index_size) {
if (index_size < 2) {
f[0] = 0;
f[1] = 1;
index_size = 2;
} else if (index > FIBONACCI_INDEX_MAX) {
fprintf(stderr, "Fibonacci index too great %u\n", index);
exit(EXIT_FAILURE);
}
while (index >= index_size) {
f[index_size] = f[index_size - 1] + f[index_size - 2];
index_size++;
}
}
return f[index];
}
fib_t sum_of_even_fibonacci(fib_t f_max) {
fib_t sum = 0;
fib_t f;
for (unsigned index = 0; (f = fibonacci(index)) <= f_max; index += 3) {
if (sum > FIB_MAX - f) {
fprintf(stderr, "Sum too large f:%s sum:%s\n", FIB_STR(f), FIB_STR(sum));
exit(EXIT_FAILURE);
}
sum += f;
}
return sum;
}
int main(void) {
for (unsigned i = 0; 1 && i <= FIBONACCI_INDEX_MAX; i++) {
printf("%3u %*s\n", i, FIB_BASE10_LEN, FIB_STR(fibonacci(i)));
}
printf("Sum of even Fibonacci numbers that do not exceed\n");
printf("%*s %*s\n", FIB_BASE10_LEN, "limit", FIB_BASE10_LEN, "sum");
fib_t f_max = FIB_MAX; // 4000000;
for (fib_t i = 4; i <= f_max; i *= 10) {
printf("%*s %*s\n", FIB_BASE10_LEN, FIB_STR(i), FIB_BASE10_LEN,
FIB_STR(sum_of_even_fibonacci(i)));
if (i >= FIB_MAX / 10)
break;
}
return 0;
}
Output
0 0
1 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
9 34
10 55
11 89
12 144
13 233
14 377
15 610
16 987
17 1597
18 2584
19 4181
20 6765
21 10946
22 17711
23 28657
24 46368
25 75025
26 121393
27 196418
28 317811
29 514229
30 832040
31 1346269
32 2178309
33 3524578
34 5702887
35 9227465
36 14930352
37 24157817
38 39088169
39 63245986
40 102334155
41 165580141
42 267914296
43 433494437
44 701408733
45 1134903170
46 1836311903
47 2971215073
48 4807526976
49 7778742049
50 12586269025
51 20365011074
52 32951280099
53 53316291173
54 86267571272
55 139583862445
56 225851433717
57 365435296162
58 591286729879
59 956722026041
60 1548008755920
61 2504730781961
62 4052739537881
63 6557470319842
64 10610209857723
65 17167680177565
66 27777890035288
67 44945570212853
68 72723460248141
69 117669030460994
70 190392490709135
71 308061521170129
72 498454011879264
73 806515533049393
74 1304969544928657
75 2111485077978050
76 3416454622906707
77 5527939700884757
78 8944394323791464
79 14472334024676221
80 23416728348467685
81 37889062373143906
82 61305790721611591
83 99194853094755497
84 160500643816367088
85 259695496911122585
86 420196140727489673
87 679891637638612258
88 1100087778366101931
89 1779979416004714189
90 2880067194370816120
91 4660046610375530309
92 7540113804746346429
93 12200160415121876738
94 19740274219868223167
95 31940434634990099905
96 51680708854858323072
97 83621143489848422977
98 135301852344706746049
99 218922995834555169026
100 354224848179261915075
101 573147844013817084101
102 927372692193078999176
103 1500520536206896083277
104 2427893228399975082453
105 3928413764606871165730
106 6356306993006846248183
107 10284720757613717413913
108 16641027750620563662096
109 26925748508234281076009
110 43566776258854844738105
111 70492524767089125814114
112 114059301025943970552219
113 184551825793033096366333
114 298611126818977066918552
115 483162952612010163284885
116 781774079430987230203437
117 1264937032042997393488322
118 2046711111473984623691759
119 3311648143516982017180081
120 5358359254990966640871840
121 8670007398507948658051921
122 14028366653498915298923761
123 22698374052006863956975682
124 36726740705505779255899443
125 59425114757512643212875125
126 96151855463018422468774568
127 155576970220531065681649693
128 251728825683549488150424261
129 407305795904080553832073954
130 659034621587630041982498215
131 1066340417491710595814572169
132 1725375039079340637797070384
133 2791715456571051233611642553
134 4517090495650391871408712937
135 7308805952221443105020355490
136 11825896447871834976429068427
137 19134702400093278081449423917
138 30960598847965113057878492344
139 50095301248058391139327916261
140 81055900096023504197206408605
141 131151201344081895336534324866
142 212207101440105399533740733471
143 343358302784187294870275058337
144 555565404224292694404015791808
145 898923707008479989274290850145
146 1454489111232772683678306641953
147 2353412818241252672952597492098
148 3807901929474025356630904134051
149 6161314747715278029583501626149
150 9969216677189303386214405760200
151 16130531424904581415797907386349
152 26099748102093884802012313146549
153 42230279526998466217810220532898
154 68330027629092351019822533679447
155 110560307156090817237632754212345
156 178890334785183168257455287891792
157 289450641941273985495088042104137
158 468340976726457153752543329995929
159 757791618667731139247631372100066
160 1226132595394188293000174702095995
161 1983924214061919432247806074196061
162 3210056809456107725247980776292056
163 5193981023518027157495786850488117
164 8404037832974134882743767626780173
165 13598018856492162040239554477268290
166 22002056689466296922983322104048463
167 35600075545958458963222876581316753
168 57602132235424755886206198685365216
169 93202207781383214849429075266681969
170 150804340016807970735635273952047185
171 244006547798191185585064349218729154
172 394810887814999156320699623170776339
173 638817435613190341905763972389505493
174 1033628323428189498226463595560281832
175 1672445759041379840132227567949787325
176 2706074082469569338358691163510069157
177 4378519841510949178490918731459856482
178 7084593923980518516849609894969925639
179 11463113765491467695340528626429782121
180 18547707689471986212190138521399707760
181 30010821454963453907530667147829489881
182 48558529144435440119720805669229197641
183 78569350599398894027251472817058687522
184 127127879743834334146972278486287885163
185 205697230343233228174223751303346572685
186 332825110087067562321196029789634457848
More output
Sum of even Fibonacci numbers that do not exceed
limit sum
4 2
40 44
400 188
4000 3382
40000 14328
400000 257114
4000000 4613732
40000000 19544084
400000000 350704366
4000000000 1485607536
40000000000 26658145586
400000000000 478361013020
4000000000000 2026369768940
40000000000000 36361730124070
400000000000000 154030760585064
4000000000000000 2763969850442378
40000000000000000 49597426547377748
400000000000000000 210098070363744836
4000000000000000000 3770056902373173214
40000000000000000000 15970217317495049952
400000000000000000000 286573922006908542050
4000000000000000000000 5142360378806858706956
40000000000000000000000 21783388129427422369052
400000000000000000000000 390887039715493615101718
4000000000000000000000000 1655824071758491008590040
40000000000000000000000000 29712557378756321606437562
400000000000000000000000000 125864412841774744075212130
4000000000000000000000000000 2258545247825195935704356468
40000000000000000000000000000 40527950048011752098603204302
400000000000000000000000000000 171679151392093647435137529168
4000000000000000000000000000000 3080657373857639014791750813074
40000000000000000000000000000000 13049874051046942401006156573274
400000000000000000000000000000000 234170488363228576876271664997964
4000000000000000000000000000000000 4202018916487067441371883813390086
40000000000000000000000000000000000 17800037772979229481611438290658376
400000000000000000000000000000000000 319408717806595170952881986194752746
4000000000000000000000000000000000000 1353037041234784669179345581755034578
40000000000000000000000000000000000000 24279264572217720059860402834614598820
By Binet's formula,
√5 F3m = p^m + q^m
where p is the cubed Golden ratio and q the cubed inverse.
Summing from 0 to m = n/3 one gets
√5 Σ F3m = ((p³)^(m+1) - 1) / (p³-1) - ((q³)^(m+1) - 1) / (q³-1)
If floating-point is allowed, this is computed in constant time.
Question: Is it possible to solve this in constant time?
I think OP means O(1) and not constant time as functions like pow(), log() are rarely ever constant time.
Floating point (FP) approach has troubles.
A common problem with FP occurs when one wants fast code (O(1)), yet does not realized how often the answer is incorrect or excessively far from the best answer.
Testing is needed.
Sometime rigorous testing is needed.
OP's answer was not apparently tested with various bounds.
correct bound sum
ref 0 0
ref 2 2
ref 8 10
ref 34 44
ref 144 188
ref 610 798
ref 2584 3382
ref 10946 14328
ref 46368 60696
ref 196418 257114
ref 832040 1089154
ref 3524578 4613732
Haziq 0 0
Haziq 2 2
Haziq 7 10 error
Haziq 27 44 error
Haziq 114 188 error
Haziq 480 798 error
Haziq 2032 3382 error
Haziq 8606 14328 error
Haziq 36453 60696 error
Haziq 154415 257114 error
Haziq 654110 1089154 error
Haziq 2770852 4613732 error
Incorrect results
find_fib_n() is a major culprit.
Using floor() instead of round() helps reduce the various bound errors:
// return round(log(sqrt(5) * F_n) / log((1.0 + sqrt(5)) / 2.0));
return floor(log(sqrt(5) * F_n) / log((1.0 + sqrt(5)) / 2.0));
Yet is still not fully correct.
Haziq 0 0
Haziq 2 2
Haziq 9 10 error
Haziq 34 44
Haziq 145 188 error
Haziq 610 798
Haziq 2585 3382 error
Haziq 10946 14328
Haziq 46369 60696 error
Haziq 196418 257114
Haziq 832041 1089154 ...
Haziq 3524578 4613732
To improve further is challenged by the slight errors in the argument to log() and that the formula used is not fully correct, but only mathematicaly approximate.
We could try:
F_n += (F_n & 1) == 0;
return floor(log2(sqrt(5) * F_n) / log2((1.0 + sqrt(5)) / 2.0));
Which returns the correct result over OP's target range (your results may differ). Yet that is not a vetted solution in general.
As it turns out, F_n += (F_n & 1) == 0; is better than first thought.
Deeper
OP's code hinges on returning a correct value from find_fib_n(bound). Although that function takes a integer, it could take a double. When bound = some_even_fib_number, it returns i, yet with some_even_fib_number - 0.00000001, it needs to return i - 1. Thus find_fib_n(bound) is very sensitive to calculation errors when bound = some_even_fib_number.
Notice that find_fib_n(some_even_bound) is always equal to find_fib_n(some_even_bound + 1) and the return value only change as bound increases from some_odd_bound.9999999 to the _next_even_bound.
Incrementing any even_bound, we push the floating point calculation away from that sensitive some_even_fib_number.00000 to some_even_fib_number + 1.
This nicely provides more error resilience to OP's calculation.
Combined with other silent improves consider:
unsigned long long binet(int N) {
// (sqrt(5) + 1)/2
#define PHI 1.61803398874989484820458683436564
#define root5i 0.44721359549995793928183473374626
double b = pow(PHI, N) * root5i;
assert(b < (double) LLONG_MAX);
return (unsigned long long) llround(b);
}
int find_fib_n(unsigned long long F_n) {
// 1/log2(PHI)
#define LN2PHIi (1.4404200904125564790175514995879)
F_n += (F_n & 1) == 0;
return (int) floor(log2(sqrt(5) * (double)F_n) * LN2PHIi);
}
// Input N
// Count of even numbers in the first N fib nums
int count_even_in_fib_seq(int N) {
if (N <= 3) {
return 0;
}
int tmp = N;
tmp -= 4;
return 1 + tmp / 3;
}
Moral of the story: Test code for correct functionality before worrying about speed.
For reference, follows is a correct and up to a 64-bit sum formed by using integer only math.
bound sum
ref 0 0
ref 2 2
ref 8 10
ref 34 44
ref 144 188
ref 610 798
ref 2584 3382
ref 10946 14328
ref 46368 60696
ref 196418 257114
ref 832040 1089154
ref 3524578 4613732
ref 14930352 19544084
ref 63245986 82790070
ref 267914296 350704366
ref 1134903170 1485607536
ref 4807526976 6293134512
ref 20365011074 26658145586
ref 86267571272 112925716858
ref 365435296162 478361013020
ref 1548008755920 2026369768940
ref 6557470319842 8583840088782
ref 27777890035288 36361730124070
ref 117669030460994 154030760585064
ref 498454011879264 652484772464328
ref 2111485077978050 2763969850442378
ref 8944394323791464 11708364174233842
ref 37889062373143906 49597426547377748
ref 160500643816367088 210098070363744836
ref 679891637638612258 889989708002357094
ref 2880067194370816120 3770056902373173214

Array is printing with weird question mark symbols when printing fibonacci sequences

When printing each Fibonacci sequence the first couple of sequences print in weird symbols or not at all if printing more than 8 sequences.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
//n=amount of numbers in the series to compute, seq=array to store series
void fibonacci(int n, int* seq){
// Complete this function
int i;
seq[0] = 0;
seq[1] = 1;
for(i = 2; i <= n; i++){
seq[i] = seq[i-2] + seq[i-1];
}
}
int main(){
int n;
//n, amount of series to compute
scanf("%d",&n);
//initialize array to 1, using malloc/calloc
int *seq = malloc(1 * sizeof(*seq));
int i;
for(i = 1; i <= n; i++){
//recompute the whole series
fibonacci(i, seq);
//print array
int j;
for(j = 0; j < i; j++)/* complete code */
printf("%d ", seq[j]);
//resize array, with realloc
int newSize=i+1;
int *seq = realloc(seq, newSize);
printf("\n");
}
//free array
return 0;
}
Output:
"7Y��yb�=
Um�*/E�o 1 1 2 3 5 8 13
0 1 1 2 3 5 8 13 21
0 1 1 2 3 5 8 13 21 34
0 1 1 2 3 5 8 13 21 34 55
0 1 1 2 3 5 8 13 21 34 55 89
0 1 1 2 3 5 8 13 21 34 55 89 144
0 1 1 2 3 5 8 13 21 34 55 89 144 233
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
There are different problems in your code:
In your fibonacci() function, you iterate using i <= n, but inside the loop, you assign to seq[i]. When i = n, this becomes a problem: you're accessing one cell out of the array.
You are getting n from user input, but then doing int *seq = malloc(1 * sizeof(*seq)). You are only allocating space for one element, not n. You should do malloc(n * sizeof(*seq)) instead.
Not really an error, but inside the first for loop in your main, you're both re-defining and re-allocating the seq array with int *seq = realloc(...). That is not needed at all. Your array is already n cells big, so there is no need to reallocate it each time. You can use it as is.
Not really an error, but there is no need to recompute the series each time. You can compute it only once and then partially print it on each row without a problem.
Also, IMPORTANT! Using int to hold numbers of the Fibonacci sequence is only good until you reach n = 47. More than that, and your next element will overflow the maximum positive value that an int can hold, turning negative, and invalidating the rest of the calculations too. I would suggest you to use long long unsigned int instead, which would be good up to n = 94 (assuming 64 bits). Ultimately, you should check the value of n before calculating the Fibonacci sequence to avoid an overflow.
Here's a better version of your code with those problems fixed:
void fibonacci(int n, int* seq) {
int i;
seq[0] = 0;
seq[1] = 1;
for(i = 2; i < n; i++)
seq[i] = seq[i-2] + seq[i-1];
}
int main() {
int *seq;
int n, i, j;
scanf("%d",&n);
// Allocate enough space for n elements:
seq = malloc(n * sizeof(*seq));
// Compute the whole series once:
fibonacci(n, seq);
// Print partial series on each row:
for(i = 1; i <= n; i++) {
for(j = 0; j < i; j++)
printf("%d ", seq[j]);
printf("\n");
}
free(seq);
return 0;
}

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.

SIGXFSZ runtime error

I'm trying to submit the solution for Spoj - Prime Intervals problem. But I'm getting a runtime error SIGXFSZ. It is given that, it occurs due to exceeded file size. I have used the Sieve of Eratosthenes algorithm to find the prime numbers. I don't understand what's wrong with my code and this is bugging me from last the 2 days. Please help me with the submission. Here is my code...
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
int main(){
int t, turn;
long i, l,u,k,j;
scanf("%d", &t);
/*Looping for t test cases*/
for(turn=0; turn<t; turn++){
scanf("%ld %ld", &l, &u);
bool arr[u-l+1];
/*Assigning whole array with true*/
memset(arr, true, u-l+1);
/*Sieve of Eratosthenes logic for assigning false to composite values*/
for(i=0; i<=(int)sqrt(u)-l; i++){
k=0;
j = i+l;
if(arr[i]==true){
while((j*j + k*j) <= u){
arr[(j*j + k*j) - l] = false;
k++;
}
}
}
/*Printing all the primes in the interval*/
for(i=0; i<u-l; i++){
if(arr[i]==true){
printf("%ld\n", i+l);
}
}
}
return 0;
}
Test Input:
2
2 10
2 100
Output:
2
3
5
7
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
I ran the posted code. the results were far from correct.
Most of the numbers output are not primes and fails to check the last number is the range, as shown in the second set of results
Here are the results:
1 <-- 1 test case
20 100 <-- range 20...100
20 <-- the outputs
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Note: using 1 as the low end of the range usually results with no output produced
here is another run
The output should have been 5 7 11
1 <-- test cases
5 11 <-- range
5 <-- outputs
6
7
8
9
10
The following code does not try to minimize the size of the arr[] array, and if the upper end of the range is less than 16k then could declare the arr[] as short rather than unsigned int
The lowest valid value for the low end of the input is 2, but the code is not checking for that low limit, you might want to add that check.
The code makes no effort to minimize the number of loops executed by checking for the square root of the upper limit, you might want to add that check.
The code compiles cleanly, handles the case when the upper limit is a prime and when the lower limit is a prime as well as when the limit values are not primes.
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
int numTestCases, testCase;
size_t i; // index
size_t lowLimit;
size_t upperLimit;
size_t k; // offset multiplier
scanf("%d", &numTestCases);
/*Looping for t test cases*/
for(testCase=0; testCase<numTestCases; testCase++)
{
scanf("%lu %lu", (unsigned long*)&lowLimit, (unsigned long*)&upperLimit);
unsigned arr[upperLimit+1];
/*Assigning whole array to indicate entry is a prime*/
memset(arr, 0x01, upperLimit+1);
/*Sieve of Eratosthenes logic for assigning false to composite values*/
//size_t sqrtUpperLimit = (size_t)ceil(sqrt(upperLimit));
for(i=2; i<= upperLimit; i++)
{
if(arr[i])
{
if( i >= lowLimit )
{
printf("%ld\n", i);
}
for( k=2; (i*k) <= upperLimit; k++)
{
arr[(i*k)] = 0;
}
}
}
}
return 0;
} // end function; main
here is an edited version of the code, with the addition of some instrumentation in the way of prompts to the user via calls to printf()
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
int numTestCases, testCase;
size_t i; // index
size_t lowLimit;
size_t upperLimit;
size_t k; // offset multiplier
printf("enter number of test cases\n");
scanf("%d", &numTestCases);
/*Looping for t test cases*/
for(testCase=0; testCase<numTestCases; testCase++)
{
printf( "enter lower limit upper limit limits\n");
scanf("%lu %lu", (unsigned long*)&lowLimit, (unsigned long*)&upperLimit);
unsigned arr[upperLimit+1];
/*Assigning whole array to indicate entry is a prime*/
memset(arr, 0x01, upperLimit+1);
/*Sieve of Eratosthenes logic for assigning false to composite values*/
//size_t sqrtUpperLimit = (size_t)ceil(sqrt(upperLimit));
for(i=2; i<= upperLimit; i++)
{
if(arr[i])
{
if( i >= lowLimit )
{
printf("%ld\n", i);
}
for( k=2; (i*k) <= upperLimit; k++)
{
arr[(i*k)] = 0;
}
}
}
}
return 0;
} // end function; main
Using the above instrumented code and the input of:
5 2 3 30 31 20 27 2 3 4 5
it worked perfectly.
This was the output:
enter number of test cases
5
enter upper/lower limits
2 3
sizeof arr[]: 4
2
3
enter upper/lower limits
30 31
sizeof arr[]: 32
31
enter upper/lower limits
20 27
sizeof arr[]: 28
23
enter upper/lower limits
2 3
sizeof arr[]: 4
2
3
enter upper/lower limits
4 5
sizeof arr[]: 6
5

Error in scanf()

first of all, I've got a logical error in my code. Well, this is the code
#include <stdio.h>
int main()
{
long i,j,t;
scanf("%ld",&t);
long n[t],d[t][t];
for(i = 0; i < t;i++){
scanf("%ld",&n[i]);
for(j = 0; j < n[i] ;j++){
scanf("%ld",&d[j][i]);
}
}
for(i = 0; i < t;i++){
for(j = 0; j < n[i] ;j++){
printf("%ld ",d[j][i]);
}
printf("\n");
}
return 0;
}
And I input the data
2
4
25 20 30 90
3
45 50 55
And the result is
25 20 30 90
45 50 55
Well, that's what I expected. However, when the input become like this
3
5
12 67 89 34 56
6
34 56 78 90 12 34
7
12 34 89 23 56 78 89
The result become like this
12 34 89 23 56 78 89
12 67 89 34 56 4206692 7 2293472 1982002386 16 3 2293344 2293408 0 2293552 0 0 4
198585 8918456 1982106837 1982010910 8918456 2293640 0 0 1985286516 2009576437 0
0 2293664 2009323341 2293740 2147348480 0
34 56 78 90 12 34 4199405 1982595752 8 12 2293424 2 2 1982356412 2147348480 2293
608 2147348480 1 -1 297753669 1982010784 1982015505 4199044 0 0 2147348480 21473
48480 0 0 0 7273647 2009576392 0 0 0 1 0 20 52 0 0 438759246 736 -214797894 1420
760826203 2272 852421325 3108 944791496 4028 -1322777276 4988 9 1 1 1204 7168 4
2 152 11832 7 1 40 12316 1682469715 1 140 44 0 0 0 2 0 7209065 5701724 6029427
12 34 89 23 56 78 89
Well, the simple question, why the output become like the above?? When I input above 2, the same result will be happened. Any possible answers and links if you don't mind it?? Thanks
You are writing outside your 2D array in many cases, sometimes you don't get errors, but that's just by chance.
You determine the size of the 2D array by the number of arrays to be inputted, but you also determine the size of the inner arrays at the same time:
scanf("%ld",&t);
long n[t],d[t][t];
So for example, let's take the first example:
2 >> create array n[2], and array d[2][2]
4 >> number of values to d[0]
25 20 30 90 >> d[0][1] = 25 d[0][2] = 20 you access d[0][3] and d[0][4] but you are not allowed to do that.
3 >> number of values to d[1]
45 50 55 >> d[1][0] = 45 d[1][1] = 50 you access d[1][2] but you are not allowed to do that
You build a matrix with size t*t, then fill in rows with more or less elements.
If you fill a row with too few elements, the rest remain uninitialized, and you get strange numbers. It's OK in your case, because you don't print these elements.
If you fill a row with too many elements, the excess overlaps into the next row. It may also exceed the whole matrix and corrupt your stack.
I guess this is what's going on - your n array is overrun, and your code goes crazy.
I believe that you can use malloc.
#include <stdio.h>
#include <stdlib.h>
int main()
{
long i,j,t;
printf("Rows : ");
scanf("%ld",&t);
long *n;
long **d;
n = (long* )malloc(sizeof(long) * t); // add malloc
d = (long** )malloc(sizeof(long *) * t); // add malloc
for(i = 0; i < t;i++){
printf("Column : ");
scanf("%ld",&n[i]);
d[i] = (long* )malloc(sizeof(long) * n[i]); //add malloc
if(d[i] == NULL)
printf("ERROR\n");
for(j = 0; j < n[i] ;j++){
scanf("%ld", &d[i][j]); // change from &d[j][i]
}
}
printf("\n\n");
for(i = 0; i < t;i++){
for(j = 0; j < n[i] ;j++){
printf("%ld ",d[i][j]); // change from d[j][i]
}
printf("\n");
}
return 0;
}
Well, the simple question, why the output become like the above?? When
I input above 2, the same result will be happened. Any possible
answers and links if you don't mind it?? Thanks
because you allocate less memory than used.
scanf("%ld", &d[j][i]); you have to exchange the "i" and "j".

Resources