Find the Minimum amount needed for a man - c

A person has to cross a road and with each step he either gains some energy or loses some (this info is provided as an array) . Find out the min amount of energy he should start with so that at any level his energy is not less than 1.
But the below program always prints "Error" not the number.
#include<stdio.h>
#include<limits.h>
int main(){
int a[]={10,20,20};
int n = sizeof(a)/sizeof(a[0]);
int ans = calldistance(a,n);
if(ans==-1)
printf("error");
else
printf("%d",ans);
return 0;
}
int calldistance(int a[],int n){
int i,min=INT_MAX;
for(i=0;i<n;i++){
min+=a[i];
if(min<1) return -1;
else continue;
}
return min;
}

You always return -1 because you call it quits if the array is one where the value isn't trivial.
You need to keep track of partial sums of the array. In particular you need to know when the partial sum is at its lowest negative value (or zero). The absolute value of this + 1 is your answer.
If the sum is never bellow 1, then your answer is just 1.
int calldistance(const int a[], const int n) {
int min_partial_sum = 0;
int partial_sum = 0;
for(int i = 0; i < n; ++i) {
partial_sum += a[i];
if(min_partial_sum > partial_sum)
min_partial_sum = partial_sum;
}
if(min_partial_sum < 0)
return -min_partial_sum + 1;
return 1;
}

int calldistance(int a[],int n){
int i,min=INT_MAX;
for(i=0;i<n;i++){
min+=a[i];
if(min<1) return -1;
else continue;
}
return min;
}
In the above function you are initializing min=INT_MAX and if you add even 1, it will return a negative number. That's the why you are always getting error as answer.

Related

Why this program prints 0?

