Cant understand what happens when i run this code - c

I can't understand why the result of effe(10) procedure is 110. (Thats a code taken from an exercise)
I tried to write down what is happening in the code, but there are too many recursions and i can't understand what is happening.
int effe(int);
int gi(int);
int main(){
int test = effe(10);
printf("%d\n", test); //this prints 110
system("pause");
return 0;
}
int effe(int a){
if(a < 2)
return a * 2;
else
return (gi(a - 1) + gi(a - 2));
}
int gi(int a){
if (a < 2)
return effe(a);
else
return (effe(a - 1) + effe(a - 2));
}

To some extent, this is variation of Fibonacci.
Calculate the values starting with efff(0), gi(0), and calculate efff(1), gi(1),efff(2), gi(2), until you reach efff(10), gi(10)
a efff(a) gi(a)
0 0 0
1 2 2
2 2=2+0 2=2+0
3 4=2+2 4=2+2
4 6=2+4 6=2+4
5 10=4+6 10=4+6
6 16=6+10 16=6+10
7 26 26
8 42 42
9 68 68
10 110 110
Note that each item is 2 times the Fibonacci value (1,1,2,3,5,8,13,21,34,55).

Related

Why is there a segmentation-fault error only with certain input values on pascal's triangle? (C)

I am trying to create a program outputting the pascal's triangle, using C in OnlineGDB and repl.it using a 2x2 array asking how many lines the user wants to print. The main problem is that the program works, but only until printing for 7 rows in onlinegdb, and only 3 rows in repl.it.
There is no error in OnlineGDB, and repl.it says "signal: segmentation fault (core dumped)"
Additionally, I added 3 "PASS" print lines to see where the error occurs, and when reaching the 8th line in onlineGDB it passes all 3 of the for statements filling the array. When reaching the 4th line in repl.it passes all 3 of the for statements filling the array, but both of them doesn't print out the correct numbers. Again, inputted numbers below these values show that all of the code works.
Is there a fix for this, or is it an error with websites handling arrays?
#include <stdio.h>
int main(void){
int intCount;
int intCount1;
int intRows;
int intColumns;
printf("HOW MANY ROWS DO YOU WANT?? ");
scanf("%i", &intRows);
intColumns = intRows;
int intNum[intRows][intColumns];
printf("PASS ");
// FIRST FILL ARRAY WITH 0
for(intCount = 0; intCount <= intRows+1; ++intCount){
for(intCount1 = 0; intCount1 <= intColumns+1; ++intCount1){
intNum[intCount][intCount1] = 0;
}
}
printf("PASS ");
// SET STARTING POINT (1)
intNum[0][0] = 1;
// NOW FILL ARRAY WITH PASCAL TRIANGLE
for(intCount = 0; intCount <= intRows; ++intCount){
for(intCount1 = 0; intCount1 <= intColumns; ++intCount1){
intNum[intCount+1][intCount1+1] = ((intNum[intCount][intCount1+1])+ (intNum[intCount][intCount1]));
}
}
printf("PASS\n");
// NOW PRINT ARRAY
for(intCount = 0; intCount <= intRows; ++intCount){
for(intCount1 = 0; intCount1 <= intColumns; ++intCount1){
// WITHOUT ZEROES:
/*if(intNum[intCount][intCount1] != 0){
printf("%5i",intNum[intCount][intCount1]);
}*/
// WITH ZEROES:
printf("%4i",intNum[intCount][intCount1]);
}
printf("\n");
}
return 0;
}
Logic: In the code above I created a 2 x 2 array with height and width dimensions one larger than the user asks for. I then fill the array with zeroes, and start with a 1 in the top left corner. From there I can use the pascals triangle formula by adding the two numbers above it
I tried changing the counting variables of arrays to make sure everything was correct, but it did not help. I originally coded on onlineGDB but used repl.it to see if there was any further errors, to which there was none. Additionally checked other questions on stack.
Desired Output:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
OnlineGDB Output: (limited to 7 rows in the input)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
repl.it Output: (limited to 3 rows in the input)
1
1 1
1 2 1
Note: In the output, my code also prints the 0s at the moment and the whole array so that I can visualize it. I am also 100% sure it's the same code uploaded to both
This could be something simple, but I appreciate all the help I can get. I'm more curious why the outputs are different on separate websites with the same code.
Why are you using loops like
for (intCount = 0; intCount <= intRows+1; ++intCount)
{
for (intCount1 = 0; intCount1 <= intColumns+1; ++intCount1)
{
intNum[intCount][intCount1] = 0;
}
}
when you allocated intNum[intRows][intColumns]? You are trampling way out of bounds. That's why your code crashes. That's why you get different behaviours in different systems.
Use:
for (int i = 0; i < intRows; i++)
{
for (int j = 0; j < int columns; j++)
intNum[i][j] = 0;
}
or an equivalent. Note that you use < and not <=; you use the declared limit, not that limit plus one.
Here is some working code, printing without the zeros. Your algorithm for generating the values in Pascal's Triangle was flawed on at least two counts. As before, it trampled way out of bounds of the array, and it also produced two rows with a single 1 in the output (when zeros were not printed). This code avoids those flaws. It also uses i and j as the loop counters — old Fortran programmers die hard.
/* SO 7549-7765 */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int intRows;
int intColumns;
printf("How many rows do you want? ");
if (scanf("%i", &intRows) != 1)
{
fprintf(stderr, "failed to read an integer\n");
exit(1);
}
if (intRows < 1 || intRows > 64)
{
fprintf(stderr, "value %d is outside the range 1..64\n", intRows);
exit(1);
}
printf("Rows: %d\n", intRows);
intColumns = intRows;
int intNum[intRows][intColumns];
printf("PASS\n");
// First, fill array with zeros
for (int i = 0; i < intRows; i++)
{
for (int j = 0; j < intColumns; j++)
{
intNum[i][j] = 0;
}
}
printf("PASS\n");
// Set starting point (1)
intNum[0][0] = 1;
// Now fill array with Pascal's Triangle
for (int i = 1; i < intRows; i++)
{
intNum[i][0] = intNum[i-1][0];
for (int j = 1; j <= i; j++)
{
intNum[i][j] = intNum[i-1][j-1] + intNum[i-1][j];
}
}
printf("PASS\n");
// Now print array
for (int i = 0; i < intRows; i++)
{
for (int j = 0; j < intColumns; j++)
{
// Without zeros:
if (intNum[i][j] != 0)
printf(" %5d", intNum[i][j]);
// With zeros:
// printf(" %5d", intNum[i][j]);
}
printf("\n");
}
return 0;
}
Note the use of " %5d" in the printing format. That space ensures that the numbers remain separate even if there are 6 or more digits in the values (which first happens with 21 rows requested).
Sample output:
How many rows do you want? 15
Rows: 15
PASS
PASS
PASS
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1

