Using sieve of sundaram for a given range (b,a) - c

I used the following code to generate a simple sieve-
#include<stdio.h>
int main()
{
int a,b,i,j;
scanf("%d%d",&a,&b);
int m = (a)/2;
int d[m+1];
for (i=0;i<m;i++)
d[i]=1;
for (i=1;i<=m;i++)
for (j=i;j<=((m-i)/(2*i+1));j++)
d[i+j+2*i*j]=0;
if (b<=2) printf("2\n");
for (i=0;i<m;i++)
if(d[i]!=0&&i!=0) printf("%d\n",2*(i)+1);
}
but I want to eliminate the extra time used for finding primes upto b, for this I made m = (a-b)/2 and tried starting the main for loop from b/2 and sqrt b/2 instead of zero but it doesn't seem to work, how can I reduce the extra calculation ? Thanks in advance.

Related

passing argument 4 of ‘addsum’ makes pointer from integer without a cast [-Wint-conversion]

Thank you to anyone reading this , I have a problem with a part of my code , I'm learning to do functions, and functions that are named enter and get_random work fine.
Now i want to add function addsum, but for some reason when i run the code with it, the debugger stops me when the for loop of checking the column finishes and the for loop that loops row should start .
Could anyone tell me what I am doing wrong? i only know the bare essentials of pointers, maybe that is the solution to my problems? thanks in advance.
This is the message from the debugger
passing argument 4 of ‘addsum’ makes pointer from integer without a cast [-Wint-conversion]
#include<math.h>
#include<stdio.h>
#include<stdlib.h> // libraries added from example
#include<time.h>
//(*) For a square matrix calculate the sum of elements under the main diagonal excluding it.
#define A -10
#define B 10
int main(){
void enter(int *x,int *y);
int get_random(int lbound,int ubound);
int addsum(int ro, int co, int s, int arr[ro][co]);
int r;
int c;
int row,col,sum=0;
enter(&r,&c);
srand48(time(NULL)); //Call srand48 with current time reported by `time` casted to a long integer.
// srand48 is used to reinitialize the most recent 48-bit value in this storage
int array[r][c]; // we decided its gonna be r rows and c columns
for (row=0;row<r;++row) // we cycle numeration of rows of matrix
{
for(col=0;col<c;col++) // we cycle numeration of columns of matrix
{
array[row][col]=get_random(B,A);// filling array with random numbers, taken from example
printf("%d ",array[row][col]);
addsum(row, col, sum, array[row][col]);
}
printf("\n"); // this is to break line after row 1,2 col 3, so it looks nicer
}
printf("\n");
printf("sum of array: %d\n", sum);
return 0;
}
void enter(int *x,int *y){ // we have to use pointers if we want more then one return from a function
printf("How man rows in array? ");
scanf("%d", x); // we use x instead of &x because we need the adress of the number not the value
printf("How man columns in array? ");
scanf("%d", y); // we use y instead of &y because we need the adress of the number not the value
}
int get_random(int lbound,int ubound)
{
return rand()%(ubound-lbound+1)+lbound; // function for generating random numbers
}
int addsum(int ro, int co, int s, int arr[ro][co])
{
if (ro>co){ //since we want the sum numbers below the diagonal row>col must be true
s=s+arr[ro][co];// if row>col than we add the number to our sum
return s;
}
}
I have tried to rewrite the function in several different ways, but i dont think its my syntax thats the problem.

Counting paths through a grid: can this algorithm be improved?

I'm a novice without any knowledge of algorithm optimization.
I'm trying to write a code that counts the number of paths on a 20x20 grid, or lattice, from its top-left corner to its bottom-right one, only being able to move down and to the right. For example, the number of paths on a 2x2 grid would be 6:
My (very not optimal) idea is: any sequence of 2*20 moves such that I move down as many times as I move to the right, will get me to the final point.
So I would generate any possible sequence of down and right moves, and then count those that respect that criteria.
I wanted to represent this sequence with a 40-bits binary number, where 0s and 1s represent the two possible moves.
I code in C and didn't find a way to deal with binary numbers, so I use an array of 40 ints.
So by starting from int n = {0,0,...,0} I check that number of zeros = number of ones, if so I increase a counter. I then "sum 1" to this array as I would do to a binary number, and I repeat until I get to {1,1,...,1}.
The code takes 7 seconds for 13x13 grids, up to 8 minutes for a 16x16 grid, and I'd need weeks to run it for a 20x20 grid. Is there any way that this code can be speeded up? Or is this an overall silly strategy to solve the problem? The code is the following:
#include <stdio.h>
#include <stdlib.h>
int ispath(int* n, int siz){
//returns 1 if n has number of 1s = number of 0s, returns 0 otherwise
int n0,n1;
n0=0; n1=0;
for(int i=0;i<siz;i++){
if(n[i]==0) n0++;
else n1++;
}
if(n1==n0) return 1;
else return 0;
}
int risen(int* n,int siz){
//"sums" 1 to the binary number represented by n
//returns just to break from function
for(int i =siz-1;i>=0;i--){
if(n[i]==0){
n[i]=1; return 1;
}else n[i]=0;
}
}
int sumn(int* n, int siz){
int sum=0;
//sum elements of n, to check when n=11...1 and stop the while loop in main
for(int i =0;i<siz;i++) sum+=n[i];
return sum;
}
int main(){
int n[] = {0,0,0,0};//NXN lattice requires n with 2N starting zeros. This n represents 2x2 lattice
int sizen = sizeof(n)/sizeof(n[0]);
long long cnt = 0;
while(sumn(n,sizen)<sizen){
if(ispath(n,sizen)){
cnt++;
}
risen(n,sizen);
}
printf("Number of paths: %lli",cnt);
}