I am supposed to write a program that prints the minimum value from vector.This is what i tried. It only prints 0. I tried to change the sign both ways but it doesnt work.
#include <stdio.h>
int read(int v[], int size)
{
int i = 0;
do
{
scanf("%i", &v[i]);
i++;
} while (v[i-1] != 0 && i < size);
int n = i;
return n;
}
int minim(int v[], int n)
{
int m;
m = v[0];
int i;
for (i = 1; i <= n-1; i++)
{
if (v[i] < m)
{
m = v[i];
}
}
return m;
}
int main()
{
int arr[100];
int n = read(arr, 100);
int min = minim(arr, n);
printf("\nMinimum vrom vector is %i\n", min);
return 0;
}
Since your scanf loop (I'd recommend staying away from function names like read, which are part of the C standard, even if you didn't include unistd.h) ends when 0 is entered, you need to include a check at the end to decrement the size of the array if 0 is the last entry. Basically, replace everything after your do-while loop with this:
if (v[i - 1]) {
return i;
}
return --i;
This will return i if all 100 elements are non-zero, otherwise it will decrement to remove the 0 from your array before returning. No need to declare int n=i just to instantly return n.
Edit: I saw your comment that it worked properly for finding the maximum. This is because you almost certainly entered a number into the array that's greater than 0, so adding 0 at the end would not affect the maximum number. Try finding the max again, but only enter negative numbers. The result will be 0.
read() uses a 0 entry to terminate reading more input. Yet that 0 is included in the array and counts toward the array length as part of the return value.
Instead, only increment the array count when input was numeric and non-zero.
int read(int v[], int size) {
int i = 0;
while (i < size) {
// Also test if valid numeric input was read.
if (scanf("%i", &v[i]) != 1) {
break;
}
// Stop if a 0 was read
if (v[i] == 0) {
break;
}
// Now increment
i++;
}
return i;
}
Could use shorter code, yet it is less readable. Best to code for clarity.
int read(int v[], int size) {
int i = 0;
while (i < size && scanf("%i", &v[i]) == 1 && v[i]) {
i++;
}
return i;
}
The test condition
while (v[i-1] != 0
checks whether the last element read was 0, after it was successfully processed and converted by scanf (but you never checked the return value). The 0 is then included in the array, and will always be the minimum unless you enter a non-negative number.
Here's the working code:
#include <stdio.h>
#include <stdlib.h>
static size_t read (int v[], size_t size)
{
size_t i = 0;
do
{
/* Check if scanf was successful */
if (scanf("%i",&v[i]) != 1) {
fprintf(stderr, "Error: Invalid input.\n");
return EXIT_FAILURE;
}
} while (v[i] != 0 && ++i < size);
return i;
}
static int minim (int v[],size_t n)
{
int min;
min = v[0];
for(size_t i = 1; i < n; i++) {
if (v[i] < min) {
min = v[i];
}
}
return min;
}
int main(void)
{
int arr[100];
size_t n = read(arr,100);
int min = minim(arr,n);
printf("\nMinimum vrom vector is %i\n", min);
return EXIT_SUCCESS;
}
I made some minor changes to it. Though I'm not satisfied with the design.
Sample I/O:
20
8
18
60
39
56
0
Minimum vrom vector is 8

factorial calculation in C

I wanted to write a simple program to calculate the factorial of a given number using C. Yet my code seems to have some logical error that I can't detect. Would be glad for help.
int fact(int n);
int main(void)
{
int num = get_int("Type number: ");
printf("%i\n", fact(num));
}
//define function
int fact(int n)
{
for (int i = 1; i < n; i++)
{
n *= i;
}
return n;
}
You can't use n to calculate.
You have to save total with another variable
int fact(int n)
{
int product = 1;
for (int i = 1; i <= n; i++)
{
product = product * i;
}
return product;
}
In mathematics, the factorial of a positive integer N, denoted by N!, is the product of all positive integers less than or equal to N:
N!=N*(N-1)*(N-2)*(N-3)*.......*1
+-------------------------+
notice that this is: (N-1)! <==> So, N! = N*(N-1)!
we can use these mathematical facts to implement the factorial function in 2 different forms, recursive and iterative approaches:
recursive approach
size_t rec_factorial(size_t n)
{
/*Base case or stopping condition*/
if(n==0)
{
/* 0! = 1 */
return 1;
}
/*n! = n * (n-1)!*/
return n * rec_factorial(n-1);
}
iterative approach
size_t factorial(size_t n)
{
size_t j = 1;
size_t result = 1;
while(j <= n){
result *= j; /* n!=n*(n-1)*(n-2)*(n-3)*....1 */
++j;
}
return result;
}

C recursive program to print all prime factors of a given number from the biggest factor to the smallest

i'm trying to write a program that print the prime factors of a given number ,but i need to print them from the biggest factor to the smallest, for example:
for the input 180 the output will be: 5*3*3*2*2,
any suggestions? here is what i got for now :
#include<stdio.h>
void print_fact(int n)
{
if (n==1)
return;
int num=2;
while (n%num != 0)
num++;
printf("*%d",num);
print_fact (n/num);
}
int main ()
{
int n;
printf("please insert a number \n");
scanf("%d",&n);
print_fact(n);
}
for this code the output is :
*2*2*3*3*5
You can simply print the output after the recursive call returns. You need to slightly modify how you display the *, which I leave to you.
#include<stdio.h>
void print_fact(int n)
{
if (n==1)
return;
int num=2;
while (n%num != 0)
num++;
// printf("*%d",num); // remove from here
print_fact (n/num);
printf("%d ",num); // put here
}
int main ()
{
int n;
printf("please insert a number \n");
scanf("%d",&n);
print_fact(n);
}
The output this gives on input 180 is:
5 3 3 2 2
Aside, there are much more efficient ways of actually finding the numbers though.
It is much faster to find them in the ascending order, mathematically speaking. Much, much faster.
The solution, if you don't want to bother yourself with dynamic arrays, is recursion. Find the lowest prime factor, recurse on the divided out number (num /= fac), and then print the earlier found factor, which will thus appear last.
to change the order in which they are printed, you could put the printf statement after the print_fact statement. To get rid of thew leading *, you would probably want to store the results and display them after computation
well, i'm trying to optimize my algorithm
this is my code for now:
functions code
#include "prime_func.h"
int divisors(int x) /* Function To set the maximum size of the future array,
Since there is no way to find the number of primary factors
without decomposing it into factors,
we will take the number of total number divisors
(which can not be greater than the number of primary factors) */
{
int limit = x;
int numberOfDivisors = 0;
if (x == 1) return 1;
for (int i = 1; i < limit; ++i) {
if (x % i == 0) {
limit = x / i;
if (limit != i) {
numberOfDivisors++;
}
numberOfDivisors++;
}
}
return numberOfDivisors;
}
void find_fact(int n, int *arr, int size, int i) //func to find the factors and apply them in allocated array
{
int num = 2;
if (n < 2)
{
printf("error\n");
return;
}
while (n%num != 0)
num++;
arr[i++] = num;
find_fact(n / num, arr, size, i);
}
void print_fact(int *arr, int size) // func to print the array in reverse
{
int i = 0;
int first;
first = FirstNumToPrint(arr, size);
for (i = first; i>0; i--)
printf("%d*", arr[i]);
printf("%d", arr[0]);
}
int FirstNumToPrint(int *arr, int size) // func to find the first number to print (largest prime factor)
{
int i;
for (i = 0; i < size; i++)
if (arr[i] == 0)
return i - 1;
}
int first_prime(int num) // for now i'm not using this func
{
for (int i = 2; i<sqrt(num); i++)
{
if (num%i == 0)
{
if (isprime(i));
return(i);
}
}
}
bool isprime(int prime) // for now i'm not using this func
{
for (int i = 2; i<sqrt(prime); i++)
{
if (prime%i == 0)
return(false);
}
return(true);
}
main code
#include "prime_func.h"
int main()
{
int n,i=0; // first var for input, seconde for index
int *arr; // array for saving the factors
int size;//size of the array
printf("please insert a number \n");// asking the user for input
scanf("%d", &n);
size = divisors(n); //set the max size
arr = (int *)calloc(size,sizeof(int)); //allocate the array
if (arr == NULL) // if the allocation failed
{
printf("error\n");
return 0;
}
find_fact(n, arr,size,i);// call the func
print_fact(arr,size); //print the result
free(arr); // free memo
}
#WillNess #GoodDeeds #mcslane

Custom Recursive function |returning no values at all| in C

I thought of making this An=8(An-1)*(An-1)/An-2 while a1=1,a0=1
With the following code for n=2 a2=0.0000 which is altogether wrong
On the other hand (Sum of An) S(n)=1+1+0.0000(false number) theoretically correct
#include <stdio.h>
float rec(int n);
float sum(int n);
main()
{
int n;
printf("\nInput N of term an: ");
scanf("%d",&n);
printf("\n\na%d=%f",n,rec(n));
printf("\n\nS(%d)=%f",n,sum(n));
}
float rec(int n)
{
int i;
float a[1000]={1,1};//a0=1,a1=1
if(n<0)
printf("\nNegative values of N are invalid");
else if(n==0)
return a[0];
else if(n==1)
return a[1];
else if(n>1)
for(i=2;i<=n;i++)
a[i]=((8 * a[i-1]*a[i-1]) - 1)/a[i-2];
return a[i];
}
float sum(int n)
{
int i;
float sum=0;
for(i=0;i<=n;i++)
sum+=rec(i);
return sum;
}
float a[1000]={1,1};
initializes a[0] = 1 and a[1] = 1 and rest of the elements to 0.
Now, you are returning a[i] from your function. For n=2 it will return a[3], which is 0 of course, but not the a[2] as you are expecting.
Now just change the return value to a[i-1] and it will work.
float rec(int n)
{
int i;
...
...
return a[i-1];
}
for(i=2;i<=n;i++)
a[i]=((8 * a[i-1]*a[i-1]) - 1)/a[i-2];
return a[i];
problem here, you will always get zero!!! why?
say i input 3,, now say i = 3,alls well a[3] gets calcualted, now you program goes back to the for loop, now i =4, it now does not fit the check i<=n, and so now i is 4,
you are returning a[i] which is actually a[myanswer+1]...
fix it by returning a[i-1]
At this point in rec:
return a[i];
i is 3, not 2, because it was incremented before the last test of the loop. As such you're returning the element of the array after the last one set. Be careful if you fix this by returning a[i-1] because if i is never initialized or is 0, this will cause a problem. You should clean up the rec method a bit to handle these corner cases, but the immediate problem is that i is 3, not 2.
Replace
return a[i];
with
return a[n];
(As an aside, you do not need the extra branches for 0 and 1.)
A beautiful example of Schlemiel the Painter's algorithm :)
About half the computations are done unnecessarily multiple times
The array is unnecessary and defeats the whole point of using a recursive approach
Beside, it is defined to hold 1000 values, but the function grows so fast that it will exceed a float capacity after 10 terms or so.
A more streamlined version here :
#include <stdio.h>
float A (int n, float * sum)
{
if (n <= 0) { *sum = 0; return 0; }
if (n == 1) { *sum = 1; return 1; }
if (n == 2) { *sum = 2; return 1; }
float anm2 = A(n-2, sum); // store A(n-2). sum will be overwritten by A(n-1)
float anm1 = A(n-1, sum); // store A(n-1) once to avoid calling A twice, and get preceding sum
float an = ((8 * anm1*anm1) - 1)/anm2;
*sum += an;
printf ("index %d : term %g sum %g\n", n, an, *sum);
return an;
}
int main (void)
{
int n;
float sum;
printf("\nInput N of term an: ");
scanf("%d",&n); printf("\n");
printf("\na%d=%f",n,A(n, &sum));
printf("\n\nS(%d)=%f",n,sum);
}
Beside, recursion is unnecessary and leads to inefficient and confusing code.
See a more straightforward solution here:
#include <stdio.h>
typedef struct {
float term;
float sum;
} A; // current term and sum of series A
void compute_A (int n, A * res)
{
int i;
float anm1, // a[n-1]
anm2; // a[n-2]
// special case for n<=1
if (n == 1)
{
res->sum = res->term = 1;
return;
}
if (n <= 0)
{
res->sum = res->term = 0;
return;
}
// initial terms
anm2 = anm1 = 1;
// initial sum
float sum = anm1+anm2;
// compute the remaining n-2 terms and cumulate the sum
for (i = 2 ; i <= n ; i++)
{
// curent term
float an = ((8 * anm1*anm1) - 1)/anm2;
// cumulate sum
sum += an;
// shift computation window
anm2 = anm1;
anm1 = an;
printf ("index %d : term %g sum %g\n", i, an, sum);
}
// report result
res->sum = sum;
res->term = anm1;
}
int main (void)
{
int n;
A res;
printf("\nInput N of term an: ");
scanf("%d",&n); printf("\n");
compute_A (n, &res);
printf("\na%d=%f",n,res.term);
printf("\n\nS(%d)=%f",n,res.sum);
}
float rec(int n){
static max_i = 1;
static float a[1000]={1,1};//a0=1,a1=1
int i;
if(n<0){
printf("\nNegative values of N are invalid");
return NAN;//<math.h>
}
if(n >= 1000){
printf("\nMore than 1000 are invalid");
return NAN;
}
if(n<2)
return a[n];
if(n>max_i){
for(i=max_i+1;i<=n;++i)
a[i]=((8 * a[i-1]*a[i-1]) - 1)/a[i-2];
max_i = n;
return a[n];
}
return a[n];
}

Recursive sum of an array in C [duplicate]

This question already has answers here:
calculate the sum of all element in a double array
(12 answers)
Closed 9 years ago.
Hello I'm learning recursion in C and I am trying to find the sum of the elements.
This is my main:
int main()
{
int arr[] = {1,2,3,4,5};
int sum;
sum = arr_sum(arr,4);
printf("\nsum is:%d",sum);
return 0;
}
And my recursive function:
//n is the last index of the array
int arr_sum( int arr[], int n )
{ // must be recursive
int sum = 0;
//base case:
if (n < 0) {
return sum;
} else{
sum = sum + arr[n];
}
//make problem smaller
arr_sum(arr,n-1);
}
The output is:
sum is :0
Try this for your recursive function:
int arr_sum( int arr[], int n ) {
if (n < 0) {
//base case:
return 0;
} else{
return arr[n] + arr_sum(arr, n-1);
}
}
you need to add your n-th case to your n-1 case until you get to the base case.
You could add a third argument, which is the running total calculated so far (start it as 0).
When you recursively call the function, pass the running total.
int arr_sum( int arr[], int n, int sum )
{ // must be recursive
if (n < 0) {
return sum;
}
sum += arr[n];
return arr_sum(arr, --n, sum);
}
Alternatively, you change it to not require passing the sum variable like so.
int arr_sum( int arr[], int n )
{ // must be recursive
if (n < 0) {
return sum;
}
return arr[n] + arr_sum(arr, n - 1);
}
In this way, it is similar to finding a number in the Fibonacci sequence.
Try this modified version of your program and work out on pen/paper the way it flows through. Hope it helps.
#include <stdio.h>
//n is the last index of the array
int
arr_sum(int arr[], int n )
{
//base case:
if (n == 0) {
return arr[0];
}
return (arr[n] + arr_sum(arr,n-1));
}
int
main(void)
{
int arr[] = {1,2,3,4,5};
int sum;
sum = arr_sum(arr,4);
printf("\nsum is:%d\n",sum);
return 0;
}
You are not returning any thing from else part.You also have return from that.
like.
return arr_sum(arr,n-1)+arr[n];
so this call the function again and again until n will be zero.
you got my point?
The problem with your code is that everytime when your recursive function calls, it initializes the sum as 0.
Declare sum outside the recursive method that will solve the problem.

Resources