find gcd of multiple user inputted values using C - c

#include <stdio.h>
int gcd()
{
int i,j,rem;
printf("Enter two integers: ");
scanf("%d%d",&i,&j);
while (i !=0)
{
rem = j % i;
j=i;
i=rem;
}
printf("Greatest common denominator is %d\n",j);
}
int main()
{
gcd();
return 0;
}
I am learning C using "C programming a modern approach 2nd edition."
One of the exercises I had to create a function that takes in two numbers from a user
and returns the gcd, I would like to be able to pass in multiple numbers but I don't know how to achieve this using C.

I recommend passing the numbers as an array of int and then applying the gcd algorithm on it recursively (preferably).
int gcd(int *array, int n)
{
if(n == 0)
{
//find gcd using while loop of array[n] and array[n + 1]. store in result.
return result;
}
return gcd(int *a, n -1);
}

Related

How to store individual units of an int in an int array; C Language

I am a beginner starting in C and am doing some exercises on codewars. The exercise requires me to take a decimal int, convert it into binary and output the number of 1s in the binary number. Below my incomplete code. I store the binary in int b and I want to output it into an array so that I can run a loop to search for the 1s and output the sum.
Thanks in advance!
#include <stddef.h>
#include <stdio.h>
//size_t countBits(unsigned value);
int countBits(int d);
int main() {
int numD = 1234;
int numB = countBits(numD);
printf("The number %d converted to binary is %d \n", numD, numB);
}
int countBits(int d) {
if (d < 2) {
return d;
} else {
int b = countBits(d / 2) * 10 + d % 2; //convert decimal into binary
int c;
int bArray[c];
}
Your function is almost correct:
you should define the argument type as unsigned to avoid problems with negative numbers
you should just return b in the else branch. Trying to use base 10 as an intermediary representation is useless and would fail for numbers larger than 1023.
Here is a corrected version:
int countBits(unsigned d) {
if (d < 2) {
return d;
} else {
return countBits(d / 2) + d % 2;
}
}
There are many more efficient ways to compute the number of bits in a word.
Check Sean Eron Anderson's Bit Twiddling Hacks for classic and advanced solutions.
You can make an array char as one of the replies said, for example:
#include <stdio.h>
#include <string.h>
int main(){
int count=0;
int n,bit;
char binary[50];
printf("Enter a binary: \n");
scanf("%s",binary);
n=strlen(binary);
for(int i=0;i<n;i++){
bit=binary[i]-'0';
if (bit==1){
count=count+1;
}
}
printf("Number of 1's: %d\n",count);
return 0;
}
This should count the number of 1's of a given binary.
Try something like this!
edit: I know that binary[i]-'0' might be confusing, if you don't understand that..take a look at this:
There are definitely 'smarter'/more compact ways to do this, but here is one way that will allow you to count bits of a bit larger numbers
#include <stdio.h>
int count_bits(int x)
{
char c_bin[33];
int count=0;
int mask=1;
for( int i =0; i < 32; i++){
if (x & mask ){
count=i+1;
c_bin[31-i]='1';
}
else{
c_bin[31-i]='0';
}
mask=mask*2;
}
c_bin[32]='\0';
printf("%d has %d bits\n",x,count);
printf("Binary x:%s\n",c_bin);
return count;
}
int main()
{
int c=count_bits(4);
return 0;
}

Not able to understand why on some particular test cases it shows segmentation faults while on others it is successfully accepted

I'm trying to answer the following assignment:
We are given two arrays a and b containing elements each.
Choose a pair of elements (x,y) such that: x belongs to array a; y belongs to array b; gcd(x,y) is the maximum of all pairs (x,y).
If there is more than one such pair having maximum gcd, then choose the one with maximum sum.
Print the sum of elements of this maximum-sum pair.
n -> size of the input arrays
a and b are two arrays consisting of n numbers each.
This code is showing segmentation fault. I can't figure out the problem.
it is showing segmentation fault for some test cases while for other it runs perfectly.Can you figure out the problem with the code?
#include <stdio.h>
long int max_gcd=0,max_sum=0;
long int n;
long int a[1000000],b[1000000];
long int hcf(long int n1, long int n2)
{
if (n2 != 0)
return hcf(n2, n1%n2);
else
return n1;
}
long int gcd(long int i,long int j,long int n)
{
long int ans=hcf(a[i],b[j]);
if(ans>max_gcd)
{
max_gcd=ans;
max_sum=a[i]+b[j];
}
if(ans==max_gcd && max_sum<a[i]+b[j])
{
max_sum=a[i]+b[j];
}
if(j+1<n)
return gcd(i,j+1,n);
else if(i+1<n)
return gcd(i+1,0,n);
return max_sum;
}
int main()
{
long int i;
scanf("%ld",&n);
for(i=0;i<n;i++)
{
scanf("%ld",&a[i]);
}
for(i=0;i<n;i++)
{
scanf("%ld",&b[i]);
}
long int ans=gcd(0,0,n);
printf("%ld",ans);
return 0;
}
You should not ask running contest's question. Better try it by own or wait for editorial. Don't abide contest rule.
https://www.hackerrank.com/contests/w34/challenges/maximum-gcd-and-sum

how to calculate the sum of successive integers starting at 1 and ending at n by using a recursion function

My function gets a number and returns the sum of the numbers before the input including the input; however, i was wondering if it is possible to calculate the sum of successive integers starting at 1 and ending at n(as input)
#include<stdio.h>
int sum(int x){
if(x>0)return x+sum(x-1);
else return 0;
}
main(){
int x;
scanf("%d",&x);;
printf("%d\n\n",sum(x));
}
I found the answer for my question, but the stackoverflow.com don't let me answer it. So, I'll answer it here:
It is really simple, all it needs is another argument for incrementation and the other one to keep track of the value inputed.
#include<stdio.h>
int sum(int x,int t){
if(t<=x) return t+sum(x,t+1);
else return 0;
}
main(){
int x;
printf("enter int: ");
scanf("%d",&x);
printf("%d\n",sum(x,0));
}
The sum of all the intergers smaller than n, and larger than 0 can be found with
int sum = (n*(n+1))/2
which has much less overhead than a recursive function. But if you really want to then you function looks correct, I'd add some curly braces though:
int sum(int x){
if(x>0) {
return x+sum(x-1);
}
else {
return 0;
}
}
The problem with the above function, is that is uses the stack for for memorisation, so you probably won't be able to calculate large ns. You can make your function tail recursive:
int sum(int x, int sum){
if(x>0) {
return sum(x-1, sum + x);
}
else {
return sum;
}
}
This wont use the stack to memorise your intermediate sums. However a simple loop is probably better, and if you want it to look really cryptic and effective, you can do:
int sum = (n*(++n))>>1

Merging entries of two arrays as the even and odd entries of another array.

I've got a function thats able to produces 2 arrays, one when the index 'i' is even and one when the index 'i' is odd, so I end up with two arrays. The even 'i' array is called W_e and made of N elements, the odd 'i' array is called W_o and also made of N elements.
I now need to be merge these two arrays into another array Wn (which has 2*N elements) such that it looks like Wn=[W_e[0],W_o[0],W_e[1],W_o[1],...,W_e[N-1],W_o[N-1]] but I'm not sure how to do it. I tried to use nested loops but it didn't work. The arrays W_e and W_o are produced correctly according to my calculations, I'm just unable to combine the entries into one array.
This is what I have so far. I have not done anything in the main function except call the function which is giving me trouble "double *MakeWpowers(int N);". Please keep in mind this works for N>2, I have not yet dealt with N=1 or N=2.
Any help will be greatly appreciated. Thank you!!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
#define pi 4*atan(1)
double *MakeWpowers(int N);
void print_vector(double *x,int N);
double *make_vector(double *x,int N);
int main(void)
{ int N;
double *Wn;
printf("\n Please enter the size of the NxN matrix:\n");
scanf("%d",&N);
Wn=MakeWpowers(N);
//print_vector(Wn,N);
free(Wn);
return(0);
}
double *MakeWpowers(int N)
{
double *Wn,*W_e,*W_o;
int i,j;
Wn=make_vector(Wn, 2*N);
W_e=make_vector(W_e, N);
W_o=make_vector(W_o, N);
for(i=0;i<=N-1;i++)
{
if(i%2==0)
{
W_e[i]=cos((2*i*pi)/N);
}
else
{
W_o[i]=sin((2*i*pi)/N);
}
}
printf("\nThis is the even vector W_e:\n");
print_vector(W_e, N);
printf("\nThis is the odd vector W_o:\n");
print_vector(W_o, N);
for(j=0;j<2*N;j++)
{
if(j%2==0)
{Wn[j]=W_e[i];}
//++i;}
else
{Wn[j]=W_o[i];}
//++i;}
printf("\nthis is Wn:\n\n");
print_vector(Wn, 2*N);
//Wn[j]=W_o[i];
//j++;
}
return(Wn);
}
void print_vector(double *x,int N)
{
int i;
for (i=0; i<N; i++)
{
printf ("%9.4f \n", x[i]);
}
printf("\n");
}
double *make_vector(double *x,int N)
{ int i;
double xi;
x=(double *)malloc((N)*sizeof(double));
for(i=0;i<N;i++)
{
x[i]=(double)xi;
}
return(x);
}
Here's the general logic to it:
LET a, b, merge BE ARRAYS
FOR k IN 0..length(a)
merge[2*k] = a[i]
merge[2*k+1] = b[i]
RETURN merge
a makes the even entries (2k), b the odd ones (2k+1).
This is probably wrong
double *make_vector(double *x,int N)
{ int i;
double xi;
You have to initialize variable xi same thing goes for *Wn,*W_e,*W_o

Check if a given number is the sum of two numbers from 2 arrays

i tried the brute force way:
#include <stdio.h>
int sum(int a [],int b[], int m);
int main (void)
{
int a [] = {1,2,3,4,5};
int b [] = {4,3,5,2,6};
int i;
printf("Enter to find a given number:\n");
scanf("%d",&i);
printf("%s\n",sum(a,b,i) ? "True":"False");
return 0;
}
int sum(int a[], int b[],int m)
{
int i=0,j=0;
for (i=0;i<=sizeof(a)/sizeof(int)+1;i++)
for(j=0;j<=sizeof(b)/sizeof(int)+1;j++)
if (a[i]+b[j]==m)
return 1;
return 0;
}
as you can see the run time is O(n^2), are there any clever way to minimise this?
The faster possible solution (O(n)) is to use hash table. Just put all the elements from the first array in it and then while iterating over the second one check if the difference between the target number and the current one is in the hash table.
Here is implementation in C++:
int main(){
int a [5] = {1,2,3,4,5};
int b [5] = {4,3,5,2,6};
int m;
printf("Enter to find a given number:\n");
scanf("%d",&m);
set<int> s;
for (int i = 0; i < 5; i++)
s.insert(a[i]);
for (int i = 0; i < 5; i++)
if (s.count(m-b[i]) > 0) {
printf("True\n");
return 0;
}
printf("False\n");
}
This is just another formulation of "Find all pairs of elements (a1,b1) such that a1 belongs to Array A and b1 belongs to Array B whose sum a1+b1 = k".
In short, use a hash table.
No need for an hash table!!
You could sort the arrays (one increasing the other one decreasing) and then compare the first elements of the arrays. At each step then move on the first array increasing and on the second decreasing (if the sum is too large you should move on the decreasing array, if the sum too small you have to move on the increasing array)
This algorithm is 2N log(N) + 2 N
You can precompute the "sums" array, put it in size order, and then bsearch(3) the array:
int sums = { /* list of sorted sums */ };
int compare(void *a, void *b) { return ((int *)a - (int *)b); }
if (bsearch((void *)int_to_test, (void *)sums, number_of_items_in_sums, sizeof(int), compare) == NULL)
errx(1, "not in list!");
printf("found it\n!");
The bsearch syntax is from memory, so double-check that in your man pages.

Resources