Looking For Data Structure To Add Numbers Consecutively - algorithm

Like the title says I'm trying to add numbers consecutively. Here's an example:
I'm preatty sure there's a data structure for this but don't remember what it's called. Any help is greatly appreciated. Thanks.

I think this is more of a math question than a data structures question. :-)
The sum of the numbers 1 + 2 + ... + n is equal to n(n + 1) / 2. This number is called the nth triangular number.
Hope this helps!

Data-Structure for this simple summing problem is a overkill. If the number is consecutive, then n(n + 1) / 2 is the best formula for drive this. Even if the consecutive sequence start from any random number like [8 9 10 11 12 13], then you can still calculate it by ((13 * (13 + 1)) / 2) - ((7 * (7 + 1)) / 2).
Further if you need data-structure, then you can use Segment Tree to calculate Range Sum uery. (It is best suit when the data is not consecutive)

Related

four-square sum representation for integers upto N

Lagrange's four-square theorem proves that any natural number can be written as the sum of four square numbers. What I need is to find any one way to write a natural number x as sum of four square numbers for all 0 <= x <= N for any given upper limit N.
What I have done so far is find two-square sum representation for all the numbers <= N for which it is possible to find one, and saved them in an array called two_square_div. Then I used a greedy approach like following:
last_two_square_sum = 0
for num in 0..N
if num can be written as sum of two square
last_two_square_sum = num
other_last_two_square_sum = num - last_two_square_sum
four_square_div[num] = (two_square_div[last_two_square_sum], two_square_div[other_last_two_square_sum]
But this approach does not work for numbers like 23, for which last_two_square_sum = 20 other_last_two_square_sum = 3. But 3 can not be written as sum of two squares so this method fails.
So could anybody provide a correct O(N) solution or any helpful hint? Thank you.
Your algorithm should make more than one attempt (if it already does, then the exit condition must be improved).
23 can be written as 3 + 20, yes; but 3 is not a decomposable of order two and can't lead to a solution.
So you go on: next you try 4 + 19, and this time it's 19 that is rejected. Next you try 5, so 23-5 is 18, and 5 is 12 + 22 while 18 is 32 + 32.
(Of course this is not O(N) at all).
It is not clear to me how you arrive at 20 and not accept previous solutions; try posting the whole of the code.
Also, try asking on Math StackExchange.

algorithm - Mapping n C 4 integers to a unique value within [1, N]

So to demonstrate what I'm hoping to achieve I'll use a deck of cards.
Let's say there are three people, each with their own randomly shuffled deck. The cards in the deck simply have values 1 through 13, and there are four of each card.
When it comes time to draw a card, everyone takes their top card and shows its value to the other two players.
What I want now, is some way to map the values of each of these top cards to a single integer from 1 - 13. The goal being that this algorithm would generate something unique for each operation, and only allow for 4 of the same value (when the exact same inputs are calculated each of 4 times it can happen).
I know I can use Cantor Pairing Function to generate a unique value, but again I want it to be in the range 1-13.
The Cantor pairing function is only necessary if you want to map all positive integers. What's wrong with simply the following, with n = 13 and N = n^4?
(val1 - 1) * n^3 + (val2 - 1) * n^2 + (val3 - 1) * n + (val4 - 1) + 1
The ordering can be given by the suit of the card, or the order in which they are drawn.

Permutation algorithm in the form of

R= repeats allowed -> 2
A= alphabet (1-10)
S= space = 4;
So we want example:
[1][1][4][5]
[1][7][4][5]
[5][1][4][5]
But need a fancy math formula to calculate this and all combinations ?
As I understand it, your alphabet is 1 .. 10, with each 'letter' possibly occurring twice. So what you really have is an alphabet that is ...
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
It has a length of 20, not 10.
The problem now becomes 20 permute 4.
Hope this helps.
EDIT:
As per your additional comments to your question, you can then check each generated permutation to see if it is of the form XXYY as that would be invalid according to what you have written.
A correct general answer requires a summation. I will show you how to do it for these particular values, and let you generalize it.
There are two cases:
Permutations containing no duplicates. This is just 10 P 4
Permutations containing exactly one duplicate:
Choose which number is the duplicate: 10 C 1
Choose two places for it: 4 C 2
Choose the numbers which fit into the remaining two places: 9 P 2
Thus the answer to this particular case is 9360.
The total number is
N * [ (S choose 1) * ((N-1) permute (S-1))
+ (S choose 2) * ((N-1) permute (S-2))
+ ...
+ (S choose R) * ((N-1) permute (S-R)) ]
In otherwords, probably best to fix 1
of the repeated item in place (S
choose 1 different ways of doing
this) and permute the remaining N-1
items over the S-1 remaining spaces; (same as normal N permute S)
then fix 2 of your identical item in
place (S choose 2 different ways of
doing this) and permute the remaining
N-1 items over the remaining S-2 spaces.
etc for each possible number of repeated items, from 1 up to R
And then there are N choices for
your possible repeated item.
You can use this algorithm to enumerate the possibilities too.
Edit
Oh dear.
Thanks #blueraja, you are absolutely correct! the n-repeated-items case does not generalise to 1 item!
corrected formula is therefore
(N permute S)
+ N * [ (S choose 2) * ((N-1) permute (S-2))
+ (S choose 3) * ((N-1) permute (S-3))
+ ...
+ (S choose R) * ((N-1) permute (S-R)) ]
There are relatively few possible solutions (< 10000), so it should be ok to generate all words in A^4, then remove the words with more than 2 repeats.
OR
Generate the (ordered) combinations of N distinct words
Generate the permutations of that subset to get all the possibilities without duplicates
Do the same with N-1 words
For each element in these words, add a duplicate at all the positions but the position of the said character.
I assume that only one item can repeat, and this item is not predetermined.
Here is a formula that works on A(alphabet size), S(strings size) and R(maximum repetition count):
f(A,S,R) = (A perm S) + ASum[r=2 to R] ( (S choose r)(A-1 perm S-r) )
For example, for R=1 (simple permutation) we get f(A,S,R)=(A perm S) as expected. For A=S=R=2 we have f(A,S,R)=4 which corresponds to:
1,2
2,1
1,1
2,2
The case you describe in the question is A=10, R=2, S=4, and then we have:
f(A,S,R) = 9360
(Exactly as BlueRaja calculated)
This is a nice article about combinations and permutations, there you can find all the formulas

Calculating powers (e.g. 2^11) quickly [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
The most efficient way to implement an integer based power function pow(int, int)
How can I calculate powers with better runtime?
E.g. 2^13.
I remember seeing somewhere that it has something to do with the following calculation:
2^13 = 2^8 * 2^4 * 2^1
But I can't see how calculating each component of the right side of the equation and then multiplying them would help me.
Any ideas?
Edit: I did mean with any base. How do the algorithms you've mentioned below, in particular the "Exponentation by squaring", improve the runtime / complexity?
There is a generalized algorithm for this, but in languages that have bit-shifting, there's a much faster way to compute powers of 2. You just put in 1 << exp (assuming your bit shift operator is << as it is in most languages that support the operation).
I assume you're looking for the generalized algorithm and just chose an unfortunate base as an example. I will give this algorithm in Python.
def intpow(base, exp):
if exp == 0:
return 1
elif exp == 1:
return base
elif (exp & 1) != 0:
return base * intpow(base * base, exp // 2)
else:
return intpow(base * base, exp // 2)
This basically causes exponents to be able to be calculated in log2 exp time. It's a divide and conquer algorithm. :-) As someone else said exponentiation by squaring.
If you plug your example into this, you can see how it works and is related to the equation you give:
intpow(2, 13)
2 * intpow(4, 6)
2 * intpow(16, 3)
2 * 16 * intpow(256, 1)
2 * 16 * 256 == 2^1 * 2^4 * 2^8
Use bitwise shifting. Ex. 1 << 11 returns 2^11.
Powers of two are the easy ones. In binary 2^13 is a one followed by 13 zeros.
You'd use bit shifting, which is a built in operator in many languages.
You can use exponentiation by squaring. This is also known as "square-and-multiply" and works for bases != 2, too.
If you're not limiting yourself to powers of two, then:
k^2n = (k^n)^2
The fastest free algorithm I know of is by Phillip S. Pang, Ph.D and can the source code can be found here.
It uses table-driven decomposition, by which it is possible to make exp() function, which is 2-10 times faster, then native exp() of Pentium(R) processor.

(ProjectEuler) Sum Combinations

From ProjectEuler.net:
Prob 76: How many different ways can one hundred be written as a sum of at least two positive integers?
I have no idea how to start this...any points in the right direction or help? I'm not looking for how to do it but some hints on how to do it.
For example 5 can be written like:
4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1
So 6 possibilities total.
Partition Numbers (or Partition Functions) are the key to this one.
Problems like these are usually easier if you start at the bottom and work your way up to see if you can detect any patterns.
P(1) = 1 = {1}
P(2) = 2 = {[2], [1 + 1]}
P(3) = 3 = {[3], [2 + 1], [1 + 1 + 1]}
P(4) = 5 = {[4], [3 + 1], [2 + 2], [2 + 1 + 1], [1 + 1 + 1 + 1]}
P(5) = 7 ...
P(6) = 11 ...
P(7) = 15 ...
P(8) = 22 ...
P(9) = 30 ...
Hint: See if you can build P(N) up from some combination of the results prior to P(N).
The solution can be found using a chopping algorithm.
Use for example the 6. Then we have:
6
5+1
4+2
3+3
but we are not finished yet.
If we take the 5+1, and consider the +1 part as finished, because all other ending combinations are handled by the 4+2 and 3+3. So we need to apply the same trick to the 5.
4+1+1
3+2+1
And we can continue. But not mindlessly. Because for example 4+2 produces 3+1+2 and 2+2+2. But we don't want the 3+1+2 because we will have a 3+2+1. So we only use all productions of 4 where the lowest number is greater or equal than 2.
6
5+1
4+1+1
3+1+1+1
2+1+1+1+1
1+1+1+1+1+1
2+2+1+1
3+2+1
4+2
2+2+2
3+3
Next step is to put this in an algorithm.
Ok we need a recursive function that takes two parameters. The number to be chopped and the minimal value:
func CountCombinations(Number, Minimal)
temp = 1
if Number<=1 then return 1
for i = 1 to Floor(Number/2)
if i>=Minimal then
temp := temp + CountCombinations(Number-i, i)
end for
return temp
end func
To check the algorithm:
C(6,1) = 1 + C(5,1) + C(4,2) + C(3,3) = 11, which is correct.
C(5,1) = 1 + C(4,1) + C(3,2) = 7
C(4,1) = 1 + C(3,1) + C(2,2) = 5
C(3,1) = 1 + C(2,1) = 3
C(2,1) = 1 + C(1,1) = 2
C(1,1) = 1
C(2,2) = 1
C(3,2) = 1
C(4,2) = 1 + C(2,2) = 2
C(3,3) = 1
By the way, the number of combinations of 100:
CC(100) = 190569292
CC(100) = 190569291 (if we don't take into account 100 + 0)
A good way to approach these is not get fixated on the '100' but try to consider what the difference between totalling for a sum n and n+1 would be, by looking for patterns as n increases 1,2,3....
I'd have a go now but I have work to do :)
Like most problems in Project Euler with big numbers, the best way to think about them is not to get stumped with that huge upper bound, and think of the problem in smaller terms, and gradually work your way up. Maybe, on the way you'll recognize a pattern, or learn enough to get you to the answer easily.
The only other hint I think I can give you without spoiling your epiphany is the word 'partition'.
Once you've figured that out, you'll have it in no time :)
one approach is to think recursive function: find permutations of a numeric series drawn from the positive integers (duplicates allowed) that add up to 100
the zero is 1, i.e. for the number 1 there are zero solutions
the unit is 2, i.e for the number 2 there is only one solution
another approach is to think generative function: start with the zero and find permutation series up to the target, keeping a map/hash or the intermediate values and counts
you can iterate up from 1, or recurse down from 100; you'll get the same answer either way. At each point you could (for a naive solution) generate all permutations of the series of positive integers counting up to the target number minus 1, and count only those that add up to the target number
good luck!
Notice: My maths is a bit rusty but hopefully this will help...
You are going well with your break down of the problem.
Think Generally:
A number n can be written as (n-1)+1 or (n-2)+2
You generalise this to (n-m)+m
Remember that the above also applies to all numbers (including m)
So the idea is to find the first set (lets say 5 = (5-1)+1) and then treat (5-1) as a new n...5 = 4 +1...5 = ((4-1)+1)+1. The once that is exhausted begin again on 5 = 3 + 2....which becomes 5 = ((3-1)+1)+2 ....= 2+1+2....breaking down each one as you go along.
Many math problems can be solved by induction.
You know the answer for a specific value, and you can find the answer for every value, if you find something that link n with n+1.
For example in your case you know that the answer for How many different ways can one be written as a sum of at least two positive integers? is just 1.
What do I mean with the link between n and n+1? Well I mean exactly that you must find a formula that, provide you know the answer for n, you will find the answer for n+1. Then, calling recursively that formula, you'll know the answer and you've done (note: this is just the mathematical part of it, in real life you might find that this approach would gave you something too slow to be practical, so you've not done yet - in this case I think you will be done).
Now, suppose that you know n can be written as a sum of at least two positive integers? in k different ways, one of which would be:
n=a1+a2+a3+...am (this sum has m terms)
What can you say about n+1? Since you would like just hints I'm not writing the solution here, but just what follows. Surely you have the same k different ways, but in each of them there will be the +1 term, one of which would be:
n+1=a1+a2+a3+...am+1 (this sum has m+1 terms)
Then, of course, you will have other k possibilities, such those in which the last term of each sum is not the same, but it will be increased by one, like:
n+1=a1+a2+a3+...(am+1) (this sum has m terms)
Thus there are at least 2k ways of writing n+1 as a sum of at least two positive integers. Well, there are other ones. Find it out, if you can :-)
And enjoy :-))

Resources