Divide array into two equal parts with minimal difference and Find sum of each part

Hi I am trying to solve a problem with brute force, but I cannot wrap my head around how to solve it. I tried for hours.
Consider an array inputArray with atleast two non-zero positive integers ranging between 1 to 300 inclusive. Divide the arrayr into two groups based on these rules.
Each integer should belong to one of the two groups
The total sum of integers in each of the groups must be as nearly equal as possible.
The total number of integers between the 2 groups should not differ by more than 1
I need to return the sums of each group
I solved this problem using c++
#include <bits/stdc++.h>
using namespace std;
vector<int> v;
int ans(int i,int n,float s)
{
if(i<n-1) return INT_MAX;
if(n==0) return abs(s);
return min(ans(i-1,n-1,s-v[i-1]),ans(i-1,n,s));
}
int main()
{
string s;
cin>>s;
int c=0;
for(int i=0;i<s.length();i++)
{
if(s[i]==',') {v.push_back(stoi(s.substr(c,i-c)));
c=i+1;}
}
v.push_back(stoi(s.substr(c,s.length()-c)));
//for(int i=0;i<v.size();i++) cout<<v[i];
int ss=0;
for(int i=0;i<v.size();i++) ss+=v[i];
int n1=v.size();
int n2=n1/2;
float su=ss/2;
int k=ans(n1-1,n2,su);
cout<<ss-su-k<<" "<<su+k;
}
this is solution for this
I hope this helped you
output image

Binomial coefficient recursive solution in C

Why is my solution to binomial coefficient crashing? I've really tried to learn recursion, but I still think I am not clear about about it. I wonder if anyone can help me learn about recursion, and how to think recursively?
Even when I write a good base case, my program crashes. Any link to learn recursion with clear demonstration would be very helpful for me.
Here is my code for binomial coefficient, and I'm unable to find the bug/error, looking for your help.
code:
#include<stdio.h>
long long m,n,o,p,result;
long long binomial(long long n,long long m)
{
if(n==m)
return 1;
else {
if(m==0)
return 1;
else {
o=binomial(n-1,m);
p=binomial(n-1,m-1);
return o+p;
}
}
}
int main()
{
printf("Please Enter The Value Of n:\n");
scanf("%lld",&n);
printf("Now Enter The value of m:\n");
scanf("%lld",&m);
result = binomial(n,m);
printf("Resultant Binomial coefficient: %lld\n",result);
return 0;
}
The binomial coefficient is only defined for pairs n and k when n >= k. It is conventional to use n and k in binomial coefficient expressions, but these correspond to n and m in your code.
You need to include some error-checking of input to avoid problems. Your code crashes when n is less than m because each time the statement o=binomial(n-1,m); is executed, the value of n in the called function is reduced, but n is already smaller than m, which is nonzero (if m were zero the function would have simply returned 1), so n == m can never occur.
Incidentally, you can improve your code in a few ways. Using global variables is generally a bad idea, and it would be better to move the declaration:
long long m, n, result;
into main(), where these variables are needed. Also, the function signature for main() should be int main(void). And you can tighten up the logic in the binomial() function considerably, removing the need for o and p:
long long binomial(long long n,long long m)
{
if (m != 0 && n != m) {
return binomial(n-1, m) + binomial(n-1, m-1);
} else {
return 1;
}
}

Perfect square in fibonacci sequence?

Create a program to find out the first perfect square greater than 1 that occurs in the Fibonacci sequence and display it to the console.
I have no output when I enter an input.
#include <stdio.h>
#include <math.h>
int PerfectSquare(int n);
int Fibonacci(int n);
main()
{
int i;
int number=0;
int fibNumber=0;
int psNumber=0;
printf("Enter fibonacci number:");
scanf("%i",&number);
fibNumber = Fibonacci(number);
psNumber = PerfectSquare(fibNumber);
if(psNumber != 0){
printf("%i\n",psNumber);
}
}
int PerfectSquare(int n)
{
float root = sqrt(n);
if (n == ((int) root)*((int) root))
return root;
else
return 0;
}
int Fibonacci(int n){
if (n==0) return 0;
if (n==1) return 1;
return( Fibonacci(n-1)+Fibonacci(n-2) );
}
Luke is right. If your input is n, then the Fibonacci(n) returns the (n+1)th Fibonacci number.
Your program check whether (number +1)th is perfect square or not actually.
If you enter 12, then there is output. Because the 13th Fibonacci number is 144. And it is perfect square. PS: print fibNumber instead of psNumber.
printf("%i\n", fibNumber);
Right now you're only calculating one Fibonacci number and then testing whether it's a perfect square. To do this correctly you'll have to use a loop.
First suggestion is to get rid of the recursion to create fib numbers. You can use 2 variables and continually track the last 2 fib numbers. They get added something like:
fib1=0;fib2=1;
for(i=3;i<MAXTOCHECK;i++)
{
if(fib1<fib2)
fib1+=fib2;
else
fib2+=fib1;
}
What is nice about this method is that first you can change you seeds to anything you want. This is nice to find fib like sequences. For example Lucas numbers are seeded with 2 and 1. Second, you can put your check for square inline and not completely recalculate the sequence each time.
NOTE: As previously mentioned, your index may be off. There is some arbitrariness of indexing fib numbers from how it is initially seeded. This can seen if you reseed with 1 and 1. You get the same sequence shifted by 1 index. So be sure that you use a consistent definition for indexing the sequence.

Resources