Mod of two large numbers in C++ - c++

I have a class named LargeNum, which stores large numbers by array such as digit[]. Because int is not large enough to store it.
The base is 10000, so number '9876 8764 7263' is stored like:
digit[4] = {9876, 8764, 7263};
(the base can be changed into 10 or 100, like digit[12] = {9,8,7,6,8,7,6,4,7,2,6,3})
The problem is that I want to overload operator %, so than I can get the remainder of two large numbers. Overloading operator *, - between large numbers is finished by dealing with every digit of the large number. But I really don't how to do so with %. Like:
{1234,7890,1234} % {4567,0023}
Can anyone help me?

The pseudocode should be:
while digits_source > digits_base {
while first_digit_source > first_digit_base {
source -= base << (digits_source - digits_base)
}
second_digit_source += first_digit_source * LargeNum.base
first_digit_source = 0
digits_source--
}
while (source >= base) {
source -= base
}
return source
This should take advantage of your "digits" of the large number.
Edit: For simplicity, I am assuming that a single digit of you array can contain (numerically speaking) two digits. If it cannot, then the code would become quite tricky because you cannot do second_digit_source += first_digit_source * LargeNum.base
Edit:
Regarding an example operation (base = 10000)
{65,0000,0099} % {32,0001}
As 65 is > 32, then proceed to do:
65 - 32 = 33
0 - 1 = -1
Then we have {33, -1, 99} % {32, 1}. Proceed again
33 - 32 = 1
-1 - 1 = -2
We have {1, -2, 99} % {32, 1}. Because 32 > 1, the we join the two first digits of the source and we have {1*1000 - 2, 99} % {32, 1}. Now we can go into the simple while, simply by doing the minus operation. The while does a full comparison of source >= base because we cannot afford to have negative digits. However, during the first part of the algorithm we can because we are guaranteeing that the combination of the two first digits will be positive.

Related

find the minimum lucky number that has the sum of digits equal to N