Eratosthenes prime numbers

I have created a program to search for prime numbers. It works without problems until the entered number is smaller than 52, when it is bigger output prints out some blank (0) numbers and I don't know why. Also other numbers have blank output.
My code is:
#include <stdio.h> //Prime numbers
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
int c[100], n, a[50], d, e, b = 1;
void sort() {
for (int i = 1; i < n; i++) {
if (c[i] > 1) {
a[b] = c[i];
printf("%d %d %d\n", a[1], b, i);
b++;
e = 2;
d = 0;
while (d <= n) {
d = c[i] * e;
c[d - 1] = 0;
e++;
}
}
}
}
int main() {
printf("Enter number as an limit:\n");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
c[i] = i + 1;
}
sort();
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 1; i < b; i++) {
printf("%d ", a[i]);
}
return 0;
}
Here is output for 25:
Enter number as an limit:
25
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
But for 83 is:
Enter number as an limit:
83
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
2 10 28
2 11 30
2 12 36
2 13 40
2 14 42
2 15 46
2 16 52
0 17 58
0 18 60
0 19 66
0 20 70
0 21 72
0 22 78
0 23 82
Prime numbers between 1 and 83 are:
0 3 5 7 11 0 17 19 23 29 31 37 0 43 47 53 0 61 67 71 73 79 83
Blank spots always spots after 17th prime number. And always the blank numbers are the same. Can you help me please what is the problem?
The loop setting entries in c for multiples of c[i] runs too far: you should compute the next d before comparing against n:
for (d = c[i] * 2; d <= n; d += c[i]) {
c[d - 1] = 0;
}
As a matter of fact you could start at d = c[i] * c[i] because all lower multiples have already been seen during the previous iterations of the outer loop.
Also note that it is confusing to store i + 1 into c[i]: the code would be simpler with an array of booleans holding 1 for prime numbers and 0 for composite.
Here is a modified version:
#include <stdio.h>
int main() {
unsigned char c[101];
int a[50];
int n, b = 0;
printf("Enter number as a limit:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 100) {
printf("invalid input\n");
return 1;
}
for (int i = 0; i < n; i++) {
c[i] = 1;
}
for (int i = 2; i < n; i++) {
if (c[i] != 0) {
a[b] = i;
//printf("%d %d %d\n", a[0], b, i);
b++;
for (int d = i * i; d <= n; d += i) {
c[d] = 0;
}
}
}
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 0; i < b; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Output:
chqrlie$ ./sieve4780
Enter number as a limit:
25
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
chqrlie$ ./sieve4780
Enter number as a limit:
83
Prime numbers between 1 and 83 are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79
Your problem seems to be caused by the fact that you have declared an array with size 50, but in fact it goes further than that: imagine you want to use Eratosthenes' procedure to find the first 10,000 prime numbers. Does this mean that you need to declare an array of size 10,000 first (or even bigger), risking to blow up your memory?
No: best thing to do is to work with collections where you don't need to set the maximum size at declaration time, like a linked list, a vector, ..., like that you can make your list grow as much as you like during runtime.

Search for `count' distinct odd numbers that are smaller than `bound' and add up to `sum'

I am working on a problem that finds 'count' odd numbers below the int value 'bound' and adds up to an int value sum. It is suggested that I use recursion to solve.
I have completed the recursion and have made it solve 7 / 8 cases in mimir. There is one case that is showing a fail but I cannot figure out what is wrong even when stepping through with gdb.
Problem case:
Input: 10 54 108
EDIT:
So it turns out that my code is correct and is finding the correct answer for this case ( AKA - No solution exists ) but my problem is that I only have 3 sec of run time to find this solution and currently my code takes longer than that.
Not looking for a straight answer necessarily, more of a point in the right direction. Trying to learn from this :)
https://ibb.co/4138WBw
int odd_sum(int count, int bound, int sum)
{
if (bound % 2 == 0)
return odd_sum(count, bound -1, sum);
else if ( sum == 0 && count == 0 && bound >= -1)
return 1;
else if ( sum - bound < 0)
return odd_sum(count, bound - 2, sum);
else if (count == 0 && sum != 0)
return 0;
else if (bound < 1 && sum != 0)
return 0;
else
{
int value = (odd_sum(count - 1, bound - 2, sum - bound));
if ( value )
{
return printf("%d ", bound);
}
else
return (odd_sum(count - 1, bound - 2, sum - bound));
}
/* Do not change the main() function */
int main(void)
{
int value;
int c, b, s;
printf("Please enter 3 positive integers: count, bound, and sum:\n");
if (scanf("%d%d%d", &c, &b, &s) != 3) {
printf("Please enter 3 integers.\n");
return 1;
}
if (c <= 0 || b <= 0 || s <= 0) {
printf("Integers must be positive.\n");
return 1;
}
value = odd_sum(c, b, s);
if (value)
printf("\n");
else
printf("There are no solutions.\n");
return 0;
}
The final result needs to look like this for the two cases, ( pass or fail )
$./odd_sum
Please enter 3 positive integers: count, bound, and sum:
10 20 100
1 3 5 7 9 11 13 15 17 19
$./odd_sum
Please enter 3 positive integers: count, bound, and sum:
10 18 100
There are no solutions.
$./odd_sum
Please enter 3 positive integers: count, bound, and sum:
12 30 200
5 7 9 11 13 15 17 19 23 25 27 29
Thank you guys in advance
This code seems to return the correct result for input, (10, 54, 108): 1 3 5 7 9 11 13 15 17 27
int odd_sum(int count, int bound, int sum){
if (count == 0 && sum == 0)
return 1;
if (count == 0 || bound <= 0)
return 0;
if (bound % 2 == 0)
return odd_sum(count, bound - 1, sum);
if (odd_sum(count - 1, bound - 2, sum - bound))
return printf("%d ", bound);
else
return odd_sum(count, bound - 2, sum);
return 0;
}

Need help for find the logic of a heuristic sequence

I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
0 1
2 3 4 5
6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

C programming 122 = 12 + 34 - 5 - 6 + 78 + 9

Input n. Put + or - betweeen 1,2,3,4,5,6,7,8,9 to found a expression equal to n
(122 = 12 + 34 - 5 - 6 + 78 + 9 or 146 = 123 + 45 + 67 - 89)
My idea is that we could fill between 2 numbers 3 values: 0 for no blank, 1 for + and 2 for -
for example 1 + 2 + 3456 - 78 + 9 is 11000201. And this is base-3-number
There are 3^8 expressions to test because we have 8 position to fill, each one has 3 ways.
Start for loop, i from 1 to 3^8. Convert each i to base-3-number and and convert each character of i into + - or no blank to calculate if the present expression is equal to n or not. If equal, print out the expression and end the loop...
My problem is that the program give me the wrong answer and I can't find out a bug.
for example I input 145 but it give me 123 + 45 + 67 - 89 (=146)
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n, result, a[100],count, i,j, test,temp, checkpoint,num,checkresult=0;
printf("Input n\n");
scanf("%d",&n);
for (num=1;num<=6561;num++)
{
count=1;
test = num;
result = 0;
checkpoint=0;
a[0]=1;
//convert to base 3
while (test>0)
{
a[count]=test%3;
//printf("%d ",a[count]);
test = test/3;
count++;
}
count--;
//put 0 to fill full 8 blank
while (count<8)
{
count++;
a[count]=0;
//printf("%d ",a[count]);
}
//inverse the sequence to have the right
for (i=1;i<=count/2;i++)
{
temp = a[i];
a[i] = a[count+1-i];
a[count+1-i] = temp;
}
//calculate the number
//1 is +, 2 is -, 0 is no blank
for (i=1;i<=8;i++)
{
if ((a[i]==1) || (a[i]==2))
{
if (a[checkpoint]==1)
for (j=checkpoint+1;j<=i;j++)
result = result + j*pow(10,i-j);
if (a[checkpoint]==2)
for (j=checkpoint+1;j<=i;j++)
result = result - j*pow(10,i-j);
checkpoint=i;
}
}
if (i==9)
{
if (a[checkpoint]==1)
for (j=checkpoint+1;j<=i;j++)
result = result + j*pow(10,i-j);
if (a[checkpoint]==2)
for (j=checkpoint+1;j<=i;j++)
result = result - j*pow(10,i-j);
}
//check if the result is correct or not. If correct, print it out and break the loop
if (result == n)
{
checkresult=1;
for (i=1;i<=8;i++)
{
printf("%d",i);
if (a[i]==1)
printf("+");
if (a[i]==2)
printf("-");
}
printf("9\n");
break;
}
}
if (checkresult==0)
printf("Can't found...");
return 0;
}
I have solved the problem.
Just have to change the result variable's type into double. Because pow statement require a double type variable
Your code is running fine for me, here is the screenshot for the output:
Input: n=145 Output: 123-4-56-7+89

Resources