I've written a program which calculates e and am working on a world record computation. How would I verify a computation with more decimal places than any other existing computation? How would I program that in C++/Python?
The main problem of precise calculations is to proove that your result is correct. in case of e if you say that your algorithm will print e with n decimal digits means that you can proove by means of mathematics that your number differs form the Euler number not more than by 10E-n.
In other words, before writing a program you have to develop an algorithm and proove it's correctness.
I do not see any usable Euler number identities which would enable you to quickly check the validity of your computation. In that case, I think that what you will have to live with is to check the first (millions) of decimal places against the known ground truth, and if it fits you will claim that your algorithm is working correctly. This is what is sometimes called "known cases" in the Unit testing frameworks.
You should copy suspectus' link into a .txt file and then write a program that uses fstream to compare each element digit by digit just to check if you've gotten the first 2 million decimals right. edit: I've written a program that would allow you to do that, edit the filename string so that it matches and have your algorithm put its numbers into the e_my_algorithm string.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
fstream in;
string filename = "C:\\Users\\Aaron\\Desktop\\TXT.txt";
string e_known;
string e_my_algorithm;
in.open(filename);
while(in.good())
{
e_known += in.get();
}
in.close();
auto itk = e_known.begin();
auto ite = e_my_algorithm.begin();
while(itk != e_known.end() - 1)
{
if(*itk++ != *ite++)
{
cout << "failure" << endl;
break;
}
}
return 0;
}
Beyond that you would need a background in mathematics to prove that your algorithm accurately approximates e to n digits. In particular you should study Real Analysis:
http://en.wikipedia.org/wiki/Real_analysis
The mathematical constant e is something the mathematics profession thoroughly understands so chances are any algorithm you come up with is already known to mathematicians. So you should probably just look for an existing method to approximate e and code that.
If you're really serious about it, check this out, apparently someone was able to break the world record on an overclocked desktop computer:
http://www.numberworld.org/misc_runs/e-500b.html
he used the taylor series expansion:
e = 1/(0!) + 1/1(!) + 1/(2!) + 1/(3!) + 1/(4!)...
Related
Ok so i have been learning binary search. My teacher has given me a problem on codeforces and it always fails on test 2. Here is the problem:
In this problem jury has some number x, and you have to guess it. The number x is always an integer from 1 and to n, where n
is given to you at the beginning.
You can make queries to the testing system. Each query is a single integer from 1
to n
. Flush output stream after printing each query. There are two different responses the testing program can provide:
the string "<" (without quotes), if the jury's number is less than the integer in your query;
the string ">=" (without quotes), if the jury's number is greater or equal to the integer in your query.
When your program guessed the number x
, print string "! x", where x
is the answer, and terminate your program normally immediately after flushing the output stream.
Your program is allowed to make no more than 25 queries (not including printing the answer) to the testing system.
Input
Use standard input to read the responses to the queries.
The first line contains an integer n
(1≤n≤pow(10,6) — maximum possible jury's number.
Following lines will contain responses to your queries — strings "<" or ">=". The i
-th line is a response to your i-th query. When your program will guess the number print "! x", where x
is the answer and terminate your program.
The testing system will allow you to read the response on the query only after your program print the query for the system and perform flush operation.
Output
To make the queries your program must use standard output.
Your program must print the queries — integer numbers xi
(1≤xi≤n), one query per line (do not forget "end of line" after each xi
). After printing each line your program must perform operation flush.
And here is my code:
#include <iostream>
using namespace std;
int main()
{
int n;
string s;
int k=0;
cin>>n;
int min=1,max=n;
int a;
while(k==0)
{
if(max==min+1)
{
cout<<"! "<<min;
k=1;
break;
}
a=(min+max)/2;
cout<<a<<endl;
cin>>s;
if(s==">=")
min=a;
else
max=a;
}
}
I dont know what test 2 is, but i would be happy to hear ideas as to where my programs is wrong. My guess is its something with the number of guesses. Thanks in advance!
I have tried variations of the loop written above, but they all give the same result.
I'm trying to write a program that alerts a user if a certain puppy owner has a puppy that is beyond a certain distance from the puppy owner.
Specifically, the following program:
first asks the user to input the location of the owner, namely inputting 2 integers a and b.
then asks the user to input the number of puppies the owner has. This is a positive integer n.
for each puppy i of the n puppies, the program asks the user to input the location of puppy i. This is 2 integers x and y, both of which are of course dependent on i.
If puppy i is calculated to have reached a distance greater than 10 units from its owner, then the program should inform the user by printing i.
Finally, the program should tell the user the total number of puppies whose numbers have been printed. This number is represented by the variable count, a positive integer.
The following is an example case
Inputs:
(Owner location) 2 1
(number puppies) 4
(location puppies) (15 15), (14 -2), (1 3), (0 4)
Outputs:
Puppy 1 and Puppy 2 too far away
Total 2 puppies too far away
When I try to run the program, the program outputs a question mark instead of the instead of the i's. What did I do wrong, please?
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main() {
string puppies;
int a,b;
cin>>a>>b;
int n;
cin>>n;
int i,x,y,count=0;
for (i=1;i<=n;i++){
cin>>x>>y;
int dist;
dist=abs(a-x)+abs(b-y);
if (dist>10){
count++;
puppies += i;
}
}
if (count==1){
cout<<"Puppy "<<puppies[0]<<" too far away"<<endl;
cout<<"Total "<< count <<" puppy too far away";
}
if (count>1){
int j;
for (j=0;j<=(count-2);j++){
cout<<"Puppy "<<puppies[j]<<" and"<<" ";
}
cout<<"Puppy "<<puppies[count-1]<<" too far away"<<endl;
cout<<"Total "<< count <<" puppies too far away";
}
if (count==0){
cout<<"No puppies too far away";
}
}
Here is the copied output (for the same case as above)
Puppy and Puppy too far away
Total 2 puppies too far awayPress any key to continue . . .
Here is a screenshot
enter image description here
You're trying to use a std::string as a container for numbers. It can do that for small enough ones, sure, but you'll probably want to switch to std::vector<int>.
The issue you're actually observing is that puppies[0] is a char, which in std::cout << puppies[0] is interpreted as a single text character, which in your case is a low codepoint corresponding to a non-printable character, hence the question mark displayed by your shell. You can fix it by converting explicitly with static_cast<int>(puppies[0]), but again using a suitable container for actual numbers would be more advisable.
puppies += i;
If you take a look at the overload set, you'll find that there is no overload for int. However, there is an overload for char. All integer types are implicitly convertible to other integer types, and in this case int is converted to char. The character that is appended to the string is the one which is represented by the integer value. What integer value represent what character depends on the character set that your system uses.
You may have intended to append the integer in a textual representation instead. You can convert an integer to a string for example using std::to_string.
That said, using string for this purpose seems backwards, as you don't appear to use it as a character string, but more like an array of integers. As such, a vector of integers might be a more sensible choice.
Input
The input begins with two positive integers n k (n, k<=10^7). The next n lines of input contain one positive integer ti, not greater than 10^9, each.
Output
Write a single integer to output, denoting how many integers ti are divisible by k.
Example
Input:
7 3
1
51
966369
7
9
999996
11
Output:
4
My Code:
#include <iostream>
using namespace std;
int main()
{
long long n,k, i;
cin>>n;
cin>>k;
int count=0;
for(i=0;i<n;i++)
{
int z;
cin>>z;
if(z%k == 0) count++;
}
cout<<count;
return 0;
}
Now this code produces the correct output. However, its not being accepted by CodeChef(http://www.codechef.com/problems/INTEST) for the following reason: Time Limit Exceeded. How can this be further optimized?
As said by caleb the problem is labeled "Enormous Input Test" so it requires you to use some better/faster I/O methods
just replacing cout with printf and cin with scanf will give you an AC but to improve your execution time you need to use some faster IO method for example reading character by character using getchar_unlocked() will give you a better execution time
so you can read the values by using a function like this , for a better execution time.
inline int read(){
char c=getchar_unlocked();
int n=0;
while(!(c>='0' && c<='9'))
c=getchar_unlocked();
while(c>='0' && c<='9'){
n=n*10 + (c-'0');
c=getchar_unlocked();
}
return n;
}
The linked problem contains the following description:
The purpose of this problem is to verify whether the method you are
using to read input data is sufficiently fast to handle problems
branded with the enormous Input/Output warning. You are expected to be
able to process at least 2.5MB of input data per second at runtime.
Considering that, reading values from input a few bytes at a time using iostreams isn't going to cut it. I googled around a bit and found a drop-in replacement for cin and cout described on CodeChef. Some other approaches you could try include using a memory-mapped file and using stdio.
It might also help to look for ways to optimize the calculation. For example, if ti < k, then you know that k is not a factor of ti. Depending on the magnitude of k and the distribution of ti values, that observation alone could save a lot of time.
Remember: the fact that your code is short doesn't mean that it's fast.
Is there a better way of doing this ?
http://projecteuler.net/problem=8
I added a condition to check if the number is >6 (Eliminates small products and 0's)
#include <iostream>
#include <math.h>
#include "bada.h"
using namespace std;
int main()
{
int badanum[] { DATA };
int pro=0,highest=0;
for(int i=0;i<=996;++i)
{
if (badanum[i]>6 and badanum[i+1] > 6 and badanum[i+2] >6 and badanum[i+3]>6 and badanum[i+4]>6)
{
pro=badanum[i]*badanum[i+1]*badanum[i+2]*badanum[i+3]*badanum[i+4];
if(pro>highest)
{
cout << pro << " " << badanum[i] << badanum[i+1] << badanum[i+2] << badanum[i+3] << badanum[i+4] << endl;
highest = pro;
}
pro = 0;
}
}
}
bada.h is just a file containing the 1000 digit number.
#DEFINE DATA <1000 digit number>
http://projecteuler.net/problem=8
that if slows things down actually
causes branching the parallel pipeline of CPU execution
also as mentioned before it will invalidate the result
does not matter that your solution is the same as it should be (for another digits it could not)
On algorithmic side you can do:
if you have fast enough division you can lower the computations number
char a[]="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450\0";
int i=0,s=0,m=1,q;
for (i=0;i<4;i++)
{
q=a[i ]-'0'; if (q) m*=q;
}
for (i=0;i<996;i++)
{
q=a[i+4]-'0'; if (q) m*=q;
if (s<m) s=m;
q=a[i ]-'0'; if (q) m/=q;
}
also you can do a table for mul,div operations for speed (but that is not faster in all cases)
int mul_5digits[9*9*9*9*9+1][10]={ 0*0,0*1,0*2, ... ,9*9*9*9*9/9 };
int div_5digits[9*9*9*9*9+1][10]={ 0/0,0/1,0/2, ... ,9*9*9*9*9/9 };
// so a=b*c; is rewritten by a=mul_5digits[b][c];
// so a=b/c; is rewritten by a=div_5digits[b][c];
of course instead of values 0*0 have to add neutral value = 1 !!!
of course instead of values i/0 have to add neutral value = i !!!
int i=0,s=0,t=1;
for (i=0;i<4;i++)
{
t=mul_5digits[t][a[i ]-'0'];
}
for (i=0;i<996;i++)
{
t=mul_5digits[t][a[i+4]-'0'];
if (s<t) s=t;
t=div_5digits[t][a[i ]-'0'];
}
Run-time measurements on AMD 3.2GHz, 64bit Win7, 32 bit App BDS2006 C++:
0.022ms classic approach
0.013ms single mul,div per step (produce false outut if there is none product > 0 present)
0.054ms tabled single mul,div per step (is slower for my setup)
PS.
All code improvements should be measured so you see if you actually speed thing up or not.
Because what is faster for one compiler/platform/computer can be slower for another.
Use at least 0.1 ms resolution.
I prefer the use of RDTSC or PerformanceCounter for that.
Except for the errors pointed out in the comments, that much multiplications aren´t necessary. If you start with the product of [0] * [1] * [2] * [3] * [4] for index 0, what would be the product starting at [1]? The old result divided by [0] and multiplied by [5]. One division and one multiplication could be faster than 4 multiplications
You don't need to store all the digits at once. Just current five of them (use an array with cyclic overwriting), one variable to store the current problem result and one to store the latest multiplication result(see below). If the number of digits in the input will grow you won't get any troubles with memory.
Also you could have the check if the oldest read digit equals zero. If it is, than you will really have to multiply all the five current digits, but if not - a better way will be to divide previous multiplication result by the oldest digit and multiply it by the latest read digit.
I am in the midst of solving a simple combination problem whose solution is 2^(n-1).
The only problem is 1 <= n <= 2^31 -1 (max value for signed 32 bit integer)
I tried using Java's BigInteger class but It times out for numbers 2^31/10^4 and greater, so that clearly doesn't work out.
Furthermore, I am limited to using only built-in classes for Java or C++.
Knowing I require speed, I chose to build a class in C++ which does arithmetic on strings.
Now, when I do multiplication, my program multiplies similarly to how we multiply on paper for efficiency (as opposed to repeatedly adding the strings).
But even with that in place, I can't multiply 2 by itself 2^31 - 1 times, it is just not efficient enough.
So I started reading texts on the problem and I came to the solution of...
2^n = 2^(n/2) * 2^(n/2) * 2^(n%2) (where / denotes integer division and % denotes modulus)
This means I can solve exponentiation in a logarithmic number of multiplications. But to me, I can't get around how to apply this method to my code? How do I choose a lower bound and what is the most efficient way to keep track of the various numbers that I need for my final multiplication?
If anyone has any knowledge on how to solve this problem, please elaborate (example code is appreciated).
UPDATE
Thanks to everyone for all your help! Clearly this problem is meant to be solved in a realistic way, but I did manage to outperform java.math.BigInteger with a power function that only performs ceil(log2(n)) iterations.
If anyone is interested in the code I've produced, here it is...
using namespace std;
bool m_greater_or_equal (string & a, string & b){ //is a greater than or equal to b?
if (a.length()!=b.length()){
return a.length()>b.length();
}
for (int i = 0;i<a.length();i++){
if (a[i]!=b[i]){
return a[i]>b[i];
}
}
return true;
}
string add (string& a, string& b){
if (!m_greater_or_equal(a,b)) return add(b,a);
string x = string(a.rbegin(),a.rend());
string y = string(b.rbegin(),b.rend());
string result = "";
for (int i = 0;i<x.length()-y.length()+1;i++){
y.push_back('0');
}
int carry = 0;
for (int i =0;i<x.length();i++){
char c = x[i]+y[i]+carry-'0'-'0';
carry = c/10;
c%=10;
result.push_back(c+'0');
}
if (carry==1) result.push_back('1');
return string(result.rbegin(),result.rend());
}
string multiply (string&a, string&b){
string row = b, tmp;
string result = "0";
for (int i = a.length()-1;i>=0;i--){
for (int j= 0;j<(a[i]-'0');j++){
tmp = add(result,row);
result = tmp;
}
row.push_back('0');
}
return result;
}
int counter = 0;
string m_pow (string&a, int exp){
counter++;
if(exp==1){
return a;
}
if (exp==0){
return "1";
}
string p = m_pow(a,exp/2);
string res;
if (exp%2==0){
res = "1"; //a^exp%2 is a^0 = 1
} else {
res = a; //a^exp%2 is a^1 = a
}
string x = multiply(p,p);
return multiply(x,res);
//return multiply(multiply(p,p),res); Doesn't work because multiply(p,p) is not const
}
int main(){
string x ="2";
cout<<m_pow(x,5000)<<endl<<endl;
cout<<counter<<endl;
return 0;
}
As mentioned by #Oli's answer, this is not a question of computing 2^n as that's trivially just a 1 followed by 0s in binary.
But since you want to print them out in decimal, this becomes a question of how to convert from binary to decimal for very large numbers.
My answer to that is that it's not realistic. (I hope this question just stems from curiosity.)
You mention trying to compute 2^(2^31 - 1) and printing that out in decimal. That number is 646,456,993 digits long.
Java BigInteger can't do it. It's meant for small numbers and uses O(n^2) algorithms.
As mentioned in the comments, there are no built-in BigNum libraries in C++.
Even Mathematica can't handle it: General::ovfl : Overflow occurred in computation.
Your best bet is to use the GMP library.
If you're just interested in seeing part of the answer:
2^(2^31 - 1) = 2^2147483647 =
880806525841981676603746574895920 ... 7925005662562914027527972323328
(total: 646,456,993 digits)
This was done using a close-sourced library and took roughly 37 seconds and 3.2 GB of memory on a Core i7 2600K # 4.4 GHz including the time needed to write all 646 million digits to a massive text file.
(It took notepad longer to open the file than needed to compute it.)
Now to answer your question of how to actually compute such a power in the general case, #dasblinkenlight has the answer to that which is a variant of Exponentiation by Squaring.
Converting from binary to decimal for large numbers is a much harder task. The standard algorithm here is Divide-and-Conquer conversion.
I do not recommend you try to implement the latter - as it's far beyond the scope of starting programmers. (and is also somewhat math-intensive)
You don't need to do any multiplication at all. 2^(n-1) is just 1 << (n-1), i.e. 1 followed by (n-1) zeros (in binary).
The easiest way to apply this method in your code is to apply it the most direct way - recursively. It works for any number a, not only for 2, so I wrote code that takes a as a parameter to make it more interesting:
MyBigInt pow(MyBigInt a, int p) {
if (!p) return MyBigInt.One;
MyBigInt halfPower = pow(a, p/2);
MyBigInt res = (p%2 == 0) ? MyBigInt.One : a;
return res * halfPower * halfPower;
}