I know there are many examples of this problem but I tried to write a different one myself.
This is using the Taylor series e^x = 1 + x/1! + x^2/2! + x^3/3! + ......
My code compiles and runs but it wont output the correct answer for some imputes and I'm not sure why. is this even usable code or should i scrap it?
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double final,power,end_n = 1.0,e=1.0,x=2.0, n;
cout<< "n: ";
// usually enter 5 for test
cin>> n;
while (n>1){
power = pow(x,n);
end_n = end_n*n;
e= (power/end_n)+e;
n--;
}
final =e+x;
cout<< final;
return 0;
}
I honestly have no idea what your reasoning is, at all. The code for that particular expansion is trivially simple:
double x;
cin >> x;
double oldres, res=1, top=1, bottom=1;
int iter=1;
do {
oldres=res; // to calculate the difference between iterations
++iter; // next iteration
top*=x; // multiply by one x for each iteration
bottom*=(iter-1); // multiply by the iteration number for each iteration
res+=top/bottom; // and add the fraction to the result
} while(fabs(res-oldres)>.1); // while the difference is still large
cout << res; // done, show the result
To be very clear about something that others are hinting at: if your loop counted up from 1 to n then end_n would equal n! at each step. But counting down, it doesn't. Look at the examples from 1 to 5:
Forwards
n | n!
1 | 1
2 | 2
3 | 6
4 | 24
5 | 120
Backwards
n | end_n
5 | 5
4 | 20
3 | 60
2 | 120
1 | 120
Since absolutely none of your denominators are right, it's a surprise if your code is only wrong for some inputs — in fact it's probably only correct for x=0.
Finally, I hope that this is just an exercise for learning. If you really need the value of e^x you should use exp(x).
I think you are close. Maybe you want something more like this:
#include <iostream>
#include <cmath>
using namespace std;
double factorial(long n)
{
double result = n;
while(--n) result*=n;
}
int main()
{
long n, power;
double final, e=1.0, x=2.0;
cout<< "n: ";
// usually enter 5 for test
cin>> n;
while (n>1)
{
power = pow((double)x, (double)n);
end_n = factorial(n);
e = (power/end_n)+e;
n--;
}
final = e+x;
cout<< final;
return 0;
}
You could actually employ a Horner-like scheme that uses the counting down in an essential manner
1 + x/1! + x^2/2! + x^3/3! + … + x^n/n! = (((((x/n+1)*x/(n-1)+1)*x/(n-2)+…)*x/1+1
e = 1.0;
while (n>0){
e = e*x/n + 1;
n--;
}
Compare the approximations of e^x and 1/(e^-x) for positive x for exactness.
Explore (e^(x/4))^4 for better exactness.
Related
I'm trying to solve Codewars task and facing issue that looks strange to me.
Codewars task is to write function digital_root(n) that sums digits of n until the end result has only 1 digit in it.
Example: 942 --> 9 + 4 + 2 = 15 --> 1 + 5 = 6 (the function returns 6).
I wrote some bulky code with supporting functions, please see code with notes below.
The problem - digital_root function works only if I put cout line in while loop. The function returns nonsense without this cout line (please see notes in the code of the function).
My questions are:
Why isn't digital_root working without cout line?
How cout line can effect the result of the function?
Why does cout line fix the code?
Thanks a lot in advance! I'm a beginner, spent several days trying to solve the issue.
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int getDigit (int, int);
int sumDigits (int);
int digital_root (int);
int main()
{
cout << digital_root (942); // expected output result is 6 because 9 + 4 + 2 = 15 -> 1 + 5 = 6
}
int getDigit (int inputNum, int position) // returns digit of inputNum that sits on a particular position (works)
{
int empoweredTen = pow(10, position-1);
return inputNum / empoweredTen % 10;
}
int sumDigits (int inputNum) // returns sum of digits of inputNum (works)
{
int sum;
int inLen = to_string(inputNum).length();
int i = inLen;
while (inLen --)
{
sum += getDigit(inputNum, i);
i --;
}
return sum;
}
int digital_root (int inputNum) // supposed to calculate sum of digits until number has 1 digit in it (abnormal behavior)
{
int n = inputNum;
while (n > 9)
{
n = sumDigits(n);
cout << "The current n is: " << n << endl; // !!! function doesn't work without this line !!!
}
return n;
}
I've tried to rewrite the code from scratch several times with Google to find a mistake but I can't see it. I expect digital_root() to work without any cout lines in it. Currently, if I delete cout line from while loop in digital_root(), the function returns -2147483647 after 13 seconds of calculations. Sad.
Here is an implementation using integer operators instead of calling std::to_string() and std::pow() functions - this actually works with floating-point numbers. It uses two integer variables, nSum and nRem, holding the running sum and remainder of the input number.
// calculates sum of digits until number has 1 digit in it
int digital_root(int inputNum)
{
while (inputNum > 9)
{
int nRem = inputNum, nSum = 0;
do // checking nRem after the loop avoids one comparison operation (1st check would always evaluate to true)
{
nSum += nRem % 10;
nRem /= 10;
} while (nRem > 9);
inputNum = nSum + nRem;
std::cout << "The current Sum is: " << inputNum << endl; // DEBUG - Please remove this
}
return inputNum;
}
As for the original code, the problem was the uninitialized sum variable, as already pointed out by other members - it even generates a compiler error.
int sumDigits (int inputNum) // returns sum of digits of inputNum (works)
{
int sum = 0; // MAKE SURE YOU INITIALIZE THIS TO 0 BEFORE ADDING VALUES TO IT!
int inLen = to_string(inputNum).length();
int i = inLen;
while (inLen --)
{
sum += getDigit(inputNum, i);
i --;
}
return sum;
}
Initialize your variables before adding values to them, otherwise you could run into undefined behaviour. Also for the record, adding the cout line printed out something, but it wasn't the correct answer.
I have this code here that should output all squared numbers before n. For example, if you type 10, it will show 1 4 9. The problem is, when I input 25, it should've given output 1 4 9 16 25. But, instead, it shows 1 4 9 16 24
#include <iostream>
using namespace std;
#include <cmath>
int main(){
int a, b;
cin >> a;
for(int i = 1; i <= a; i++)
{
b = pow(i,2);
if (b <= a) cout << b << " ";
}
return 0;
}
if you only use integers, and squared numbers you don't need any math library for the solution, you can get the square of a number by multiplying it to itself.
And you can have better performance if you break out of the loop when you reach the first square number that is bigger than your input number, no need to calculate any more.
example code:
#include <iostream>
int main()
{
int a;
std::cin >> a;
for (int b, i = 1;; ++i)
{
b = i * i;
if (b > a)
break;
std::cout << b << " ";
}
return 0;
}
Your problem is likely caused by the pow() function. While I was not able to reproduce this error (cmath in MinGW and Visual C++ uses std::pow that has integer overloads since C++98), I believe Your compiler uses the float overload for some reason. You should try replacing b = pow(i,2) with b = i * i.
I came across this problem in an Online contest and I'm trying to solve it using Disjoint Set Data-structure.
Problem Definition:
Bob visits a nuclear power plant during his school excursion. He observes that there are n nuclear rods in the plant and the initial efficiency of the nuclear rods is 1. After a period of time nuclear rods start fusing with each other and combine to form a group. This process reduces the efficiency of the nuclear rods to square root of the size of the group. Bob, being a curious student, wants to know the total efficiency of the nuclear plant after some time. This is obtained by adding the efficiencies of the groups.
Initially all the rods belong to its own group of size 1. There are f fusions. If rod1 and rod2 get fused, it means their groups got fused.
Sample Input:
5 2
1 2
2 3
Sample Output:
3.73
Explanation:
n=5 fusions=2
group 1,2,3 => 1.73 (sqrt(3))
group 4 => 1
group 5 => 1
total = (1.73 + 1 + 1) = 3.73
My code:
#include <iostream>
#include <set>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <iomanip>
using namespace std;
typedef long long int lli;
vector<lli> p,rank1,setSize; /* p keeps track of the parent
* rank1 keeps track of the rank
* setSize keeps track of the size of the set.
*/
lli findSet(lli i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
bool sameSet(lli x,lli y) { return findSet(x) == findSet(y); }
void union1(lli x,lli y) { // union merges two sets.
if(!sameSet(x,y)) {
lli i = findSet(x), j = findSet(y);
if(rank1[i] > rank1[j]) {
p[j] = i;
setSize[i] += setSize[j];
}
else {
p[i] = j;
setSize[j] += setSize[i];
if(rank1[i] == rank1[j])
rank1[j]++;
}
}
}
int main() {
freopen("input","r",stdin);
lli n;
cin >> n; //number of nuclear rods
setSize.assign(n,1); //Initialize the setSize with 1 because every element is in its own set
p.assign(n,0);
rank1.assign(n,0); //Initialize ranks with 0's.
for(lli i = 0; i < n; i++) p[i] = i; //Every set is distinct. Thus it is its own parent.
lli f;
cin >> f; //Number of fusions.
while(f--){
lli x,y;
cin >> x >> y; //combine two rods
union1(x,y);
}
double ans;
set<lli> s (p.begin(),p.end()); //Get the representative of all the sets.
for(lli i : s){
ans += sqrt(setSize[i]); //sum the sqrt of all the members of that set.
}
printf("\n%.2f", ans); //display the answer in 2 decimal places.
}
The above code seems to work for all testcases but one.
The input is here for which my code fails.
The expected output is : 67484.82
My output : 67912.32
I can't really work out where I went wrong since the input is really huge.
Any help would really be appreciated. Thanks in advance.
p holds the immediate parents of the elements and not their findSet values. Hence when you do set<lli> s (p.begin(),p.end()); you can have additional elements there.
There are two ways I can think of to deal with this:
Insert findSet(i) into the set with a loop instead of directly putting p
After you do setSize[i] += setSize[j], set setSize[j] = 0. This way, the intermediate parents will not contribute to the sum.
I have a square of side length 1 . Now, after each second, each square of side L will break into four squares each of side L/2.
I need the compute the total perimeter of the resulting figure, where total perimeter is defined as the sum of lengths of all line segments in the resulting figure. For example, the total perimeter of the image on the left is 4L while that on the right is 6L - 4L from the regular square edges and 2L from the internal line segments.
My code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define mod 1000000007
int main() {
int s;
cin>>s;
long long int ans=4;
for(int i=1;i<=s;i++)
ans+=1<<i;
ans=ans%mod;
cout<<ans<<endl;
return 0;
}
Since the final answer might not fit in a 64-bit signed integer, I am required to compute the answer modulo 1000000007.
For example, after 0 seconds, the length is 4.
After 1 second, the length is 6.
I am not getting the correct output. PLease help
Solve it recursively - let P(L, n) be the "perimeter" of the figure obtained after n iterations, starting with an LxL square. So, P(L, n+1) = 4*P(L/2,n) - 2*L. Also, since the perimeter is linear, P(L/2, n) = P(L, n)/2, giving you P(L,n) = 2*P(L,n-1) - 2*L. Substitute L=1 and run your loop.
int s;
cin>>s;
long long int ans=4;
for(int i=1;i<=s;i++)
{
ans = 2*(ans-1);
ans=ans%mod;
}
The perimeter after s seconds will be : 4+2(2^s-1)
So,
int main()
{
int s;
cout << "Enter Time: ";
cin >> s;
cout << "Perimeter = " << (4 + 2 * (pow( 2, s ) - 1));
}
You have an undivided square. When you split the square into 4 equal squares, you are essentially adding half of the initial perimeter. The outer walls of the original square are included as is in the new perimeter, and add to that the length of the 2 lines drawn inside it, the length of each of which is equal to the side of the square.
noOfsqaures = 1;
oldSide = 1; //one sqaure of side 1
oldPerimeter = 4*oldSide;
loop for the number of seconds
newPerimeter = oldPerimeter + 2*oldSide*noOfSquares
oldSide = oldSide/2; //for the next iteration
oldPermiter = newPermeter //for the next iteration
noOfSquares = noOfSquares*4;
o/p: 4(initial value) +
2 + 4 + 8 + 16 + 32 + ...
I think it would help you for coding. If you need I will give you code
for(int i=1;i<=s;i++)
{
ans+=1<<i;
}
Project Euler problem 1 is: Find the sum of all the multiples of 3 or 5 below 1000
Here is my program, using two simple functions to work out the sum of all the multiples of 3 and all the multiples of 5 and then add them up:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
int threeSum( void );
int fiveSum( void );
int main( int argc, char** argv )
{
cout << "\n The sum of all the natural numbers below 1000 that are multiples of 3 or 5 = \n" << endl;
cout << threeSum() + fiveSum() << endl << endl;
system( "PAUSE" );
}
int threeSum( void )
{
int sumSoFar = 0;
for ( int i = 1 ; i < 1000 ; i++ )
{
if ( i % 3 == 0 )
sumSoFar = sumSoFar + i;
}
return sumSoFar;
}
int fiveSum( void )
{
int sumSoFar = 0;
for ( int i = 1 ; i < 1000 ; i++ )
{
if ( i % 5 == 0 )
sumSoFar = sumSoFar + i;
}
return sumSoFar;
}
which produces 266333 as the answer. Is this correct, or am I doing something wrong, as the website checker says this is the wrong answer!
Another way of seeing this is:
answer = (sum of multiplies of 3) + (sum of multiplies of 5) - (sum of multiples of 15)
these are simple arithmetic series so you don't even need loops.
You are summing up with all the multiples of 15. This is an easy mathematical problem:
In the case of 15, since it is dividable by both 3 and 5, you are counting it twice in both of the functions.
I suggest that you can use one single loop and ||. Of course, a single formula would be better, but that's just mathy, I doubt you will like it:)
BTW, Project Euler is more math/computer science than pure programming, so when in doubt, try to think in a mathy way:)
As most others pointed out, you're summing the multiples of 15 twice.
Just a hint for another solution:
The sum of multiples of 3 below 1000 is
SUMBELOW(3,1000) = 3 + 6 + 9 + ... + 999 = 3*(1+2+3+...+333) = 3*333*(1+333)/2 = 3*((1000-1)/3)*(1+(1000-1)/3)/2
(All divisions are integer divisions...)
There are similar formulas for calculating the sums of multiples of 5 and 15. To get the overall result, you have to add the sums for 3 and 5 and subtract the sum for 15...
Your solution does not take into account the fact that some numbers (like 15) are divisible by both 5 and 3. You are adding them twice in your sum.
My guess is you're double counting the common multiples of 3 and 5.
This is the best answer and the easiest I could do:
{
int sum ;
for (int i=1;i<1000;i++){
if (i%3==0 || i%5==0) sum+=i;
}
cout<<sum;
}