The lucky numbers are the positive integers whose decimal representations contain only the digits 4 or 7 .enter code here`
For example, numbers 47 , 474 , 4 are lucky and 3 , 13 , 567 are not
if there is no such no then output should -1.
input is sum of digits.
i have written this code:
int main(){
long long int s,no=0,minimum=999999999999999999999;
cin>>s;
for(int i=0; i<=s; i++){
for(int j=0; j<=s; j++){
if(i*4+j*7==s){no=0;
for(int k=0; k<i; k++){
no=no*10+4;
}
for(int l=0; l<j; l++){
no=no*10+7;
}if(no<minimum){
minimum=no;}
}
}
}if(minimum==999999999999999999999){cout<<-1;}
else {cout<<minimum;}
}
it is working fine smaller sum values but input is large then no formed is large due to which i am not able to compare them, the constraints for sum is 1<=n<=10^6
This answer shows a process, one of refinement to develop an efficient solution. The most efficient answer can be found in the paragraphs at the bottom, starting with the text "Of course, you can be even more clever ...".
I've left the entire process in so you can understand the sort of thinking that goes into algorithm development. So, let's begin.
First, I wouldn't, in this case, try to compare large numbers, it's totally unnecessary and limits the sort of ranges you want to handle. Instead, you simply have some number of fours and some number of sevens, which you can easily turn into a sum with:
sum = numFours * 4 + numSevens * 7
In addition, realising that the smallest number is, first and foremost, the one with the least number of digits, you want the absolute minimum number of fours and maximum number of sevens. So start with no fours and as many sevens as needed until you're at or just beyond the required sum.
Then, as long as you're not at the sum, perform the following mutually exclusive steps:
If you're over the desired sum, take away a seven if possible. If there are no sevens to take away, you're done, and there's no solution. Log that fact and exit.
Otherwise (i.e., if you're under the sum), add a four.
At this point, you will have a solution (no solution possible means that you would have already performed an exit in the first bullet point above).
Hence you now have a count of the fours and sevens that sum to the desired number, so the lowest number will be the one with all the fours at the left (for example 447 is less than any of {474, 744}). Output that, and you're done.
By doing it this way, the limitation (say, for example, an unsigned 32-bit int) is no longer the number you use (about four billion, so nine digits), instead it is whatever number of fours you can hold in four billion (about a billion digits).
That's an increase of about 11 billion percent, hopefully enough of an improvement for you, well beyond the 106 maximum sum specified.
In reality, you won't get that many fours since any group of seven fours can always be replaced with four sevens, giving a smaller number (a7777b will always be less than a4444444b, where a is zero or more fours and b is zero or more sevens, same counts in both numbers), so the maximum count of fours will always be six.
Here's some pseudo-code (Python code, actually) to show it in action. I've chosen Python, even though you stated C++, for the following reasons:
This is almost certainly an educational question (there's very little call for this sort of program in the real world). That means you're better off doing the heavy lifting of writing the code yourself, to ensure you understand and also to ensure you don't fail for just copying code off the net.
Python is the most awesome pseudo-code language ever. It can easily read like normal English pseudo-code but has the added benefit that a computer can actually run it for testing and validation purposes :-)
The Python code is:
import sys
# Get desired sum from command line, with default.
try:
desiredSum = int(sys.argv[1])
except:
desiredSum = 22
# Init sevens to get at or beyond sum, fours to zero, and the sum.
(numSevens, numFours) = ((desiredSum + 6) // 7, 0)
thisSum = numSevens * 7 + numFours * 4
# Continue until a solution is found.
while thisSum != desiredSum:
if thisSum > desiredSum:
# Too high, remove a seven. If that's not possible, exit.
if numSevens == 0:
print(f"{desiredSum}: no solution")
sys.exit(0)
numSevens -= 1
thisSum -= 7
else:
# Too low, add a four.
numFours += 1
thisSum += 4
# Only get here if solution found, so print lowest
# possible number that matches four/seven count.
print(f"{desiredSum}: answer is {'4' * numFours}{'7' * numSevens}")
And here's a transcript of it in action for a small sample range:
pax:~> for i in {11..20} ; do ./test47.py ${i} ; done
11: answer is 47
12: answer is 444
13: no solution
14: answer is 77
15: answer is 447
16: answer is 4444
17: no solution
18: answer is 477
19: answer is 4447
20: answer is 44444
And here's the (rough) digit count for a desired sum of four billion, well over half a billion digits:
pax:~> export LC_NUMERIC=en_US.UTF8
pax:~> printf "%'.f\n" $(./test47.py 4000000000 | wc -c)
571,428,597
If you really need a C++ solution, see below. I wouldn't advise using this if this is course-work, instead suggesting you convert the algorithm shown above into your own code (for reasons previously mentioned). This is provided just to show the similar approach in C++:
#include <iostream>
int main(int argc, char *argv[]) {
// Get desired sum from command line, defaulting to 22.
int desiredSum = 22;
if (argc >= 2) desiredSum = atoi(argv[1]);
// Init sevens to get at or beyond desired sum, fours to zero,
// and the sum based on that.
int numSevens = (desiredSum + 6) / 7, numFours = 0;
int thisSum = numSevens * 7 + numFours * 4;
// Continue until a solution is found.
while (thisSum != desiredSum) {
if (thisSum > desiredSum) {
// Too high, remove a seven if possible, exit if not.
if (numSevens == 0) {
std::cout << desiredSum << ": no solution\n";
return 0;
}
--numSevens; thisSum -= 7;
} else {
// Too low, add a four.
++numFours; thisSum += 4;
}
}
// Only get here if solution found, so print lowest
// possible number that matches four / seven count.
std::cout << desiredSum << ": answer is ";
while (numFours-- > 0) std::cout << 4;
while (numSevens-- > 0) std::cout << 7;
std::cout << '\n';
}
Of course, you can be even more clever when you realise that the maximum number of fours will be six, and that you can add one to the sum-of-digits by removing one seven and adding two fours.
So simply:
work out the number of sevens required to get at or just below the desired sum;
add a single four if that will still keep you at or below the desired sum;
then adjust by enough actions of "remove one seven and add two fours" until you get to that desired sum (keeping in mind you may already be there). This will be done exactly once for each unit the shortfall in your current sum (how far it is below the desired sum) so, if the shortfall was two, you would remove two sevens and add four fours (- 14 + 16 = 2). That means you can use a simple mathematical formula rather than a loop.
if that formula results in a negative count of sevens, there was no solution, otherwise use the counts as previously mentioned to form the lowest number (fours followed by sevens).
Just Python for this solution, given how easy it is:
import sys
# Get desired number.
desiredNum = int(sys.argv[1])
# Work out seven and four counts as per description in text.
numSevens = int(desiredNum / 7) # Now within six of desired sum.
shortFall = desiredNum - (numSevens * 7)
numFours = int(shortFall / 4) # Now within three of desired sum.
shortFall = shortFall - numFours * 4
# Do enough '+7-4-4's to reach desired sum (none if already there).
numSevens = numSevens - shortFall
numFours = numFours + shortFall * 2
# Done, output solution, if any.
if numSevens < 0:
print(f"{desiredNum}: No solution")
else:
print(f"{desiredNum}: {'4' * numFours}{'7' * numSevens}")
That way, no loop is required at all. It's all mathematical reasoning.
If I understand the question correctly, you are searching for the smallest number x which contains only the numbers 4 and 7 and the sum of its digits N. The smallest number is for sure written as:
4...47...7
and consists of m times 4 and n times 7. So we know that N = n · 4 + m · 7.
Here are a couple of rules that apply:
(n + m) · 7 ≥ N :: This is evident, just replace all 4's by 7's.
(n + m) · 4 ≤ N :: This is evident, just replace all 7's by 4's.
(n + m) · 7 − N = m · (7 − 4) :: in other words (m+n) · 7 − N needs to be divisible by 7 − 4
So with these two conditions, we can now write the pseudo-code very quickly:
# always assume integer division
j = N/7 # j resembles n+m (total digits)
if (N*7 < N) j++ # ensure rule 1
while ( (j*4 <= N) AND ((j*7 - N)%(7-4) != 0) ) j++ # ensure rule 2 and rule 3
m = (j*7 - N)/(7-4) # integer division
n = j-m
if (m>=0 AND n>=0 AND N==m*4 + n*7) result found
Here is a quick bash-awk implementation:
$ for N in {1..30}; do
awk -v N=$N '
BEGIN{ j=int(N/7) + (N%7>0);
while( j*4<=N && (j*7-N)%3) j++;
m=int((j*7-N)/3); n=j-m;
s="no solution";
if (m>=0 && n>=0 && m*4+n*7==N) {
s=""; for(i=1;i<=j;++i) s=s sprintf("%d",(i<=m?4:7))
}
print N,s
}'
done
1 no solution
2 no solution
3 no solution
4 4
5 no solution
6 no solution
7 7
8 44
9 no solution
10 no solution
11 47
12 444
13 no solution
14 77
15 447
16 4444
17 no solution
18 477
19 4447
20 44444
21 777
22 4477
23 44447
24 444444
25 4777
26 44477
27 444447
28 7777
29 44777
30 444477
The constraints for sum are 1 ≤ n ≤ 106
It means that you might have to find and print numbers with more than 105 digits (106 / 7 ≅ 142,857). You can't store those in a fixed-sized integral type like long long, it's better to directly generate them as std::strings composed by only 4 and 7 characters.
Some mathematical properties may help in finding a suitable algorithm.
We know that n = i * 4 + j * 7.
Of all the possible numbers generated by each combination of i digits four and j digits seven, the minimum is the one with all the fours at left of all the sevens. E.g. 44777 < 47477 < 47747 < ... < 77744.
The minimal lucky number has at max six 4 digits, because, even if the sum of their digits is equal, 4444444 > 7777.
Now, let's introduce s = n / 7 (integer division) and r = n % 7 (the remainder).
If n is divisible by 7 (or when r == 0), the lucky number is composed only by exactly s digits (all 7).
If the remainder is not zero, we need to introduce some 4. Note that
If r == 4, we can just put a single 4 at the left of s sevens
Every time we substitute (if we can) a single 7 with two 4s, the sum of the digits increases by 1.
We can calculate exactly how many 4 digits we need (6 at max) without a loop.
This is enough to write an algorithm.
#include <string>
struct lucky_t
{
long fours, sevens;
};
// Find the minimum lucky number (composed by only 4 and 7 digits)
// that has the sum of digits equal to n.
// Returns it as a string, if exists, otherwise return "-1".
std::string minimum_lucky(long n)
{
auto const digits = [multiples = n / 7L, remainder = n % 7L] {
return remainder > 3
? lucky_t{remainder * 2 - 7, multiples - remainder + 4}
: lucky_t{remainder * 2, multiples - remainder};
} ();
if ( digits.fours < 0 || digits.sevens < 0 )
{
return "-1";
}
else
{
std::string result(digits.fours, '4');
result.append(digits.sevens, '7');
return result;
}
}
Tested here.

Time optimize C++ function to find number of decoding possibilities

This is an interview practice problem from CodeFights. I have a solution that's working except for the fact that it takes too long to run for very large inputs.
Problem Description (from the link above)
A top secret message containing uppercase letters from 'A' to 'Z' has been encoded as numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
You are an FBI agent and you need to determine the total number of ways that the message can be decoded.
Since the answer could be very large, take it modulo 10^9 + 7.
Example
For message = "123", the output should be
mapDecoding(message) = 3.
"123" can be decoded as "ABC" (1 2 3), "LC" (12 3) or "AW" (1 23), so the total number of ways is 3.
Input/Output
[time limit] 500ms (cpp)
[input] string message
A string containing only digits.
Guaranteed constraints:
0 ≤ message.length ≤ 105.
[output] integer
The total number of ways to decode the given message.
My Solution so far
We have to implement the solution in a function int mapDecoding(std::string message), so my entire solution is as follows:
/*0*/ void countValidPaths(int stIx, int endIx, std::string message, long *numPaths)
/*1*/ {
/*2*/ //check out-of-bounds error
/*3*/ if (endIx >= message.length())
/*4*/ return;
/*5*/
/*6*/ int subNum = 0, curCharNum;
/*7*/ //convert substr to int
/*8*/ for (int i = stIx; i <= endIx; ++i)
/*9*/ {
/*10*/ curCharNum = message[i] - '0';
/*11*/ subNum = subNum * 10 + curCharNum;
/*12*/ }
/*13*/
/*14*/ //check for leading 0 in two-digit number, which would not be valid
/*15*/ if (endIx > stIx && subNum < 10)
/*16*/ return;
/*17*/
/*18*/ //if number is valid
/*19*/ if (subNum <= 26 && subNum >= 1)
/*20*/ {
/*21*/ //we've reached the end of the string with success, therefore return a 1
/*22*/ if (endIx == (message.length() - 1) )
/*23*/ ++(*numPaths);
/*24*/ //branch out into the next 1- and 2-digit combos
/*25*/ else if (endIx == stIx)
/*26*/ {
/*27*/ countValidPaths(stIx, endIx + 1, message, numPaths);
/*28*/ countValidPaths(stIx + 1, endIx + 1, message, numPaths);
/*29*/ }
/*30*/ //proceed to the next digit
/*31*/ else
/*32*/ countValidPaths(endIx + 1, endIx + 1, message, numPaths);
/*33*/ }
/*34*/ }
/*35*/
/*36*/ int mapDecoding(std::string message)
/*37*/ {
/*38*/ if (message == "")
/*39*/ return 1;
/*40*/ long numPaths = 0;
/*41*/ int modByThis = static_cast<int>(std::pow(10.0, 9.0) + 7);
/*42*/ countValidPaths(0, 0, message, &numPaths);
/*43*/ return static_cast<int> (numPaths % modByThis);
/*44*/ }
The Issue
I have passed 11/12 of CodeFight's initial test cases, e.g. mapDecoding("123") = 3 and mapDecoding("11115112112") = 104. However, the last test case has message = "1221112111122221211221221212212212111221222212122221222112122212121212221212122221211112212212211211", and my program takes too long to execute:
Expected_output: 782204094
My_program_output: <empty due to timeout>
I wrote countValidPaths() as a recursive function, and its recursive calls are on lines 27, 28 and 32. I can see how such a large input would cause the code to take so long, but I'm racking my brain trying to figure out what more efficient solutions would cover all possible combinations.
Thus the million dollar question: what suggestions do you have to optimize my current program so that it runs in far less time?
A couple of suggestions.
First this problem can probably be formulated as a Dynamic Programming problem. It has that smell to me. You are computing the same thing over and over again.
The second is the insight that long contiguous sequences of "1"s and "2"s are a Fibonacci sequence in terms of the number of possibilities. Any other value terminates the sequence. So you can split the strings into runs of of ones and twos terminated by any other number. You will need special logic for a termination of zero since it does not also correspond to a character. So split the strings count, the length of each segment, look up the fibonacci number (which can be pre-computed) and multiply the values. So your example "11115112112" yields "11115" and "112112" and f(5) = 8 and f(6) = 13, 8*13 = 104.
Your long string is a sequence of 1's and 2's that is 100 digits long. The following Java (Sorry, my C++ is rusty) program correctly computes its value by this method
public class FibPaths {
private static final int MAX_LEN = 105;
private static final BigInteger MOD_CONST = new BigInteger("1000000007");
private static BigInteger[] fibNum = new BigInteger[MAX_LEN];
private static void computeFibNums() {
fibNum[0] = new BigInteger("1");
fibNum[1] = new BigInteger("1");
for (int i = 2; i < MAX_LEN; i++) {
fibNum[i] = fibNum[i-2].add(fibNum[i-1]);
}
}
public static void main(String[] argv) {
String x = "1221112111122221211221221212212212111221222212122221222112122212121212221212122221211112212212211211";
computeFibNums();
BigInteger val = fibNum[x.length()].mod(MOD_CONST);
System.out.println("N=" + x.length() + " , val = " + val);
}
}

How to store output of very large Fibonacci number?

I am making a program for nth Fibonacci number. I made the following program using recursion and memoization.
The main problem is that the value of n can go up to 10000 which means that the Fibonacci number of 10000 would be more than 2000 digit long.
With a little bit of googling, I found that i could use arrays and store every digit of the solution in an element of the array but I am still not able to figure out how to implement this approach with my program.
#include<iostream>
using namespace std;
long long int memo[101000];
long long int n;
long long int fib(long long int n)
{
if(n==1 || n==2)
return 1;
if(memo[n]!=0)
return memo[n];
return memo[n] = fib(n-1) + fib(n-2);
}
int main()
{
cin>>n;
long long int ans = fib(n);
cout<<ans;
}
How do I implement that approach or if there is another method that can be used to achieve such large values?
One thing that I think should be pointed out is there's other ways to implement fib that are much easier for something like C++ to compute
consider the following pseudo code
function fib (n) {
let a = 0, b = 1, _;
while (n > 0) {
_ = a;
a = b;
b = b + _;
n = n - 1;
}
return a;
}
This doesn't require memoisation and you don't have to be concerned about blowing up your stack with too many recursive calls. Recursion is a really powerful looping construct but it's one of those fubu things that's best left to langs like Lisp, Scheme, Kotlin, Lua (and a few others) that support it so elegantly.
That's not to say tail call elimination is impossible in C++, but unless you're doing something to optimise/compile for it explicitly, I'm doubtful that whatever compiler you're using would support it by default.
As for computing the exceptionally large numbers, you'll have to either get creative doing adding The Hard Way or rely upon an arbitrary precision arithmetic library like GMP. I'm sure there's other libs for this too.
Adding The Hard Way™
Remember how you used to add big numbers when you were a little tater tot, fresh off the aluminum foil?
5-year-old math
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
Well you gotta add each column, right to left. And when a column overflows into the double digits, remember to carry that 1 over to the next column.
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
The 10,000th fibonacci number is thousands of digits long, so there's no way that's going to fit in any integer C++ provides out of the box. So without relying upon a library, you could use a string or an array of single-digit numbers. To output the final number, you'll have to convert it to a string tho.
(woflram alpha: fibonacci 10000)
Doing it this way, you'll perform a couple million single-digit additions; it might take a while, but it should be a breeze for any modern computer to handle. Time to get to work !
Here's an example in of a Bignum module in JavaScript
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
We can verify that the Wolfram Alpha answer above is correct
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
bigfib (10000)
// "336447 ... 366875"
Expand the program below to run it in your browser
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
console.log (bigfib (10000))
Try not to use recursion for a simple problem like fibonacci. And if you'll only use it once, don't use an array to store all results. An array of 2 elements containing the 2 previous fibonacci numbers will be enough. In each step, you then only have to sum up those 2 numbers. How can you save 2 consecutive fibonacci numbers? Well, you know that when you have 2 consecutive integers one is even and one is odd. So you can use that property to know where to get/place a fibonacci number: for fib(i), if i is even (i%2 is 0) place it in the first element of the array (index 0), else (i%2 is then 1) place it in the second element(index 1). Why can you just place it there? Well when you're calculating fib(i), the value that is on the place fib(i) should go is fib(i-2) (because (i-2)%2 is the same as i%2). But you won't need fib(i-2) any more: fib(i+1) only needs fib(i-1)(that's still in the array) and fib(i)(that just got inserted in the array).
So you could replace the recursion calls with a for loop like this:
int fibonacci(int n){
if( n <= 0){
return 0;
}
int previous[] = {0, 1}; // start with fib(0) and fib(1)
for(int i = 2; i <= n; ++i){
// modulo can be implemented with bit operations(much faster): i % 2 = i & 1
previous[i&1] += previous[(i-1)&1]; //shorter way to say: previous[i&1] = previous[i&1] + previous[(i-1)&1]
}
//Result is in previous[n&1]
return previous[n&1];
}
Recursion is actually discommanded while programming because of the time(function calls) and ressources(stack) it consumes. So each time you use recursion, try to replace it with a loop and a stack with simple pop/push operations if needed to save the "current position" (in c++ one can use a vector). In the case of the fibonacci, the stack isn't even needed but if you are iterating over a tree datastructure for example you'll need a stack (depends on the implementation though). As I was looking for my solution, I saw #naomik provided a solution with the while loop. That one is fine too, but I prefer the array with the modulo operation (a bit shorter).
Now concerning the problem of the size long long int has, it can be solved by using external libraries that implement operations for big numbers (like the GMP library or Boost.multiprecision). But you could also create your own version of a BigInteger-like class from Java and implement the basic operations like the one I have. I've only implemented the addition in my example (try to implement the others they are quite similar).
The main idea is simple, a BigInt represents a big decimal number by cutting its little endian representation into pieces (I'll explain why little endian at the end). The length of those pieces depends on the base you choose. If you want to work with decimal representations, it will only work if your base is a power of 10: if you choose 10 as base each piece will represent one digit, if you choose 100 (= 10^2) as base each piece will represent two consecutive digits starting from the end(see little endian), if you choose 1000 as base (10^3) each piece will represent three consecutive digits, ... and so on. Let's say that you have base 100, 12765 will then be [65, 27, 1], 1789 will be [89, 17], 505 will be [5, 5] (= [05,5]), ... with base 1000: 12765 would be [765, 12], 1789 would be [789, 1], 505 would be [505]. It's not the most efficient, but it is the most intuitive (I think ...)
The addition is then a bit like the addition on paper we learned at school:
begin with the lowest piece of the BigInt
add it with the corresponding piece of the other one
the lowest piece of that sum(= the sum modulus the base) becomes the corresponding piece of the final result
the "bigger" pieces of that sum will be added ("carried") to the sum of the following pieces
go to step 2 with next piece
if no piece left, add the carry and the remaining bigger pieces of the other BigInt (if it has pieces left)
For example:
9542 + 1097855 = [42, 95] + [55, 78, 09, 1]
lowest piece = 42 and 55 --> 42 + 55 = 97 = [97]
---> lowest piece of result = 97 (no carry, carry = 0)
2nd piece = 95 and 78 --> (95+78) + 0 = 173 = [73, 1]
---> 2nd piece of final result = 73
---> remaining: [1] = 1 = carry (will be added to sum of following pieces)
no piece left in first `BigInt`!
--> add carry ( [1] ) and remaining pieces from second `BigInt`( [9, 1] ) to final result
--> first additional piece: 9 + 1 = 10 = [10] (no carry)
--> second additional piece: 1 + 0 = 1 = [1] (no carry)
==> 9542 + 1 097 855 = [42, 95] + [55, 78, 09, 1] = [97, 73, 10, 1] = 1 107 397
Here is a demo where I used the class above to calculate the fibonacci of 10000 (result is too big to copy here)
Good luck!
PS: Why little endian? For the ease of the implementation: it allows to use push_back when adding digits and iteration while implementing the operations will start from the first piece instead of the last piece in the array.

Project Euler #2 in "Python"

I am an absolute beginner here. I was giving the questions on Project Euler a try in Python. Can you please point out where does my code go wrong?
Q) Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
def fib(a):
if ((a==0) or (a==1)):
return 1
else:
return((fib(a-1))+(fib(a-2)))
r=0
sum=0
while (fib(r))<4000000:
if(((fib(r))%2)==0):
sum+=fib(r)
print(sum)
Your code isn't wrong, it's just too slow. In order to solve Project Euler problems, not only does your code have to be correct, but your algorithm must be efficient.
Your fibonacci computation is extremely expensive - that is, recursively trying to attain the next fibonacci number runs in O(2^n) time - far too long when you want to sum numbers with a limit of four million.
A more efficient implementation in Python is as follows:
x = 1
y = 1
z = 0
result = 0
while z < 4000000:
z = (x+y)
if z%2 == 0:
result = result + z
#next iteration
x = y
y = z
print result
this definetly is not the only way- but another way of doing it.
def fib(number):
series = [1,1]
lastnum = (series[len(series)-1]+series[len(series)-2])
_sum = 0
while lastnum < number:
if lastnum % 2 == 0:
_sum += lastnum
series.append(lastnum)
lastnum = (series[len(series)-1] +series[len(series)-2])
return series,_sum
You should use generator function, here's the gist:
def fib(max):
a, b = 0, 1
while a < max:
yield a
a,b = b, a+b
Now call this function from the shell, or write a function after this calling the fib function, your problem will get resolved.It took me 7 months to solve this problem
This is probably the the most efficient way to do it.
a, b = 1, 1
total = 0
while a <= 4000000:
if a % 2 == 0:
total += a
a, b = b, a+b
print (total)
Using recursion might work for smaller numbers, but since you're testing every case up to 4000000, you might want to store the values that you've already found into values. You can look for this algorithm in existing answers.
Another way to do this is to use Binet's formula. This formula will always return the nth Fibonacci number. You can read more about this on MathWorld.
Note that even numbered Fibonacci numbers occur every three elements in the sequence. You can use:
def binet(n):
""" Gets the nth Fibonacci number using Binet's formula """
return int((1/sqrt(5))*(pow(((1+sqrt(5))/2),n)-pow(((1-sqrt(5))/2),n)));
s = 0; # this is the sum
i = 3;
while binet(i)<=4000000:
s += binet(i);
i += 3; # increment by 3 gives only even-numbered values
print(s);
You may try this dynamic program too, worked faster for me
dict = {}
def fib(x):
if x in dict:
return dict[x]
if x==1:
f = 1
elif x==2:
f = 2
else:
f = fib(x-1) + fib(x-2)
dict[x]=f
return f
i = 1
su = 0
fin = 1
while fin < 4000000:
fin = fib(i)
if fin%2 == 0:
su += fib(i)
i+=1
print (su)
As pointed in other answers your code lacks efficiency. Sometimes,keeping it as simple as possible is the key to a good program. Here is what worked for me:
x=0
y=1
nextterm=0
ans=0
while(nextterm<4000000):
nextterm=x+y
x=y
y=nextterm
if(nextterm%2==0):
ans +=nextterm;
print(ans)
Hope this helps. cheers!
it is optimized and works
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fib(10000)
This is the slightly more efficient algorithm based on Lutz Lehmann's comment to this answer (and also applies to the accepted answer):
def even_fibonacci_sum(cutoff=4e6):
first_even, second_even = 2, 8
even_sum = first_even + second_even
while even_sum < cutoff:
even_fib = ((4 * second_even) + first_even)
even_sum += even_fib
first_even, second_even = second_even, even_fib
return even_sum
Consider the below Fibonacci sequence:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, ...
Every third element in the Fibonacci sequence is even.
So the even numbers in the above sequence are 2, 8, 34, 144, 610, ...
For even number n, the below equation holds:
n = 4 * (n-1) + (n-2)
Example:
34 = (4 * 8) + 2, i.e., third even = (4 * second even) + first even
144 = (4 * 34) + 8, i.e., fourth even = (4 * third even) + second even
610 = (4 * 144) + 34 i.e., fifth even = (4 * fourth even) + third even
İt's can work with If we know in how many steps we will reach 4000000. It's around 30 steps.
a=1
b=2
list=[a,b]
for i in range (0,30):
a,b=b,a+b
if b%2==0:
list.append(b)
print(sum(list)-1)
Adapting jackson-jones answer to find the sum of the even-valued fibonacci terms below 4 million.
# create a function to list fibonacci numbers < n value
def fib(n):
a, b = 1, 2
while a < n:
yield a
a, b = b, a+b
# Using filter(), we extract even values from our fibonacci function
# Then we sum() the even fibonacci values that filter() returns
print(sum(filter(lambda x: x % 2 == 0, fib(4000000))))
The result is 4613732.

Wrong Answer in SUBSEQ spoj

I was solving Counting Subsequence Problem in spoj, but getting Wrong Answer. here is the link http://www.spoj.com/problems/SUBSEQ/
Here is my code
#include<stdio.h>
#include<cmath>
#include<algorithm>
int main(){
int t,n;
scanf("%d",&t);
while(t-->0){
scanf("%d",&n);
long arr[n+1];
for(int i=0;i<n;i++){
scanf("%ld",&arr[i]);
}
long sum=arr[0];
int start=0;
long ans=0;
for(int i=1;i<=n;i++){
while(sum>47 && start<i-1){
sum-=arr[start];
start++;
}
if(sum==47)
ans+=1;
if(i<n)
sum+=arr[i];
}
printf("%ld\n",ans);
}
}
Please help me find the error ..
You code will fail the following test case (at least):
1
4
47 -47 48 -1
Your programs gives the answer as 1, where as the answer should be 3, where 3 sequences as follows:
47 -47 48 -1 [The entire sequence]
47 [1st element only]
48 -1 [3rd plus 4th elements]
So, clearly, you've got bugs.
PS: BTW, why are you declaring an array of n+1 items: long arr[n+1]; when you are never going to reference arr[n]? (in fact that item won't even exist)
[Edit]#: Adding explanation for the above use case
How about this - Its easier than you think :-)
Scan the numbers serially. For each number encountered, add it to sum found so far.
Keep a map of number of times the sum (so far) has been found.
Now, to make a total of 47, all we need is to find a number, which when subtracted from the sum so far should give number 47. This is required because if we subtract such number from sum found so far, it would yield 47 obtained from summation of some sequence(s) of contiguous numbers.
Take the above example, 47 -47 48 -1
Initialize a map with number 0 having count = 0 (That's to say that we have found no sum so far exactly once - since we are at the begining)
Scanning the list from the beginning, take number 47, sum so far, say, s = 47. We do 2 things:
map(47) = 1 (since we've found sum so far = 47 for first time).
Now, we need to find number of times, we've can find s-47 = 0 (which is 1). So, answer so far = map(0) = 1
Take next number, -47. Sum so far, s = 0
map(0) = 1 so far, so no map(0) becomes = 2
We need to find number of occurrences of s-47 = -47. Which = 0. So answer so far = answer so far + 0 (remains = 1)
Take next number, 48, sum so far, s = 48
map(48) = 1
We need to find number of occurrences of s-48 = -1. Which = 0. So answer so far = answer so far + 0 (remains = 1)
Take last number, -1, sum so far, s = 47
map(47) = 1 (in step 2.1), so now map(47) becomes = 2
We need to find number of occurrences of s-47 = 0. Which = 2 (in step 3.1). So answer so far = answer so far + 2 = 3
So final answer = 3
It should be fairly trivial to code this.