I met this problem when verifying whether points in a finite field GF(13) is on elliptic curve y^2 = x^3 + x + 1:
first I set the loop boundary as i<2,the results came out right.
#include <stdio.h>
#include <math.h>
void main ()
{
int a[13], b[13];
int j, i, m, k = 0;
for (i = 0; i < 2; i++)
for (j = 0; j < 13; j++)
if ((i * i * i + i + 1) % 13 == (j * j) % 13) {
a[k] = i;
b[k] = j;
k++;
}
printf ("\n There are %d points on the curve\nThe points are: ", k);
for (m = 0; m < k; m++)
printf ("\nx=%d,y=%d \n", a[m], b[m]);
}
The result is link 1
after I change the i<2 to i<13,
for(i=0;i<13;i++)
the first 4 points changed: link 2
You are entering undefined behavior. If you set a break inside the loop you will notice that k >= 13 which is outside the bounds of your arrays.
You could add some bounds checking and consider the size of your arrays.
Related
How do I make my code more efficient (in time) pertaining to a competitive coding question (source: codechef starters 73 div 4):
(Problem) Chef has an array A of length N. Chef wants to append a non-negative integer X to the array A such that the bitwise OR of the entire array becomes = Y .
Determine the minimum possible value of X. If no possible value of X exists, output -1.
Input Format
The first line contains a single integer T — the number of test cases. Then the test cases follow.
The first line of each test case contains two integers N and Y — the size of the array A and final bitwise OR of the array A.
The second line of each test case contains N space-separated integers A_1, A_2, ..., A_N denoting the array A.
Please don't judge me for my choice of language .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* binary_number(int n) // returns pointer to a array of length 20(based on given constrains) representing binary
{
int* ptc;
ptc = (int*) malloc(20*sizeof(int));
for(int i = 0; i < 20; i++)
{
if((n / (int) pow(2,19-i)) > 0){*(ptc + i) = 1;}
else {*(ptc + i) = 0;}
n = n % (int) pow(2,19-i) ;
}
return ptc;
}
int or_value(int* ptc, int n) // Takes in pointers containing 1 or zero and gives the logical OR
{
for(int k = 0; k < n; n++)
{
if(*ptc == *(ptc + 20*k)){continue;} // pointers are 20 units apart
else{return 1;break;}
}
return *ptc;
}
int main(void) {
int t; scanf("%d", &t);
for (int i = 0; i < t; i++)
{
int n, y;
scanf("%d %d", &n, &y);
int a[n];
for(int j = 0; j < n ; j++)
{
scanf("%d", &a[j]);
}
int b[20*n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 20; k++)
{
b[20*j + k] = *(binary_number(a[n])+k);
}
}
int c = 0;
int p = 0;
for (int j = 0; j < 20; j++)
{
if ((*(binary_number(y) + j) == 1) && (or_value((&b[0] + j),n) == 0)){c = c + pow(2,19 - j);}
else if ((*(binary_number(y) + j) == 0) && (or_value((&b[0] + j),n) == 1)){p = 1; break;}
}
if (p==1){printf("-1");}
else {printf("%d\n", c);}
}
return 0;
}
Q: Find all prime numbers between two given Numbers a and b, by using Sieve of Eratosthene.
Im using dynamic array to store prime numbers, but it does nt work.
After debug it, everything is ok untill the last
printf() that crashes.
Code
int main() {
int i, j, n, a, b, k;
int *tab;
scanf("%i", &n); // n is number of sets
for (i = 1; i <= n; i++){
scanf("%i %i", &a, &b);
tab = (int*) malloc(b * sizeof(int)); //allocating the memorry
for (j= 0; j < b; j++){ //seting all numbers to be prime
*(tab + j) = 1;
}
for (j = 2; j <= b; j++){
if (*(tab + j) == 1){
for(k = j; k <= b; k+=j)
*(tab + k) = 0; //seting 0 for all non prime numbers
}
}
for (j = a; j <= b; j++){
if (*(tab + j) == 1){
printf("%i", j); //printing prime numbers
}
}
free(tab);
}
return 0;
}
your second loop should be
for (j = 2; j <= b; j++){
if (*(tab + j) == 1){
for(k = j; k <= b; k += j)
*(tab + k) = 0; //seting 0 for all non prime numbers
}
}
the problem was that because you used multiplication, you tried to access an item in the tab array with index above its allocated size.
edit: and as #melpomene stated, the array is too short. therefore the allocation should be
tab = (int*) malloc((1+b) * sizeof(int));
The problem is, you're accessing array out of its bounds:
*(tab + k*j) = 0;
when
k <= b
j <= b
When you declare array of b elements, you can only access array from 0 to b-1 index.
BTW, as mentioned in comments, using tab[k*j] is more readable and shows clearly that tab is array.
I don't really understand what you mean by sets number, but pseudocode of Sieve of Eratosthenes taken from wiki is applied from 2 to n. So in your case 2 becomes a and n becomes b. You don't need checking all numbers from a to b, root of b will suffice.
Your algorithm should look like:
create array for holding b - a elements
make every element equals 1
make 0 elements which fulfill Eratosthenes rules for complex number
print indexes which contains 1.
#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j,l,m,n;
j=0;
printf("\nenter 5 element single dimension array\n");
printf("enter shift rate\n");
scanf("%d",&n);
/* Here we take input from user that by what times user wants to rotate the array in left. */
int arr[5],arrb[n];
for(i=0;i<=4;i++){
scanf("%d",&arr[i]);
}
/* Here we have taken another array. */
for(i=0;i<=4;i++){
printf("%d",arr[i]);
}
for(i=0;i<n;i++){
arrb[j]=arr[i];
j++;
// These loop will shift array element to left by position which's entered by user.
}
printf("\n");
for(i=0;i<=3;i++){
arr[i]=arr[i+n];
}
for(i=0;i<=4;i++){
if(n==1 && i==4)
break;
if(n==2 && i==3)
break;
if(n==3 && i==2)
break;
printf("%d",arr[i]);
}
//To combine these two arrays. Make it look like single array instead of two
for(i=0;i<n;i++){
printf("%d",arrb[i]);
}
// Final sorted array will get printed here
}
Is it the efficeint program to rotate array in left direction?
Actually, very complicated, and some problems contained:
for(i = 0; i < n; i++)
{
arrb[j] = arr[i];
j++;
}
Why not simply:
for(i = 0; i < n; i++)
{
arrb[i] = arr[i];
}
There is no need for a second variable. Still, if n is greater than five, you get into trouble, as you will access arr out of its bounts (undefined behaviour!). At least, you should check the user input!
for(i = 0; i <=3 ; i++)
{
arr[i] = arr[i + n];
}
Same problem: last accessible index is 4 (four), so n must not exceed 1, or you again access the array out of bounds...
Those many 'if's within the printing loop for the first array cannot be efficient...
You can have it much, much simpler:
int arr[5], arrb[5];
// ^
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5];
This does not cover negative values of n, though.
arrb[i] = arr[(((i + n) % 5) + 5) % 5];
would be safe even for negative values... All you need now for the output is:
for(int i = 0; i < 5; ++i)
printf("%d ", arrb[i]);
There would be one last point uncovered, though: if user enters for n a value greater than INT_MAX - 4, you get a signed integer overflow, which again is undefined behaviour!
We can again cover this by changing the index formula:
arrb[i] = arr[(5 + i + (n % 5)) % 5];
n % 5 is invariant, so we can move it out of the loop:
n %= 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(5 + i + n) % 5];
Finally, if we make n positive already outside, we can spare the addition in the for loop.
n = ((n % 5) + 5) % 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5]; // my original formula again...
Last step is especially worth considering for very long running loops.
I think you want to do something like this (you should check that 0 <= n <= 5, too):
int b[5];
int k = 0;
for(i=0; i<5; i++){
if (i < 5 - n)
b[i] = arr[i+n];
else
{
b[i] = arr[k];
k++;
}
}
Array b is used to save the rotated matrix.
#include <stdio.h>
int main() {
int N = 133;
int a, b, c, d;
int flag = 0;
for ( int j = 1; j < (N/2); j++)
{
a = j;
for ( int k = 1; k < (N/2); k++)
{
b = k;
for ( int l = 1; l < (N/2); l++)
{
c = l;
for ( int m = 1; m < (N/2); m++)
{
d = m;
if ( a+b+c+d == N && (a != 0 && b!= 0 && c != 0 && d!= 0))
{
printf("\n %d + %d + %d + %d = %d" , a, b, c, d, N);
flag = 1;
break;
}
}
if(flag)
break;
}
if(flag)
break;
}
if(flag)
break;
}
return 0;
}
The code currently outputs
1 + 2 + 65 + 65 = 133
As you can see, I am getting the sum using 4 numbers to form N (133) in this case. Is there a way to improve the code to 'k' numbers without using nested 'k' for loops?
Desired Output: ( a + b + c + d + e + f + ...... + k = N )
say for a given value of N represented using sum of k terms, where k is an input parameter.
Notes:
None of the 'k' terms is zero.
Original question had loops starting from 0; updated to start from 1.
Specific Requirement, I want the terms (a to k) to have the lowest possible standard deviation among all the sums. So breaking out at the first sum is not ideal for that scenario, but this is the baseline code I have reached. Once I figure out reducing number of loops, I know how to modify for lowest S.D.
Also pretty obvious but k < N in all cases.
Much simpler code that does the same thing as yours:
#include <stdio.h>
int main()
{
int N = 133;
for ( int j = 1; j < (N/2); j++)
for ( int k = 1; k < (N/2); k++)
for ( int l = 1; l < (N/2); l++)
for ( int m = 1; m < (N/2); m++)
if ( j+k+l+m == N) {
printf("\n %d + %d + %d + %d = %d" , j, k, l , m, N);
return 0;
}
}
And to your problem, which is a bit vague, but seems to be finding k numbers a_1, a_2 ... a_k such that 1 < a_n < N/2 for all n and a_1+a_2+...+a_k=N. Here is very simple code to do that, using your algorithm but extended for arbitrary k:
#define N 133
#define k 8
int main()
{
int arr[k];
for(int i=0; i<k; i++)
arr[i]=1;
for(int i=0,c=k; c<N; c++) {
arr[i]++;
if(arr[i]>=N/2) {
c--;
i++;
}
}
for(int i=0; i<k-2; i++)
printf("%d + ", arr[i]);
printf("%d = %d\n", arr[k-1], N);
}
It has no error checking. The problem is not solvable for k=1 and k>N. And because integer division is rounded down, it is not solvable for k=2 if N is odd.
But here is some MUCH more efficient code. The problem is very simple, so it's not about finding the numbers a_1, a_2, a_3 ... a_k. It's really only about finding a_1 and a_2. The rest are one.
#define N 19
#define k 5
int main()
{
for(int i=0; i<k-2; i++)
printf("1 + ");
int c=N/2-(k-2);
if (c<1)
c=1;
printf("%d + ", c);
printf("%d = %d\n", N-(k-2)-c, N);
}
Again, no error check is made.
This is a program on sorting integers.
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
scanf("%d", &n);
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
scanf("%d", &nmbr[i]);
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting : \n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
return 0;
}
It works fine, but when I enter some number that contains more than 2 digits, the first number that is printed is negative and really big. I don't also get the last integer too. I enter N as 4, then the numbers I entered were 25, 762, 588, and 34. The result I get is:
-1217260830 25 34 588
What seems to be the problem?
You are running the loop as for (j = 0; j < n; ++j) which means j will have values from 0 to n-1 which are valid array indices (or array elements with relevant values).
But, inside that loop you are accessing an element beyond the last. For instance, in
if (nmbr[j] > nmbr[j + 1])
you are accessing nmbr[j + 1]. If the current value of j in n-1, then you are accessing nmbr[n-1 + 1] i.e. nmbr[n] which will be a value outside the array and may contain a garbage value (which might as well be negative!).
If you are trying something like Bubblesort, you might want to run the inner loop like for (j = 0; j < n - 1; ++j).
There are multiple problems in your code:
You do not check the return values of scanf(). If any of these input operations fail, the destination values remain uninitialized, invoking undefined behavior and potentially producing garbage output.
You do not verify that the number of values provided by the user is at most 100. The reading loop will cause a buffer overflow if n is too large.
Your sorting logic is flawed: in the nested loop, you refer to nmbr[j + 1] which is beyond the values read from the user. This invokes undefined behavior: potentially causing a garbage value to appear in the output.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
if (scanf("%d", &n) != 1 || n > 100) {
printf("input error\n");
return 1;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
if (scanf("%d", &nmbr[i]) != 1) {{
printf("input error\n");
return 1;
}
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n - 1; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting :\n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
printf("\n");
return 0;
}
Your Sorting Logic is wrong. It should be:
for (i = 0; i < n; ++i){
for (j = 0; j < (n-1); ++j){
if (nmbr[j] > nmbr[j + 1]){
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
You are trying to access out of bounds of array, when you iterate in your second loop using j. This is causing the garbage value.
As per your example involving 4 elements, when you try to access j+1, it will try to access nmbr[3+1] in the last iteration of second loop which leads to out of bounds access.
Problem is with the sorting logic as suggested by fellow coders. But It is always good coding habit to initialize the variables. Also use the qualifier if are dealing with positive numbers only.
unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};
If you would have initialized them, out put of your program would be following, which might help you tracing the problem by yourself.
0 25 34 588