I have tried to solve Project Euler problem 2 by a for loop. I'm new to c programming and I cannot seem to get the algorithm right.
3524579
The for loop is suppose to look at for the 32 fibonacci which is less than 4000000. Then I have defined the fibonacci function and after than I want to add the even fibonacci numbers by the second for loop.
I get 3524579, can anyone help me with what I'm doing wrong?
/* Edited:
Ok, I rewrote the code using your tips. I do not understand why this does not work. I tried to write each steps down on paper:
The predicate is evaluated b mod 2 == 0, so the following happends:
sum = 2 + 0
a = b -> a == 2
b = sum -> b == 2
These steps iterate until the value 4mill. Can someone see what I fail to not see :p?*/
New edited version: I finally it work using a for-loop. Just wondering if there was a prettier way to do it using for-loop maybe.
#include <stdio.h>
int main() {
int a = 0;
int b = 1;
int result = 0;
int sum = 0;
for(;;){
if(!(b < 4000000)) break;
if(b % 2 == 0)
result = result + b;
sum = a + b;
a = b;
b = sum;
printf("%d\n", result);
}
}
A couple things:
Notice that your answer is equal to the 31st fib number + 1. This means you are replacing your total with new values on every iteration instead of keeping a running total.
Consider looping until the current fib number gets > 4M instead of figuring out beforehand that there are 32 fib numbers you need to look at.
Related
I'm new here, I wanted to know how I can make my automated(for loop) variables assign to my automated (for loop) values. In the example, I only printed it but, I want them to be used later on in a certain equation. I don't want to manually assign the values cause that's kinda copy pasting. This is a CS50 problem set, so I want it if you show the minimum amount of information for me to understand. See the Images for better understanding. Best Regards.
My Code:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long credit = get_long("What's your Credit Number?(No Hyphens) ");
for (char letter= 'a'; credit != credit/10; letter++)
{
int take_credit = credit % 10;
printf("%c = %i\n", letter, take_credit);//I WANT IT TO BE ASSIGNED SO I CAN SUM ALLTOGETHER
credit= credit / 10;
}
printf("=a+b+c+d+e+f+g\n=4+1+2+0+0+4+1\n=12\n"); //THIS PART IS JUST FOR DEMONSTRATION
}
My Wanted Result:
What's your Credit Number?(No Hyphens) 1400214
a = 4
b = 1
c = 2
d = 0
e = 0
f = 4
g = 1
=a+b+c+d+e+f+g
=4+1+2+0+0+4+1
=12
I'm new to C programming (I have some very basic experience with programming via vb.NET), and I'm attempting to write a program for the Project Euler Problem #1.
https://projecteuler.net/problem=1
Algorithm
The challenge requires the programmer to find the sum of all multiples of 3 or 5 (inclusive) below 1000 (I used intInput to allow the user to enter an integer in place of 1000).
My current solution takes the input, and decrements it by 1 until (intInput - n) % 3 = 0, that is, until the next nearest multiple of 3 under the input integer is found.
The program then cycles through all integers from 1 to ((intInput - n) / 3), adding each integer to the sum of the previous integers, so long as the current integer is not a multiple of 5, in which case, it is skipped.
The resultant sum is then stored in intThreeMultiplier.
The above process is then repeated, using 5 in place of 3 to find the highest multiple of 5 under intInput, and then cycles through integers 1 to ((intInput - n) / 5), not skipping multiples of 3 this time, and stores the sum in intFiveMultiplier.
The output sum is then calculated via sum = (3 * intThreeMultiplier) + (5 * intFiveMultiplier).
The Problem
Whenever I compile and run my code, the user is allowed to input an integer, and then the program crashes. I have determined that the cause has something to do with the first For loop, but I can't figure out what it is.
I have commented out everything following the offending code fragment.
Source Code:
#include <stdio.h>
#include <stdlib.h>
void main()
{
int intInput = 0; /*Holds the target number (1000 in the challenge statement.)*/
int n = 0;
int count = 0;
int intThreeMultiplier = 1;
int intFiveMultiplier = 1;
printf("Please enter a positive integer.\n");
scanf("%d",intInput);
for( ; (((intInput - n) % 3) != 0) ; n++)
{}
/*for(; count <= ((intInput - n) / 3); count++)
{
if ((count % 5) != 0)
{
intThreeMultiplier += count;
}
}
count = 0;
for(n = 0 ; ((intInput - n) % 5) != 0 ; n++)
{}
for(; count <= ((intInput - n) / 5) ; count++)
{
intFiveMultiplier += count;
}
int sum = (3 * intThreeMultiplier) + (5 * intFiveMultiplier);
printf("The sume of all multiples of 3 or 5 (inclusively) under %d is %d.",intInput, sum);*/
}
This is my first time posting on StackOverflow, so I apologize in advance if I have broken any of the rules for asking questions, and would appreciate any feedback with respect to this.
In addition, I am extremely open to any suggestions regarding coding practices, or any rookie mistakes I've made with C.
Thanks!
scanf("%d",intInput);
might be
scanf("%d", &intInput); // note the ampersand
scanf need the address the variable where the content is to be stored. Why scanf must take the address of operator
For debugging only, print the input to verify that the input is accepted correctly, something like
printf("intInput = %d\n", intInput);
The first thing you need when you are inputting intInput you should use:
scanf("%d", &intInput);
Because scanf() need as an argument of a pointer to your variable. You are doing this by just putting the & sign before your int.
In addition I think that you should double check your algorithm, because you are summing up some numbers more than once. :)
Some time ago I ask in codereview.stackexchange a review for one of my problems. I din't get a sufficient answer and many people told me to post a question here just to get more answers and solutions. My problem is the follwoing.
Giving a dynamic array, we want to pass the array elements from a
file. The first number in the file N gives us the array length. They
follow N numbers, the actual elements of the array.
Three brothers are going to work in the shop of their father for a time. The >shop is doing well and every day generates profit which the
three brothers may provide. The brothers agreed that they would divide
the total time in three successive parts, not necessarily equal
duration, and that each one will be working in the shop during one of
these parts and collects the corresponding profit on his behalf. But
they want to make a deal fairly, so that one received from three more
profit someone else. Specifically, they want to minimize the profit
the most favored of the three will receive.
Now I created a solution with O(n^2) complexity but I want to know if someone has any other idea to solve the problem with linear complexity.
Lets assume we have the follwoing input :
1 1 8 1 1 3 4 9 5 2
The output is 15.
A=1+1+8+1+1+3 , B=4+9=13 , C=5+2=7
Remenber I want linear complexity. If someone believe it's just a homework to be done and I boring then he has no place here. I just want to know if someone has any idea how to solve the problem in C.
My try was the following:
#include <stdio.h>
#include <limits.h>
#define max(A,B,C) A > (B > C ? B : C) ? A : (B > C ? B : C)
#define N 10
int main()
{
int e[N] = {1, 1, 8, 1, 1, 3, 4, 9, 5, 2 };
int i=0;
int j = N-1;
int A = e[i];
int C = e[j];
int B = 0;
int x, AL, CR, BL, BR, m, mp = INT_MAX, L, R;
for(x = i+1 ; x < j; x++) B+=e[x];
m = max(A,B,C);
printf("A=%d B=%d C=%d\n", A, B, C);
while(m < mp)
{
AL = A+e[i+1];
CR = C+e[j-1];
BL = B-e[i+1];
BR = B-e[j-1];
L = max(AL,BL,C);
R = max(A,BR,CR);
if(L<R)
{
A=AL;
B=BL;
i++;
}
else
{
C=CR;
B=BR;
j--;
}
mp = m;
m = max(A,B,C);
printf("A=%d B=%d C=%d MAX=%d\n", A, B, C, m);
}
printf("%d", mp);
return 0;
}
I don't want someone to base in the above code cause it gives wrong outputs in 90% of the most inputs.
I am trying to make from f_rec (recursive function) to f_iter (iterative function) but I can't.
(My logic was to create a loop to calculate the results of f_rec(n-1).
int f_rec(int n)
{
if(n>=3)
return f_rec(n-1)+2*f_rec(n-2)+f_rec(n-3);
else
return 1;
}
int f_iter(int n)
{
}
I also think that my time complexity for the f_rec is 3^n , please correct me if I'm wrong.
Thank you
There are two options:
1) Use the discrete math lessons and derive the formula. The complexity (well if #Sasha mentioned it) will be O(1) for both memory and algorithm. No loops, no recursion, just the formula.
At first you need to find the characteristic polynomial and calculate its roots. Let's asssume that our roots are r1, r2, r3, r4. Then the n'th element is F(n) = A * r1^n + B * r2^n + C * r3^n + D * r4^n, where A, B, C, D are some unknown coefficients. You can find these coefficients using your initial conditions (F(n) = 1 for n <= 3).
I can explain it on russian if you need.
2) Use additional variables to store intermediate values. Just like #6052 have answered (he has answered really fast :) ).
You can always calculate the newest value from the last three. Just start calculating from the beginning and always save the last three:
int f_iter (int n) {
int last3[3] = {1,1,1}; // The three initial values. Use std::array if C++
for (int i = 3; i <= n; ++i) {
int new_value = last3[0] + 2 * last3[1] + last3[2];
last3[0] = last3[1];
last3[1] = last3[2];
last3[2] = new_value;
}
return last3[2];
}
This solution need O(1) memory and O(n) runtime. There might exist a formula that calculates this in O(1) (there most likely is), but I guess for the sake of demonstrating the iteration technique, this is the way to go.
Your solution has exponential runtime: Every additional level spawns three evaluations, so you end up with O(3^n) operations and stack-memory.
The following is the idea
int first=1,second=1,third=1; /* if n<=3 then the respective is the answer */
for(i=4;i<=n;i++)
{
int next=first+2*second+third;
first=second;
second=third;
third=next;
}
cout<<"The answer is "<<next<<endl;
Memory is O(1) and time is O(n).
EDIT
Your recursive function is indeed exponential in time , to keep it linear you can make use
of an array F[n], and use memoization. First initialize F[] as -1.
int f_rec(int n)
{
if(n>=3)
{
if(F[n]!=-1)return F[n];
F[n]=f_rec(n-1)+2*f_rec(n-2)+f_rec(n-3);
return F[n];
}
else
return 1;
}
Just keep three variables and roll them over
start with a, b and c all equal to 1
at each step new_a is a + 2*b + c
roll over: new_c is b, new_b is a
repeat the required number of steps
A bit of an overkill, but this can be further optimized by letting the what the variables represent change in an unfolded loop, combined with (link) Duff's device to enter the loop:
int f_iter(int n){
int a=1, b=1, c=1;
if(n < 3)
return(1);
switch(n%3){
for( ; n > 2; n -= 3){
case 2:
b = c + 2*a + b;
case 1:
a = b + 2*c + a;
case 0:
c = a + 2*b + c;
}
}
return c;
}
A simple program I wrote in C takes upwards of half an hour to run. I am surprised that C would take so long to run, because from what I can find on the internet C ( aside from C++ or Java ) is one of the faster languages.
// this is a program to find the first triangular number that is divisible by 500 factors
int main()
{
int a; // for triangular num loop
int b = 1; // limit for triangular num (1+2+3+......+b)
int c; // factor counter
int d; // divisor
int e = 1; // ends loop
long long int t = 0; // triangular number in use
while( e != 0 )
{
c = 0;
// create triangular number t
t = t + b;
b++;
// printf("%lld\n", t); // in case you want to see where it's at
// counts factors
for( d = 1 ; d != t ; d++ )
{
if( t % d == 0 )
{
c++;
}
}
// test to see if condition is met
if( c > 500 )
{
break;
}
}
printf("%lld is the first triangular number with more than 500 factors\n", t);
getchar();
return 0;
}
Granted the program runs through a lot of data, but none of it is ever saved, just tested and passed over.
I am using the Tiny C Compiler on Windows 8.
Is there a reason this runs so slowly? What would be a faster way of achieving the same result?
Thank you!
You're iterating over a ton of numbers you don't need to. By definition, a positive factor is any whole number that can be multiplied by another to obtain the desired product.
Ex: 12 = 1*12, 2*6, and 3*4
The order of multiplication are NOT considered when deciding factors. In other words,
Ex: 12 = 2*6 = 6*2
The order doesn't matter. 2 and 6 are factors once.
The square root is the one singleton that will come out of a factoring of a product that stands alone. All others are in pairs, and I hope that is clear. Given that, you can significantly speed up your code by doing the following:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// this is a program to find the first triangular number that is divisible by 500 factors
int main()
{
int c = 0; // factor counter
long long int b = 0; // limit for triangular num (1+2+3+......+b)
long long int d; // divisor
long long int t = 0; // triangular number in use
long long int r = 0; // root of current test number
while (c <= 500)
{
c = 0;
// next triangular number
t += ++b;
// get closest root.
r = floor(sqrt(t));
// counts factors
for( d = 1 ; d < r; ++d )
{
if( t % d == 0 )
c += 2; // add the factor *pair* (there are two)
}
if (t % r == 0) // add the square root if it is applicable.
++c;
}
printf("%lld is the first triangular number with more than 500 factors\n", t);
return 0;
}
Running this on IDEOne.com takes less than two seconds to come up with the following:
Output
76576500 is the first triangular number with more than 500 factors
I hope this helps. (and I think that is the correct answer). There are certainly more efficient ways of doing this (see here for some spoilers if you're interested), but going with your code idea and seeing how far we could take it was the goal of this answer.
Finally, this finds the first number with MORE than 500 factors (i.e. 501 or more) as per your output message. Your comment at the top of the file indicates you're looking for the first number with 500-or-more, which does not match up with your output message.
Without any math analysis:
...
do
{
c = 0;
t += b;
b++;
for (d = 1; d < t; ++d)
{
if (!(t % d))
{
c++;
}
}
} while (c <= 500);
...
You are implementing an O(n^2) algorithm. It would be surprising if the code took less than a half an hour.
Refer to your computer science textbook for a better method compared to this brute force method of: check 1, 1 + 2, 1 + 2 + 3, etc.
You might be able to shorten the inner for loop. Does it really need to check all the way up to t for factors that divide the triangular number. For example, can 10 be evenly divisible by any number greater than 5? or 100 by any number greater than 50?
Thus, given a number N, what is the largest number that can evenly divide N?
Keep reading/researching this problem.
Also, as other people have mentioned, the outer loop could be simply coded as:
while (1)
{
// etc.
}
So, no need need to declare e, or a? Note, this doesn't affect the length of time, but your coding style indicates you are still learning and thus a reviewer would question everything your code does!!
You are doing some unnecessary operations, and I think those instructions are not at all required if we can check that simply.
first :
while(e!=0)
as you declared e=1, if you put only 1 in loop it will work. You are not updating value of e anywhere.
Change that and check whether it works fine or not.
One of the beautiful things about triangle numbers, is that if you have a triangle number, with a simple addition operation, you can have the next one.