Why doesn't equating two sums in a conditional evaluate to true? - c

I am trying to return the index where the sum of the left hand side is equal to the right hand side. But I get a default of -1. Why doesn't the conditional evaluate to true?
Here is the code:
#include <stdio.h>
int find_even_index(const int *values, int length)
{
int count = 0;
int sumL = 0;
int sumR = 0;
while(count < length)
{
sumR += values[count];
count++;
}
count = 0;
while(count < length)
{
sumL += values[count];
sumR -= values[count];
printf("sumL = %d\n", sumL);
printf("sumR = %d\n", sumR);
if(sumL == sumR)//why doesn't this condition work?
{
return count;
}
count++;
}
return -1;
}
int main (void)
{
int arr[] = { 1,2,3,4,3,2,1 };
printf("%d\n", (find_even_index(arr, 7)));
return 0;
}

Because you are comparing the numbers after adding and subtracting both of them. So in the moment they are about to be the same:
sumL = 6; sumR = 10
You then sum 4 to sumL and subtract 4 to sumR:
sumL = 10; sumR = 6
And then you compare and get different values. You have to check in between the operations.

Related

Display every combination of a given array in C

I'm trying to write a program with my teacher that displays every possible combination of n numbers (for example, if n = 2, it displays from 01,02,03 etc.. to 89.) I'm using multiple tabs, incrementing the last one to go up to 9, and then incrementing the one just before so I can go from 09 to 12, and so on, but I don't really know how to proceed.
I'm quite new to C programming, so feel free to tell me if anything can be made better.
#include <unistd.h>
ft_putchar(char c)
{
write(1, &c, 1);
}
ft_affichage(int tab[], int nb)
{
int index = 0;
while(index < nb)
{
ft_putchar(tab[index] + 48);
ft_putchar(',');
ft_putchar(' ');
index++;
}
}
int ft_end(int tab[], int nb)
{
int index;
for (index = 0; index < nb ; index++)
{
if (tab[index] != 9 - nb + 1 + index)
{
return 0;
}
}
return 1;
}
void ft_print_comb_n(int nb)
{
int comb[nb];
int index = 0;
// init comb
while(index < nb)
{
comb[index] = index;
index++;
}
ft_affichage(comb, nb);
while(ft_end(comb, nb) == 0)
{
// incrementer comb;
int i = nb - 1;
int max = 9;
while(comb[0] != 9 - nb + 1 + index && comb[nb- 1] != 9 )
{
comb[nb - 1]++;
}
{
}
}
//afficher comb;
ft_affichage(comb, nb);
}
int main(void)
{
ft_print_comb_n(2);
return 0;
}
so feel free to tell me if anything can be made better
Depending on the requirements your teacher gave, the solution below is possible and very simple. It makes use of printf feature that allow to print a variable number of digit of an integer number with leading zero.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void ft_print_comb_n(int nb)
{
// Compute the limit based on the number of digits
int maxN = (int)(pow(10, nb) + 0.5);
for (int i = 0; i < maxN; i++)
printf("%0*d\n", nb, i);
}
int main(int argc, char *argv[])
{
ft_print_comb_n(3);
return 0;
}
This is based on some old code of mine, but I've forgotten how it works.
int ft_debut(int tab[], int n, int k)
{
if (k <= 0 || k > n)
{
return 0;
}
while (k--)
{
tab[k] = k;
}
return 1;
}
int ft_suivant(int tab[], int n, int k)
{
int i = k;
if (k < 0 || k > n)
{
return 0;
}
while (i--)
{
int x = tab[i];
if (x < --n)
{
do
{
tab[i++] = ++x;
}
while (i < k);
return 1;
}
}
return 0;
}
void ft_print_comb_n(int nb)
{
int comb[nb];
int va;
for (va = ft_debut(comb, 10, nb); va; va = ft_suivant(comb, 10, nb))
{
ft_affichage(comb, nb);
}
}
ft_debut fills tab[] with the initial combination (tab[i] = i for i from 0 to k) if the n and k parameters are valid.
ft_suivant "increments" the combination in tab[] if the n and k values are valid and the combination in tab[] has not yet reached the maximum value. i scans backwards from k-1 to 0, stopping when a tab[i] that can be incremented (the maximum allowed value for tab[i] is n-k+i) has been reached or when tab[0] is already at its maximum allowed value (so tab[] already contains the final combination). If a suitable tab[i] is found, it is incremented by 1, and any remaining elements from tab[i+1] up to tab[k-1]` are set to one more than their preceding element.
Example of ft_suivant for n=10, k=2, tab[0]=2, tab[1]=9:
int i = k; — i=2
while (i--) — true, i=1
{
int x = tab[i]; — x=9 (tab[1])
if (x < --n) — n=9, false
}
while (i--) — true, i=0
{
int x = tab[i]; — x=2 (tab[0])
if (x < --n) — n=8, true
{
do
{
tab[i++] = ++x; — x=3, tab[0]=3, i=1
}
while (i < k); — true
do
{
tab[i++] = ++x; — x=4, tab[1]=4, i=2
}
while (i < k); — false
return 1;
The combination has been successfully "incremented" from {2, 9} to {3, 4}.

Get the largest total starting of either by any two arrays(Maximum Sum Path in Two Arrays)

Sample Input
5
2 3 5 10 11
5
1 3 7 9 13
Sample Output
dollar 34
//Get total count sum starting from either array, If two arrays have same index it can split and continue getting total.. like 2+3+7+9+13=34 number 3 is same in 2nd index of each arrays so it change to other array and continue getting total.
#include <stdio.h>
int main(){
int a;
scanf("%d",&a);
int cash[a];
for(int i=0;i<a;i++)
scanf("%d",&cash[i]);
int b;
scanf("%d",&b);
int cash2[b];
for(int i=0;i<b;i++)
scanf("%d",&cash2[i]);
int total=0;
for (int i=0;i<a;i++){
total+=cash[i];
if(cash[i]==cash2[i])
total+=cash2[i];
}
printf("doller %d",total);
return 0;
}
You can use an int pointer to store the current array whose sum you will be calculating, once you get equal number in both the array, then you can swap the array to which pointer is pointing to. There was one more issue you forgot to use %d in printf().
#include <stdio.h>
int main(){
int a;
scanf("%d",&a);
int cash[a];
for(int i=0;i<a;i++)
scanf("%d",&cash[i]);
int b;
scanf("%d",&b);
int cash2[b];
for(int i=0;i<b;i++)
scanf("%d",&cash2[i]);
int total=0;
int* currentArray = cash;
for (int i=0;i<a;i++){
total+=currentArray[i];
if(cash[i]==cash2[i]){
if(currentArray == cash){
currentArray = cash2;
}else{
currentArray = cash;
}
}
}
printf("dollar %d",total);
return 0;
}
use printf("doller %d",total)
In C programming language, %d is a format specifier.
You can use two loops.
The first loop runs as long as you are summing up the first array. If both entries are equal, quit the loop.
The second loop continues by summing up the rest of the second array. You don't reset the index for this.
int total=0;
int i;
for (i = 0; i < a; i++) {
if (cash[i] == cash2[i]) { // could be in the loop's condition, but looks clearer here
break;
}
total += cash[i];
}
for (/* no initial instruction*/; i < a; i++) {
total += cash2[i];
}
Solved
import java.util.Scanner;
public class MaximumSumPath
{
int max(int x, int y)
{
return (x > y) ? x : y;
}
int maxPathSum(int ar1[], int ar2[], int m, int n)
{
int i = 0, j = 0;
int result = 0, sum1 = 0, sum2 = 0;
while (i < m && j < n)
{
if (ar1[i] < ar2[j])
sum1 += ar1[i++];
else if (ar1[i] > ar2[j])
sum2 += ar2[j++];
else
{
result += max(sum1, sum2);
sum1 = 0;
sum2 = 0;
while (i < m && j < n && ar1[i] == ar2[j])
{
result = result + ar1[i++];
j++;
}
}
}
while (i < m)
sum1 += ar1[i++];
while (j < n)
sum2 += ar2[j++];
result += max(sum1, sum2);
return result;
}
public static void main(String[] args)
{
MaximumSumPath sumpath = new MaximumSumPath();
int sum = 0;
Scanner s = new Scanner(System.in);
int m = s.nextInt();
int ar1[] = new int[m];
for(int i = 0; i < m; i++)
{
ar1[i] = s.nextInt();
}
int n = s.nextInt();
int ar2[] = new int[n];
for(int i = 0; i < n; i++)
{
ar2[i] = s.nextInt();
}
System.out.println("dollar" + sumpath.maxPathSum(ar1, ar2, m, n));
}
}

How to efficienty count from 0000 to 9999 in a digit display?

I've n display that count from 0 to 9. I'd like to make an efficient code for a micro in C language. What I've wrote is:
dis_value[0]++;
if (dis_value[0] > 9) {
dis_value[0] = 0;
dis_value[1]++;
}
if (dis_value[1] > 9) {
dis_value[0] = 0;
dis_value[1] = 0;
dis_value[2]++;
}
if (dis_value[2] > 9) {
dis_value[0] = 0;
dis_value[1] = 0;
dis_value[2] = 0;
dis_value[3]++;
}
if (dis_value[3] > 9) {
dis_value[0] = 0;
dis_value[1] = 0;
dis_value[2] = 0;
dis_value[3] = 0;
}
Where from 0 to 3 are display module number.
Is that the best way?
Or maybe is better a single counter of 16bit that is split into 4 different part?
You can nest the digit reset or increment
dis_value[0]++;
if (dis_value[0] > 9) {
dis_value[0] = 0;
dis_value[1]++;
if (dis_value[1] > 9) {
dis_value[1] = 0;
dis_value[2]++;
if (dis_value[2] > 9) {
dis_value[2] = 0;
dis_value[3]++;
if (dis_value[3] > 9) {
dis_value[3] = 0;
}
}
}
}
By doing above you are not unnecessarily executing all the ifs.
char *inc(char *buff, unsigned *i)
{
unsigned tmp = ++(*i);
buff[0] = tmp % 10;
tmp /= 10;
buff[1] = tmp % 10;
tmp /= 10;
buff[2] = tmp % 10;
tmp /= 10;
buff[3] = tmp % 10;
return buff;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void delay(int number_of_seconds)
{
int milli_seconds = 1000 * number_of_seconds;
clock_t start_time = clock();
while (clock() < start_time + milli_seconds);
}
int main(int argc, const char *argv[])
{
int arr[4] = {0};
for(int i=0; i < 4; i++)
{
for(int j = 0; j<9; j++)
{
arr[i]++;
delay(1000);
printf("%i%i%i%i\n",arr[3], arr[2], arr[1], arr[0]);
}
}
printf("\n");
return 0;
}
I spotted you want to keep the code with minimal dependencise on a microcontroller.
If you are willing to treat the dis_value buffer as an integer, with one byte per digit, say little-endian, which can be held in a register, which should also be faster, then you can combine the sequence:
if (dis_value[N] > 9) {
dis_value[N] = 0;
dis_value[N+1]++;
It becomes (with #kiran 's nesting)
if ((dis_value&(0xf<<(N*8)))==(10<<(N*8)))
{
dis_value+=(0x100-10)<<(N*8);
if ...
}
Where I am presuming the compiler will resolve the constant expressions.
It would also be good to reverse the addition and the if in order to improve conditional pipeline evaluation, if your controller has a pipeline, but that means writing assembler code.
The following pseudocode should give the idea. The next condition is evaluated using the value before the addition, so the two operations can be performed in parallel. If you were actually encoding this to a circuit, this is an obvious optimisation:
bool do0 = ((dis_value&(0xf<<(0*8)))==(9<<(0*8)))
dis_value++;
if (do0)
{
bool do1 = ((dis_value&(0xf<<(1*8)))==(9<<(1*8)));
dis_value += (0x100-10)<<(0*8);
if (do1)
{
do2 = ((dis_value&(0xf<<(2*8)))==(9<<(2*8)));
dis_value += (0x100-10)<<(1*8);
if (do2) ...
}
}
The next question to ask is how can you minimally update a segmented display for an increment!
simulate math addition would suffice, checking from the lowest digit to the highest.
#include <stdio.h>
void incr(int dis_value[], int n) {
++dis_value[0];
for (int i=0; i+1<n; ++i) {
if (dis_value[i] < 10) break;
dis_value[i+1] += dis_value[i] / 10;
dis_value[i] %= 10;
}
dis_value[n-1] %= 10;
}
void echo(int dis_value[], int n) {
for (int i=n-1; i>=0; --i) printf("%d", dis_value[i]);
printf("\n");
}
int main() {
int dis_value[] = {0, 0, 0, 0};
for (int i=0; i<10000; ++i) {
incr(dis_value, 4);
echo(dis_value, 4);
}
return 0;
}

Access Violation in C program involving pointer variable?

I was trying to solve Project Euler question 16 using c. I did not use bignnum libraries. The question asks 2^1000. I decided to store every digit of that number in an array.
For Example: 45 means arr[0]=4, arr[1]=5;
The problem is definitely i the function int multi.
#include<stdio.h>
#include<conio.h>
int multi(int *base, int k);// does the multiplication of array term by 2
void switcher();//switches every term when the fore mostvalue is >10
int finder();// finds the array address of last value
int arr[1000];
int summer();//sums all values of the array
int main()
{
arr[1000] = { 0 };
arr[0] = 1;
int i, j, sum, k, p;
for (i = 0; i < 1000; i++)
{
j = 0;
k = finder();
p = multi(arr + k, j);
}
sum = summer();
printf("sum of digits of 2^1000 is %d", sum);
_getch();
}
int multi(int *base, int k)
{
int p;
if (base == arr)
{
*base = *base - 1;
*base = *base + k;
if (*base > 10)
{
*base = *base - 10;
switcher();
}
return 0;
}
*base = *base * 2;
*base = *base + k;
if (*base > 10)
{
*base = *base - 10;
p = multi(base - 1, 1);
}
else
{
p = multi(base - 1, 0);
}
}
void switcher()
{
int j;
for (j = 0;; j++)
{
if (arr[j] == 0)
{
break;
}
}
j--;
for (; j > 0; j--)
{
arr[j + 1] = arr[j];
}
arr[0] = 1;
}
int finder()
{
int j;
for (j = 0;; j++)
{
if (arr[j] == 0)
{
break;
}
}
return --j;
}
int summer()
{
int summ, i;
summ = 0;
for (i = 0; i<1000; i++)
{
summ = summ + arr[i];
if (arr[i] == 0)
break;
}
return summ;
}
It compiles but during runtime it shows Access Write Violation, base was ......
Please explain this error and how to resolve it ?
Array is of 100 Bytes but you are looping for 1000. Also in function Finder() , you do not have a limit on variable j so your array size is going beyond 100 bytes.
Also use memset to assign array variables to 0.
As said in the comments, 2^1000 has 302 decimal digits.
You're going far outside your array.
But your code is very complicated because you store the digits with the most significant one first.
Since you're only interested in the digits and not the order in which they would be written, you can store the number "in reverse", with the least significant digit first.
This makes the code much simpler, as you can loop "forwards" and no longer need to shuffle array elements around.
Using -1 as "end of number" marker, it might look like this:
void twice(int* digits)
{
int i = 0;
int carry = 0;
while (digits[i] >= 0)
{
digits[i] *= 2;
digits[i] += carry;
if (digits[i] >= 10)
{
carry = 1;
digits[i] -= 10;
}
else
{
carry = 0;
}
i++;
}
if (carry)
{
digits[i] = 1;
digits[i+1] = -1;
}
}
int main()
{
int digits[302] = {1, -1}; /* Start with 1 */
twice(digits); /* digits is now { 2, -1 } */
return 0;
}

Largest palindrome made from the product of two 3-digit numbers with C

The code is trying to find the largest palindrome made from the product of two 2-digit numbers. The answer is 91*99 = 9009 but I keep getting 990, which is not even a palindrome. I really appreciate the help!
#include <stdio.h>
int main()
{
int i = 10;
int j = 10;
int a = 0;
int b = 0;
int array[100] = {0};
int divider = 10;
int num;
int great;
int product;
int n;
int flag;
/*Loop through first 2 digit number and second 2 digit number*/
while (i<100)
{
while (j < 100)
{
product = i*j;
array [a] = product % 10;
n = product / divider;
while (n != 0)
{
a++;
num = n%10;
divider *=10;
array[a]=num;
n = product/divider;
}
flag = 0;
while (b<a)
{
if (array[b] != array[a])
{
flag = 1;
}
b++;
a--;
}
if (flag == 0)
{
great = product;
}
j++;
a = 0;
b = 0;
}
i++;
}
printf("The largest palindrome is %d \n", great);
return 0;
}
Here is a code snippet you can try.
#include <stdio.h>
void main()
{
int a = 1; // first integer
int b = 1; // second integer
int currentNumber;
int currentPalin; if a palindrome is found, its stored here
while (a<100){ //loop through the first number
while (b<100){ // loop through the second number
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){ //check for palindrome
currentPalin = currentNumber;
}
b = b+1; //increment the second number
}
b = a; // you could have set b=1 but it would not be an efficient algorithm because
//some of the multiplication would occur twice. eg- (54*60) and (60*54)
a = a +1; //increment the first number
}
printf ("Largest palindrom is %d \n", currentPalin);
getchar();
}
// method for finding out reverse
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
// when you divide a number by 10, the
//remainder gives you the last digit. so you are reconstructing the
//digit from the last
n = n/10;
}
return reverse;
}
Update:- As suggested by M Oehm, I have modified the code to make it more general.
#include <stdio.h>
void main()
{
int a = 1;
int b = 1;
int currentNumber;
int currentPalin=0;
while (a<100){
while (b<100){
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){
if (currentNumber>currentPalin){
currentPalin = currentNumber;
}
}
b = b+1;
}
b = 1;
a = a +1;
}
if (currentPalin==0){
printf("No Palindrome exits in this range");
}
else {
printf ("Largest palindrome is %d \n", currentPalin);
}
getchar();
}
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
return reverse;
}
An alternative approach to solve the problem.
#include<stdio.h>
int reverse(int num)
{
int result = 0;
while( num > 0)
{
result = result * 10 + (num%10);
num/=10;
}
return result;
}
int main()
{
int last_best = 1;
int best_i=1;
int best_j = 1;
const int max_value = 99;
for( int i = max_value ; i > 0 ; --i)
{
for(int j = i ; j > 0 ; --j){
int a = i * j;
if( last_best > a )
break;
else if ( a == reverse(a) )
{
last_best = a;
best_i = i;
best_j = j;
}
}
}
printf("%d and %d = %d\n", best_i,best_j,last_best);
}
And it is quite simple to follow.
It seems that you do not reinitialize variables at the beginning of loop. They keeps values from previous iterations. For example, j and divider. Put
j = 10;
before starting "j" loop, i.e.:
j = 10;
while (j < 100) ...
The same for divider:
...
j = 10;
while (j < 100) {
divider = 10;
...
If you were using for loops you would avoid this problem naturally:
for(i=10; i<100; i++) {
for(j=10; j<100; j++) {
...
}
}

Resources