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.
Related
I'm very new to C++ programming, and have written a simple program to calculate the factorial of an integer provided by the user. I am attempting to account for inputs which would cause an error, or do not make sense (e.g. I have accounted for input of a negative number/-1 already). I want to print out an error if the user enters a number whose factorial would be larger than the maximum integer size.
I started with:
if(factorial(n) > INT_MAX)
std::cout << "nope";
continue
I tested this with n = ~25 or 26 but it doesn't prevent the result from overflowing and printing out a large negative number instead.
Second, I tried assigning this to a variable using a function from the 'limits.h' header and then comparing the result of factorial(n) against this. Still no luck (you can see this solution in the code sample below).
I could of course assign the result to a long and test against that but you wouldn't have to go very far until you started to wrap around that value, either. I'd prefer to find a way to simply prevent the value from being printed if this happens.
#include <iostream>
#include <cstdlib>
#include <limits>
int factorial(int n)
{
auto total = 1;
for(auto i = 1; i <= n; i++)
{
total = total * i; //Product of all numbers up to n
}
return total;
}
int main()
{
auto input_toggle = true;
auto n = 0;
auto int_max_size = std::numeric_limits<int>::max();
while(input_toggle = true)
{
/* get user input, check it is an integer */
if (factorial(n) > int_max_size)
{
std::cout << "Error - Sorry, factorial of " << n << " is larger than \nthe maximum integer size supported by this system. " << std::endl;
continue;
}
/* else std::cout << factorial(n) << std::endl; */`
As with my other condition(s), I expect it to simply print out that small error message and then continue asking the user for input to calculate. The code does work, it just continues to print values that have wrapped around if I request the factorial of a value >25 or so. I feel this kind of error-checking will be quite useful.
Thanks!
You are trying to do things backwards.
First, no integer can actually be bigger than INT_MAX, by definition - this is a maximum value integer can be! So your condition factorial(n) > int_max_size is always going to be false.
Moreover, there is a logical flaw in your approach. You calculate the value first and than check if it is less than maximum value allowed. By that time it is too late! You have already calculated the value and went through any overflows you might have encountered. Any check you might be performing should be performed while you are still doing your calculations.
In essence, you need to check if multiplying X by Z will be within allowed range without actually doing the multiplication (unfortunately, C++ is very strict in leaving signed integer overflow undefined behavior, so you can't try and see.).
So how do you check if X * Y will be lesser than Z? One approach would be to divide Z by Y before engaging in calculation. If you end up with the number which is lesser than X, you know that multiplying X by Y will result in overflow.
I believe, you know have enough information to code the solution yourself.
I am new c++ learner.I logged in Codeforces site and it is 11A question:
A sequence a0, a1, ..., at - 1 is called increasing if ai - 1 < ai for each i: 0 < i < t.
You are given a sequence b0, b1, ..., bn - 1 and a positive integer d. In each move you may choose one element of the given sequence and add d to it. What is the least number of moves required to make the given sequence increasing?
Input
The first line of the input contains two integer numbers n and d (2 ≤ n ≤ 2000, 1 ≤ d ≤ 106). The second line contains space separated sequence b0, b1, ..., bn - 1 (1 ≤ bi ≤ 106).
Output the minimal number of moves needed to make the sequence increasing.
I write this code for this question:
#include <iostream>
using namespace std;
int main()
{
long long int n,d,ci,i,s;
s=0;
cin>>n>>d;
int a[n];
for(ci=0;ci<n;ci++)
{
cin>>a[ci];
}
for(i=0;i<(n-1);i++)
{
while(a[i]>=a[i+1])
{
a[i+1]+=d;
s+=1;
}
}
cout<<s;
return 0;
}
It work good.But In a test codeforces server enter 2000 number.Time limit is 1 second.But it calculate up to 1 second.
How to make this code shorter to calculate faster?
One improvement that can be made is to use
std::ios_base::sync_with_stdio(false);
By default, cin/cout waste time synchronizing themselves with the C library’s stdio buffers, so that you can freely intermix calls to scanf/printf with operations on cin/cout. By turning this off using the above call the input and output operations in the above program should take less time since it no longer initialises the sync for input and output.
This is know to have helped in previous code challenges that require code to be completed in a certain time scale and which the c++ input/output was causing some bottleneck in the speed.
You can get rid of the while loop. Your program should run faster without
#include <iostream>
using namespace std;
int main()
{
long int n,d,ci,i,s;
s=0;
cin>>n>>d;
int a[n];
for(ci=0;ci<n;ci++)
{
cin>>a[ci];
}
for(i=0;i<(n-1);i++)
{
if(a[i]>=a[i+1])
{
int x = ((a[i] - a[i+1])/d) + 1;
s+=x;
a[i+1]+=x*d;
}
}
cout<<s;
return 0;
}
This is not a complete answer, but a hint.
Suppose our seqence is {1000000, 1} and d is 2.
To make an increasing sequence, we need to make the second element 1,000,001 or greater.
We could do it your way, by repeatedly adding 2 until we get past 1,000,000
1 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + ...
which would take a while, or we could say
Our goal is 1,000,001
We have 1
The difference is 1,000,000
So we need to to do 1,000,000 / 2 = 500,000 additions
So the answer is 500,000.
Which is quite a bit faster, because we only did 1 addition (1,000,000 + 1), one subtraction (1,000,001 - 1) and one division (1,000,000 / 2) instead of doing half a million additions.
Just as #molbdnilo said, Use math to get rid of the loop, and it's simple.
Here is my code, accepted on Codeforces.
#include <iostream>
using namespace std;
int main()
{
int n = 0 , b = 0;
int a[2001];
cin >> n >> b;
for(int i = 0 ; i < n ; i++){
cin >> a[i];
}
int sum = 0;
for(int i = 0 ; i < n - 1 ; i++){
if(a[i] >= a[i + 1]){
int minus = a[i] - a[i+1];
int diff = minus / b + 1;
a[i+1] += diff * b;
sum += diff;
}
}
cout << sum << endl;
return 0;
}
I suggest you profile your code to see where the bottlenecks are.
One of the popular areas of time wasting is with input. The fewer input requests, the faster your program will be.
So, you could speed up your program by reading from cin using read() into a buffer and then parse the buffer using istringstream.
Other techniques include loop unrolling and optimizing for data cache. Reducing the number of branches or if statements will also speed up your programs. Processor prefer crunching data and moving data around to jumping to different areas in the code.
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.
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!)...
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;
}