Binary search algorithm to maximize values - c++

I was assigned this problem I have to solve:
There are plenty of guided activities in a certain swimming pool. Therefore, the usage rules are very strict:
The free time slots are only one minute long. After using a free slot, we must wait for at least x seconds before using another slot. You have the list of free slots, and you want to swim for at least m minutes. What is the maximum x that allows it?
Input
Input consists of several cases. Every case begins with the number of minutes m and the number of slots n, followed by n triples H:M:S, indicating that there is a lane that is free for one minute starting at H:M:S. Assume 2 ≤ m ≤ n ≤ 1000, that the hours are between 00:00:00 and 23:59:00, and that there are no overlaps between time slots. The final entry is marked with a special case with m = n = 0.
Output
For every case, print the maximum x that permits a total bath time of m or more minutes.
What would be a possible implementation using binary search over the variable x to maximize it?
Outputs of the problem:
input:
4 8
00:10:40 00:35:30 01:00:00 01:55:00 02:10:00 03:15:00 12:00:20 23:59:00
output: x = 11000

This doesn't require any search at all. Transform the list from free time-slots to a list of waiting-time between timeslots in seconds (take into account you're swimming for one minute):
waiting_time[]
for i in [1, length(time_slots))
waiting_time[i - 1] = delta_minutes(time_slots[i - 1], time_slots[i]) * 60 - 60
Sort the list of waiting-times
sortDesc(waiting_time)
Since you've got to wait m - 1 times, x must be chosen such that at least x waiting-times are at least equally long. Since we're searching for the maximum x, the smallest waiting-time must be exactly as long as x, which is the m - 1th element in our array.
Putting it all together:
minX(input[], m):
waiting_time[]
for i in [1, length(input)):
waiting_time[i - 1] = delta_minutes(time_slots[i - 1], time_slots[i]) * 60 - 60
sortDesc(waiting_time)
return waiting_time[m - 1]

Related

Product of three primes divisible by sum of those primes

I found this problem in a cp contest which is over now so it can be answered.
Three primes (p1,p2,p3) (not necessarily distinct) are called special if (p1+p2+p3) divides p1*p2*p3. We have to find the number of these special pairs if the primes can't exceed 10^6
I tried brute force method but it timed out. Can there be any other method?
If you are timing out, then you need to do some smart searching to replace brute force. There are just short of 80,000 primes below a million so it is not surprising you timed out.
So, you need to start looking more carefully.
For example, any triple (2, p, p+2) where p+2 is also prime will meet the criteria:
2 + 3 + 5 = 10; 2 * 3 * 5 = 30; 30 / 10 = 3.
2 + 5 + 7 = 14; 2 * 5 * 7 = 70. 70 / 14 = 5.
...
2 + p + p+2 = 2(p+2); 2 * p * (p+2) = 2p(p+2); 2p(p+2) / 2(p+2) = p.
...
Are there other triples that start with 2? Are there triples that start with 3? What forms do p2 and p3 take if p1= 3? Run your program for triples up to 500 or so and look for patterns in the results. Then extrapolate those results to 10^6.
I assume you are using a Sieve to generate your initial list of primes.
I've experimented with this problem since you posted it. I've not solved it, but wanted to pass along what insight I have before I move onto something else:
Generating Primes is Not the Issue
With a proper sieve algorithm, we can generate all primes under 10**6 in a fraction of a second. (Less than 1/3 of a second on my Mac mini.) Spending time optimizing prime generation beyond this is time wasted.
The Brute Force Method
If we try to generate all permutations of three primes in Python, e.g.:
for prime_1 in primes:
for prime_2 in primes:
if prime_2 < prime_1:
continue
for prime_3 in primes:
if prime_3 < prime_2:
continue
pass
Or better yet, push the problem down to the C level via Python's itertools:
from itertools import combinations_with_replacement
for prime_1, prime_2, prime_3 in combinations_with_replacement(primes, 3):
pass
Then, our timings, doing no actual work except generating prime triples, looks like:
sec.
10**2 0.04
10**3 0.13
10**4 37.37
10**5 ?
You can see how much time increases with each order of magnitude. Here's my example of a brute force solution:
from itertools import combinations_with_replacement
def sieve_primes(n): # assumes n > 1
sieve = [False, False, True] + [True, False] * ((n - 1) // 2)
p = 3
while p * p <= n:
if sieve[p]:
for i in range(p * p, n + 1, p):
sieve[i] = False
p += 2
return [number for number, isPrime in enumerate(sieve) if isPrime]
primes = sieve_primes(10 ** 3)
print("Finished Sieve:", len(primes), "primes")
special = 0
for prime_1, prime_2, prime_3 in combinations_with_replacement(primes, 3):
if (prime_1 * prime_2 * prime_3) % (prime_1 + prime_2 + prime_3) == 0:
special += 1
print(special)
Avoid Generating Triples, but Still Brute Force
Here's an approach that avoids generating triples. We take the smallest and largest primes we generated, cube them, and loop over them with a custom factoring function. This custom factoring function only returns a value for those numbers that are made up of exactly three prime factors. For any number made up of more or less, it returns None. This should be faster than normal factoring as the function can give up early.
Numbers that factor into exactly three primes are easy to test for specialness. We're going to pretend our custom factoring function takes no time at all and simply measure how long it takes us to loop over all the numbers in question:
smallest_factor, largest_factor = primes[0], primes[-1]
for number in range(smallest_factor**3, largest_factor**3):
pass
Again, some timings:
sec.
10**2 0.14
10**3 122.39
10**4 ?
Doesn't look promising. In fact, worse than our original brute force method. And our custom factoring function in reality adds a lot of time. Here's my example of this solution (copy sieve_primes() from the previous example):
def factor_number(n, count):
size = 0
factors = []
for prime in primes:
while size < count and n % prime == 0:
factors.append(prime)
n //= prime
size += 1
if n == 1 or size == count:
break
if n > 1 or size < count:
return None
return factors
primes = sieve_primes(10 ** 3)
print("Finished Sieve:", len(primes), "primes")
special = 0
smallest_factor, largest_factor = primes[0], primes[-1]
for number in range(smallest_factor**3, largest_factor**3):
factors = factor_number(number, 3)
if factors:
if number % sum(factors) == 0:
special += 1
print(special)

What is the best approach to dp for question TRT (treat for cows) of spoj?

FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for giving vast amounts of milk. FJ sells one treat per day and wants to maximize the money he receives over a given period time. The treats are interesting for many reasons:
The treats are numbered 1..N and stored sequentially in single file in a long box that is open at both ends. On any day, FJ can retrieve one treat from either end of his stash of treats.
Like fine wines and delicious cheeses, the treats improve with age and command greater prices.
The treats are not uniform: some are better and have higher intrinsic value. Treat i has value v(i) (1 <= v(i) <= 1000).
Cows pay more for treats that have aged longer: a cow will pay v(i)*a for a treat of age a.
Given the values v(i) of each of the treats lined up in order of the index i in their box, what is the greatest value FJ can receive for them if he orders their sale optimally?
The first treat is sold on day 1 and has age a=1. Each subsequent day increases the age by 1.
Input
Line 1: A single integer, N
Lines 2..N+1: Line i+1 contains the value of treat v(i)
Output
The maximum revenue FJ can achieve by selling the treats
Example
Input:
5
1
3
1
5
2
Output:
43
What is the basic approach to dp in this problem and how do i process age in dp matrix...? Only approach hitting on my mind is the recursive one... i'm new to DP and i've done some basic dp problems but this is outta my mind... this is what i tried so far
int give(int a[],int x,int y,int age)
{
if(x==y) return age*a[x];
return max(age*a[x]+give(a,x+1,y,age+1),age*a[y]+give(a,x,y-1,age+1));
}
x=starting index ,initialized from 0, y=last index , n-1, age=1 at first call
The first thing to observe is that the current state doesn't depend on the history of where we were taking the treats from. The only thing we care about is how many times we took the treat from the left and how many times we took it from the right.
Therefore the state can be encoded with just 2 numbers: left offset and right offset.
Let f(i,j) be the amount of money we can still get if we until the current move sold. We know that there we have already taken i+j objects from the line, so the age is also i+j.
Therefore we just have to check which position we want to take from, and pick the better one. Well if we pick a treat from the left our amount gained will be
cost * time + f( i + 1 , j ) = cost * (i + j) + f( i + 1 , j ).
The amount if we take from the right has a very similar formula
cost_right * (i + j) + f( i , j + 1 ).
Therefore we can knowing f(i+1,j) and f(i,j+1) compute f(i,j).
Well this can be done using dynamic programming by storing a 2D array of size n*n that stores either -1 if f(i,j) is unknown, or the value of f(x,y) if it is known. Then you can simply update the recursive method described above to actually store the results and return the solution if it is already known. If we take a look at your code example we can modify it to run in time.
int give(int a[],int x,int y,int age)
{
if(dp[x][y]!=-1) return dp[x][y];
if(x==y) return age*a[x];
int answer=max(age*a[x]+give(a,x+1,y,age+1),age*a[y]+give(a,x,y-1,age+1));
dp[x][y]=answer;
return answer;
}
This is just a snippet, as you'll need to fix the boundary conditions and make the actual global dp array, but I hope it is enough to get started.

Number of ways to pick at least x balls (balls are identical)?

There are N distinct boxes of balls in total. There are P boxes each containing A number of balls and remaining Q boxes contains B number of balls each.
Given a number X, what are the total the number of ways in which you can pick at least X balls from the boxes.
P+Q = N
Example: Number of P boxes=2 which contain 2 balls each, Number of Q boxes=1 which contain 2 balls. X=3(Given) where x=minimum number of balls to be picked
So, P+Q=3 (total number of boxes)
Combinations for the number of ways to pick atleast x i.e. 3 balls would be:
combinations of 3:(111),(210),(120),(021),(012),(201),(102)
combinations of 4:(220)(202)(022)(211)(121)(112)
combinations of 5:(212)(122)(221)
combinations of 6: (222)
total Combinations: 17
My Approach:
I have used "Stars and Bars Approach":
To calculate combinations of 6: x+y+z=6 which is converted into (2-x)+(2-y)+(2-z)=6 giving out x+y+z=0.
So, the combination of 6 becomes Binomial(2C2)=1
Similarly, Combinations of 5 becomes Binomial(3C2)=3
Combinations of 4= Binomial(4C2)=6
Combinations of 3= Binomial(5C2)=10
1+3+6+10=20
but the answer should be 1+3+6+7=17
Edge case has appeared on calculating the combinations of 3. How should I tackle this problem?
EDIT: CODE ADDED in python
global total_combinations
total_combinations=0
from math import factorial
def combinations(a):
global total_combinations
bars=numberofAs+numberofBs-1
stars=a
total_combinations+=factorial(stars+bars)/(factorial(bars)*factorial(stars))
numberofAs,numberofBs,numberofballsinA,numberofballsinB=map(int,raw_input().split())
x=int(raw_input())
operational_array=[]
for i in range(numberofAs):
operational_array.append(numberofballsinA)
for i in range(numberofBs):
operational_array.append(numberofballsinB)
max_x=sum(operational_array) #calculate combinations from x to max_x
k=max_x
for i in range(max_x,x-1,-1):
k=max_x-i
combinations(k)
print total_combinations
The number of balls you can take out of a box containing A balls is the number of balls you can put into an empty box of capacity A.
There are known formulas for that problem.
If all boxes have the same number of balls initially (as in the given example, in which A=B=2),
and that number is equal to or greater than the total number of balls to be removed from the boxes, then "stars and bars" will work.
But if the number of balls to be removed is greater than the number in a single box, there is an iterative formula to find the number of ways the balls can be selected.
To remove t balls from k boxes containing m balls each,
from scipy.special import comb
def combinations_with_limit(t, k, m):
total = 0
max_full_boxes = min(k, int(t/(m + 1)))
for i in range(max_full_boxes + 1):
total += int((-1)**i) * comb(k, i, exact=True) * comb(t + k - 1 - i*(m + 1), k - 1, exact=True)
return total
This is based on the formula in this math.stackexchange answer, but using t rather than n for the total number of balls removed in order to avoid confusion with the use of N in this question.
You can optimize and improve the style of this code, of course
(for example, I wouldn't suggest writing int((-1)**i) in production code);
the reason it's written this way is to stay as close as practical to the format of the MSE answer.
Not surprisingly, we have to think a little harder in the case where A and B are different.
To remove a total of t balls from p boxes containing a balls each and q boxes containing b balls each,
def combinations_with_two_limits(t, p, q, a, b):
total = 0
min_balls_from_p = max(0, t - q*b)
max_balls_from_p = min(t, p*a)
for i in range(min_balls_from_p, max_balls_from_p + 1):
total += combinations_with_limit(i, p, a) * combinations_with_limit(t - i, q, b)
return total
The idea here is that you first decide how to allocate the t balls into two groups, one to be removed from the boxes containing a balls and the other to be removed from the boxes containing b balls,
and then count all the ways you can select those subsets of the balls from those subsets of the boxes.
It may be possible to optimize the code further by going back to the derivation of the MSE formula cited above (either through generating functions or the inclusion-exclusion principle), but I wouldn't try it unless it's really critical to shave a few percentage points off the running time.
To remove at least X balls from the boxes, take the sum of the values of
combinations_with_two_limits as t takes on all integer values from X up to and including the largest number of balls you can remove
(which is P*A + Q*B).
Break it in 2 parts where you pick k balls from the P boxes of capacity A and x-k balls from the Q bins with capacity B. Use stars and bars approach on each side to calculate the number of ways to pick k,x-k respectively, and multiply to get the total. (Considering of course that you can only do that when both k,x-k do not exceed the capacities A,B).
To not consider the cases where k>A and x-k>B you have to implement the formula below
Which counts all combinations in which n items are allocated to k bins, excluding combinations where at least one bin contains more than C items.
In your case you need to use this formula twice, once to allocate k balls to P bins with capacity A, and once to allocate x-k balls to Q bins with capacity B.
Then the multiplication should give you the correct result.

To find the min and max after addition and subtraction from a range of numbers

I am having a Algorithm question, in which numbers are been given from 1 to N and a number of operations are to be performed and then min/max has to be found among them.
Two operations - Addition and subtraction
and operations are in the form a b c d , where a is the operation to be performed,b is the starting number and c is the ending number and d is the number to be added/subtracted
for example
suppose numbers are 1 to N
and
N =5
1 2 3 4 5
We perform operations as
1 2 4 5
2 1 3 4
1 4 5 6
By these operations we will have numbers from 1 to N as
1 7 8 9 5
-3 3 4 9 5
-3 3 4 15 11
So the maximum is 15 and min is -3
My Approach:
I have taken the lower limit and upper limit of the numbers in this case it is 1 and 5 only stored in an array and applied the operations, and then had found the minimum and maximum.
Could there be any better approach?
I will assume that all update (addition/subtraction) operations happen before finding max/min. I don't have a good solution for update and min/max operations mixing together.
You can use a plain array, where the value at index i of the array is the difference between the index i and index (i - 1) of the original array. This makes the sum from index 0 to index i of our array to be the value at index i of the original array.
Subtraction is addition with the negated number, so they can be treated similarly. When we need to add k to the original array from index i to index j, we will add k to index i of our array, and subtract k to index (j + 1) of our array. This takes O(1) time per update.
You can find the min/max of the original array by accumulating summing the values and record the max/min values. This takes O(n) time per operation. I assume this is done once for the whole array.
Pseudocode:
a[N] // Original array
d[N] // Difference array
// Initialization
d[0] = a[0]
for (i = 1 to N-1)
d[i] = a[i] - a[i - 1]
// Addition (subtraction is similar)
add(from_idx, to_idx, amount) {
d[from_idx] += amount
d[to_idx + 1] -= amount
}
// Find max/min for the WHOLE array after add/subtract
current = max = min = d[0];
for (i = 1 to N - 1) {
current += d[i]; // Sum from d[0] to d[i] is a[i]
max = MAX(max, current);
min = MIN(min, current);
}
Generally there is no "best way" to find the min/max in the performance point of view because it depends on how this application will be used.
-Finding the max and min in a list needs O(n) Time, so if you want to run many (many in the context of the input) operations, your approach to find the min/max after all the operations took place is fine.
-But if the list will hold many elements and you don’t want to run that many operations, you better check each result of the op if its a new max/min and update if necessary.

Fastest way to find the sum of decimal digits

What is the fastest way to find the sum of decimal digits?
The following code is what I wrote but it is very very slow for range 1 to 1000000000000000000
long long sum_of_digits(long long input) {
long long total = 0;
while (input != 0) {
total += input % 10;
input /= 10;
}
return total;
}
int main ( int argc, char** argv) {
for ( long long i = 1L; i <= 1000000000000000000L; i++) {
sum_of_digits(i);
}
return 0;
}
I'm assuming what you are trying to do is along the lines of
#include <iostream>
const long long limit = 1000000000000000000LL;
int main () {
long long grand_total = 0;
for (long long ii = 1; ii <= limit; ++ii) {
grand_total += sum_of_digits(i);
}
std::cout << "Grand total = " << grand_total << "\n";
return 0;
}
This won't work for two reasons:
It will take a long long time.
It will overflow.
To deal with the overflow problem, you will either have to put a bound on your upper limit or use some bignum package. I'll leave solving that problem up to you.
To deal with the computational burden you need to get creative. If you know the upper limit is limited to powers of 10 this is fairly easy. If the upper limit can be some arbitrary number you will have to get a bit more creative.
First look at the problem of computing the sum of digits of all integers from 0 to 10n-1 (e.g., 0 to 9 (n=1), 0 to 99 (n=2), etc.) Denote the sum of digits of all integers from 10n-1 as Sn. For n=1 (0 to 9), this is just 0+1+2+3+4+5+6+7+8+9=45 (9*10/2). Thus S1=45.
For n=2 (0 to 99), you are summing 0-9 ten times and you are summing 0-9 ten times again. For n=3 (0 to 999), you are summing 0-99 ten times and you are summing 0-9 100 times. For n=4 (0 to 9999), you are summing 0-999 ten times and you are summing 0-9 1000 times. In general, Sn=10Sn-1+10n-1S1 as a recursive expression. This simplifies to Sn=(9n10n)/2.
If the upper limit is of the form 10n, the solution is the above Sn plus one more for the number 1000...000. If the upper limit is an arbitrary number you will need to get creative once again. Think along the lines that went into developing the formula for Sn.
You can break this down recursively. The sum of the digits of an 18-digit number are the sums of the first 9 digits plus the last 9 digits. Likewise the sum of the digits of a 9-bit number will be the sum of the first 4 or 5 digits plus the sum of the last 5 or 4 digits. Naturally you can special-case when the value is 0.
Reading your edit: computing that function in a loop for i between 1 and 1000000000000000000 takes a long time. This is a no brainer.
1000000000000000000 is one billion billion. Your processor will be able to do at best billions of operations per second. Even with a nonexistant 4-5 Ghz processor, and assuming best case it compiles down to an add, a mod, a div, and a compare jump, you could only do 1 billion iterations per second, meaning it will take on the order of 1 billion seconds.
You probably don't want to do it in a bruteforce way. This seems to be more of a logical thinking question.
Note - 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = N(N+1)/2 = 45.
---- Changing the answer to make it clearer after David's comment
See David's answer - I had it wrong
Quite late to the party, but anyways, here is my solution. Sorry it's in Python and not C++, but it should be relatively easy to translate. And because this is primarily an algorithm problem, I hope that's ok.
As for the overflow problem, the only thing that comes to mind is to use arrays of digits instead of actual numbers. Given this algorithm I hope it won't affect performance too much.
https://gist.github.com/frnhr/7608873
It uses these three recursions I found by looking and poking at the problem. Rather then trying to come up with some general and arcane equations, here are three examples. A general case should be easily visible from those.
relation 1
Reduces function calls with arbitrary argument to several recursive calls with more predictable arguments for use in relations 2 and 3.
foo(3456) == foo(3000)
+ foo(400) + 400 * (3)
+ foo(50) + 50 * (3 + 4)
+ foo(6) + 6 * (3 + 4 + 5)
relation 2
Reduce calls with an argument in the form L*10^M (e.g: 30, 7000, 900000) to recursive call usable for relation 3. These triangular numbers popped in quite uninvited (but welcome) :)
triangular_numbers = [0, 1, 3, 6, 10, 15, 21, 28, 36] # 0 not used
foo(3000) == 3 * foo(1000) + triangular_numbers[3 - 1] * 1000
Only useful if L > 1. It holds true for L = 1 but is trivial. In that case, go directly to relation 3.
relation 3
Recursively reduce calls with argument in format 1*10^M to a call with argument that's divided by 10.
foo(1000) == foo(100) * 10 + 44 * 100 + 100 - 9 # 44 and 9 are constants
Ultimately you only have to really calculate the sum or digits for numbers 0 to 10, and it turns out than only up to 3 of these calculations are needed. Everything else is taken care of with this recursion. I'm pretty sure it runs in O(logN) time. That's FAAST!!!!!11one
On my laptop it calculates the sum of digit sums for a given number with over 1300 digits in under 7 seconds! Your test (1000000000000000000) gets calculated in 0.000112057 seconds!
I think you cannot do better than O(N) where N is the number of digits in the given number(which is not computationally expensive)
However if I understood your question correctly (the range) you want to output the sum of digits for a range of numbers. In that case, you can increment by one when you go from number0 to number9 and then decrease by 8.
You will need to cheat - look for mathematical patterns that let you short-cut your computations.
For example, do you really need to test that input != 0 every time? Does it matter if you add 0/10 several times? Since it won't matter, consider unrolling the loop.
Can you do the calculation in a larger base, eg, base 10^2, 10^3, etcetera, that might allow you to reduce the number of digits, which you'll then have to convert back to base 10? If this works, you'll be able to implement a cache more easily.
Consider looking at compiler intrinsics that let you give hints to the compiler for branch prediction.
Given that this is C++, consider implementing this using template metaprogramming.
Given that sum_of_digits is purely functional, consider caching the results.
Now, most of those suggestions will backfire - but the point I'm making is that if you have hit the limits of what your computer can do for a given algorithm, you do need to find a different solution.
This is probably an excellent starting point if you want to investigate this in detail: http://mathworld.wolfram.com/DigitSum.html
Possibility 1:
You could make it faster by feeding the result of one iteration of the loop into the next iteration.
For example, if i == 365, the result is 14. In the next loop, i == 366 -- 1 more than the previous result. The sum is also 1 more: 3 + 6 + 6 = 15.
Problems arise when there is a carry digit. If i == 99 (ie. result = 18), the next loop's result isn't 19, it's 1. You'll need extra code to detect this case.
Possibility 2:
While thinking though the above, it occurred to me that the sequence of results from sum_of_digits when graphed would resemble a sawtooth. With some analysis of the resulting graph (which I leave as an exercise for the reader), it may be possible to identify a method to allow direct calculation of the sum result.
However, as some others have pointed out: Even with the fastest possible implementation of sum_of_digits and the most optimised loop code, you can't possibly calculate 1000000000000000000 results in any useful timeframe, and certainly not in less than one second.
Edit: It seems you want the the sum of the actual digits such that: 12345 = 1+2+3+4+5 not the count of digits, nor the sum of all numbers 1 to 12345 (inclusive);
As such the fastest you can get is:
long long sum_of_digits(long long input) {
long long total = input % 10;
while ((input /= 10) != 0)
total += input % 10;
return total;
}
Which is still going to be slow when you're running enough iterations. Your requirement of 1,000,000,000,000,000,000L iterations is One Million, Million, Million. Given 100 Million takes around 10,000ms on my computer, one can expect that it will take 100ms per 1 million records, and you want to do that another million million times. There are only 86400 seconds in a day, so at best we can compute around 86,400 Million records per day. It would take one computer
Lets suppose your method could be performed in a single float operation (somehow), suppose you are using the K computer which is currently the fastest (Rmax) supercomputer at over 10 petaflops, if you do the math that is = 10,000 Million Million floating operations per second. This means that your 1 Million, Million, Million loop will take the world's fastest non-distributed supercomputer 100 seconds to compute the sums (IF it took 1 float operation to calculate, which it can't), so you will need to wait around for quite some time for computers to become 100 so much more powerful for your solution to be runable in under one second.
What ever you're trying to do, you're either trying to do an unsolvable problem in near real-time (eg: graphics calculation related) or you misunderstand the question / task that was given you, or you are expected to perform something faster than any (non-distributed) computer system can do.
If your task is actually to sum all the digits of a range as you show and then output them, the answer is not to improve the for loop. for example:
1 = 0
10 = 46
100 = 901
1000 = 13501
10000 = 180001
100000 = 2250001
1000000 = 27000001
10000000 = 315000001
100000000 = 3600000001
From this you could work out a formula to actually compute the total sum of all digits for all numbers from 1 to N. But it's not clear what you really want, beyond a much faster computer.
No the best, but simple:
int DigitSumRange(int a, int b) {
int s = 0;
for (; a <= b; a++)
for(c : to_string(a))
s += c-48;
return s;
}
A Python function is given below, which converts the number to a string and then to a list of digits and then finds the sum of these digits.
def SumDigits(n):
ns=list(str(n))
z=[int(d) for d in ns]
return(sum(z))
In C++ one of the fastest way can be using strings.
first of all get the input from users in a string. Then add each element of string after converting it into int. It can be done using -> (str[i] - '0').
#include<iostream>
#include<string>
using namespace std;
int main()
{ string str;
cin>>str;
long long int sum=0;
for(long long int i=0;i<str.length();i++){
sum = sum + (str[i]-'0');
}
cout<<sum;
}
The formula for finding the sum of the digits of numbers between 1 to N is:
(1 + N)*(N/2)
[http://mathforum.org/library/drmath/view/57919.html][1]
There is a class written in C# which supports a number with more than the supported max-limit of long.
You can find it here. [Oyster.Math][2]
Using this class, I have generated a block of code in c#, may be its of some help to you.
using Oyster.Math;
class Program
{
private static DateTime startDate;
static void Main(string[] args)
{
startDate = DateTime.Now;
Console.WriteLine("Finding Sum of digits from {0} to {1}", 1L, 1000000000000000000L);
sum_of_digits(1000000000000000000L);
Console.WriteLine("Time Taken for the process: {0},", DateTime.Now - startDate);
Console.ReadLine();
}
private static void sum_of_digits(long input)
{
var answer = IntX.Multiply(IntX.Parse(Convert.ToString(1 + input)), IntX.Parse(Convert.ToString(input / 2)), MultiplyMode.Classic);
Console.WriteLine("Sum: {0}", answer);
}
}
Please ignore this comment if it is not relevant for your context.
[1]: https://web.archive.org/web/20171225182632/http://mathforum.org/library/drmath/view/57919.html
[2]: https://web.archive.org/web/20171223050751/http://intx.codeplex.com/
If you want to find the sum for the range say 1 to N then simply do the following
long sum = N(N+1)/2;
it is the fastest way.