Difficulty with python recursion - recursion

Can someone explain why:
def sum_digits(n):
if n // 10 == 0: return n
else: return sum_digits(n // 10) + n % 10
print(sum_digits(137))
returns 11 and when i replace + with * it returns 1 instead of 21.

To find the sum of the digits of 137 we need to, quite plainly, take 1 + 3 + 7. The trick the recursion uses is to sum the mod 10 of the number, at each stage of the recursion. To explain more visually:
input | input % 10 | remarks
137 | 7 | call sum_digits(13)
13 | 3 | call sum_digits(1)
1 | 1 | return 1, do not make more recursive calls
total | 11
When making each recursive call, we pass the input number divided by 10. This removes the tens digit number which has already been summed, and shifts the remaining digits to the right by one. When we hit a number less than 10, then the recursion ends, and we make no subsequent calls to sum_digits.

Related

Google Foobar Fuel Injection Perfection

Problem:
Fuel Injection Perfection
Commander Lambda has asked for your help to refine the automatic quantum antimatter fuel injection system for her LAMBCHOP doomsday device. It's a great chance for you to get a closer look at the LAMBCHOP - and maybe sneak in a bit of sabotage while you're at it - so you took the job gladly.
Quantum antimatter fuel comes in small pellets, which is convenient since the many moving parts of the LAMBCHOP each need to be fed fuel one pellet at a time. However, minions dump pellets in bulk into the fuel intake. You need to figure out the most efficient way to sort and shift the pellets down to a single pellet at a time.
The fuel control mechanisms have three operations:
Add one fuel pellet Remove one fuel pellet Divide the entire group of fuel pellets by 2 (due to the destructive energy released when a quantum antimatter pellet is cut in half, the safety controls will only allow this to happen if there is an even number of pellets) Write a function called solution(n) which takes a positive integer as a string and returns the minimum number of operations needed to transform the number of pellets to 1. The fuel intake control panel can only display a number up to 309 digits long, so there won't ever be more pellets than you can express in that many digits.
For example: solution(4) returns 2: 4 -> 2 -> 1 solution(15) returns 5: 15 -> 16 -> 8 -> 4 -> 2 -> 1
Test cases
Inputs: (string) n = "4" Output: (int) 2
Inputs: (string) n = "15" Output: (int) 5
my code:
def solution(n):
n = int(n)
if n == 2:
return 1
if n % 2 != 0:
return min(solution(n + 1), solution(n - 1)) + 1
else:
return solution(int(n / 2)) + 1
This is the solution that I came up with with passes 4 out of 10 of the test cases. It seems to be working fine so im wondering if it is because of the extensive runtime. I thought of applying memoization but im not sure how to do it(or if it is even possible). Any help would be greatly appreciated :)
There are several issues to consider:
First, you don't handle the n == "1" case properly (operations = 0).
Next, by default, Python has a limit of 1000 recursions. If we compute the log2 of a 309 digit number, we expect to make a minimum of 1025 divisions to reach 1. And if each of those returns an odd result, we'd need to triple that to 3075 recursive operations. So, we need to bump up Python's recursion limit.
Finally, for each of those divisions that does return an odd value, we'll be spawning two recursive division trees (+1 and -1). These trees will not only increase the number of recursions, but can also be highly redundant. Which is where memoization comes in:
import sys
from functools import lru_cache
sys.setrecursionlimit(3333) # estimated by trial and error
#lru_cache()
def solution(n):
n = int(n)
if n <= 2:
return n - 1
if n % 2 == 0:
return solution(n // 2) + 1
return min(solution(n + 1), solution(n - 1)) + 1
print(solution("4"))
print(solution("15"))
print(solution(str(10**309 - 1)))
OUTPUT
> time python3 test.py
2
5
1278
0.043u 0.010s 0:00.05 100.0% 0+0k 0+0io 0pf+0w
>
So, bottom line is handle "1", increase your recursion limit, and add memoization. Then you should be able to solve this problem easily.
There are more memory- and runtime-efficient ways to solve the problem, which is what Google is testing for with their constraints. Every time you recurse a function, you put another call on the stack, or 2 calls when you recurse twice on each function call. While they seem basic, a while loop was a lot faster for me.
Think of the number in binary - when ever you have a streak of 1s >1 in length at LSB side of the number, it makes sense to add 1 (which will flip that streak to all 0s but add another bit to the overall length), then shift right until you find another 1 in the LSB position. You can solve it in a fixed memory block in O(n) using just a while loop.
If you don't want or can't use functools, you can build your own cache this way :
cache = {}
def solution_rec(n):
n = int(n)
if n in cache:
return cache[n]
else:
if n <= 1:
return 0
if n == 2:
return 1
if n % 2 == 0:
div = n / 2
cache[div] = solution(div)
return cache[div] + 1
else:
plus = n + 1
minus = n - 1
cache[plus] = solution(n + 1)
cache[minus] = solution(n - 1)
return min(cache[plus], cache[minus]) + 1
However, even if it runs much faster and has less recursive calls, it's still too much recursive calls for Python default configuration if you test the 309 digits limit.
it works if you set sys.setrecursionlimit to 1562.
An implementation of #rreagan3's solution, with the exception that an input of 3 should lead to a subtraction rather than an addition even through 3 has a streak of 1's on the LSB side:
def solution(n):
n = int(n)
count = 0
while n > 1:
if n & 1 == 0:
n >>= 1
elif n & 2 and n != 3:
n += 1
else:
n -= 1 # can also be: n &= -2
count += 1
return count
Demo: https://replit.com/#blhsing/SlateblueVeneratedFactor

Fill three numbers inside One number

I am trying to fit 3 numbers inside 1 number.But numbers will be only between 0 and 11.So their (base) is 12.For example i have 7,5,2 numbers.I come up with something like this:
Three numbers into One number :
7x12=84
84x5=420
420+2=422
Now getting back Three numbers from One number :
422 MOD 12 = 2 (the third number)
422 - 2 = 420
420 / 12 = 35
And i understanded that 35 is multiplication of first and the second number (i.e 7 and 5)
And now i cant get that 7 and 5 anyone knows how could i ???
(I started typing this answer before the other one got posted, but this one is more specific to Arduino then the other one, so I'm leaving it)
The code
You can use bit shifting to get multiple small numbers into one big number, in code it would look like this:
int a, b, c;
//putting then together
int big = (a << 8) + (b << 4) + c;
//separating them again
a = (big >> 8) & 15;
b = (big >> 4) & 15;
c = big & 15;
This code only works when a, b and c are all in the range [0, 15] witch appears to be enough for you case.
How it works
The >> and << operators are the bitshift operators, in short a << n shifts every bit in a by n places to the left, this is equivalent to multiplying by 2^n. Similarly, a >> n shifts to to the right. An example:
11 << 3 == 120 //0000 1011 -> 0101 1000
The & operator performs a bitwise and on the two operands:
6 & 5 == 4 // 0110
// & 0101
//-> 0100
These two operators are combined to "pack" and "unpack" the three numbers. For the packing every small number is shifted a bit to the left and they are all added together. This is how the bits of big now look (there are 16 of them because ints in Arduino are 16 bits wide):
0000aaaabbbbcccc
When unpacking, the bits are shifted to the right again, and they are bitwise anded together with 15 to filter out any excess bits. This is what that last operation looks like to get b out again:
00000000aaaabbbb //big shifted 4 bits to the right
& 0000000000001111 //anded together with 15
-> 000000000000bbbb //gives the original number b
All is working exactly like in base 10 (or 16). Here after your corrected example.
Three numbers into One number :
7x12^2=1008
5*12^1=60
2*12^0=2
1008+60+2=1070
Now getting back Three numbers from One number :
1070 MOD 12 = 2 (the third number)
1070/12 = 89 (integer division) => 89 MOD 12 = 5
89 / 12 = 7
Note also that the maximum value will be 11*12*12+11*12+11=1727.
If this is really programming related, you will be using 16bits instead of 3*8 bits so sparing one byte. An easyer method not using base 12 would be fit each number into half a byte (better code efficiency and same transmission length):
7<<(4+4) + 5<<4 + 2 = 1874
1874 & 0x000F = 2
1874>>4 & 0x000F = 5
1874>>8 & 0x0F = 7
Because MOD(12) and division by 12 is much less efficient than working with powers of 2
you can use the principle of the positional notation to change from one or the other in any base
Treat yours numbers (n0,n1,...,nm) as a digit of a big number in the base B of your choosing so the new number is
N = n0*B^0 + n1*B^1 + ... + nm*B^m
to revert the process is also simple, while your number is greater than 0 find its modulo in respect to the base to get to get the first digit, then subtracts that digit and divide for the base, repeat until finish while saving each digit along the way
digit_list = []
while N > 0 do:
d = N mod B
N = (N - d) / B
digit_list.append( d )
then if N is N = n0*B^0 + n1*B^1 + ... + nm*B^m doing N mod B give you n0, then subtract it leaving you with n1*B^1 + ... + nm*B^m and divide by B to reduce the exponents of all B and that is the new N, N = n1*B^0 + ... + nm*B^(m-1) repetition of that give you all the digit you start with
here is a working example in python
def compact_num( num_list, base=12 ):
return sum( n*pow(base,i) for i,n in enumerate(num_list) )
def decompact_num( n, base=12):
if n==0:
return [0]
result = []
while n:
n,d = divmod(n,base)
result.append(d)
return result
example
>>> compact_num([2,5,7])
1070
>>> decompact_num(1070)
[2, 5, 7]
>>> compact_num([10,2],16)
42
>>> decompact_num(42,16)
[10, 2]
>>>

Summing elems of array using binary recursion

I wasn't starting to understand linear recursion and then I thought I practice up on sorting algorithms and then quick sort was where I had trouble with recursion. So I decided to work with a simpler eg, a binary sum that I found online. I understand that recursion, like all function calls, are executed one # a time and not at the same time (which is what multi-threading does but is not of my concern when tracing). So I need to execute all of recursive call A BEFORE recursive call B, but I get lost in the mix. Does anyone mind tracing it completely. The e.g. I have used of size, n = 9 where elems are all 1's to keep it simple.
/**
* Sums an integer array using binary recursion.
* #param arr, an integer array
* #param i starting index
* #param n size of the array
* floor(x) is largest integer <= x
* ceil(x) is smallest integer >= x
*/
public int binarySum(int arr[], int i, int n) {
if (n == 1)
return arr[i];
return binarySum(arr, i, ceil(n/2)) + binarySum(arr,i + ceil(n/2), floor(n/2));
}
What I personally do is start with an array of size 2. There are two elements.
return binarySum(arr, i, ceil(n/2)) + binarySum(arr,i + ceil(n/2), floor(n/2)) will do nothing but split the array into 2 and add the two elements. - case 1
now, this trivial starting point will be the lowest level of the recursion for the higher cases.
now increase n = 4. the array is split into 2 : indices from 0-2 and 2-4.
now the 2 elements inside indices 0 to 2 are added in case 1 and so are the 2 elements added in indices 2-4.
Now these two results are added in this case.
Now we are able to make more sense of the recursion technique, some times understanding bottom up is easier as in this case!
Now to your question consider an array of 9 elements : 1 2 3 4 5 6 7 8 9
n = 9 => ceil(9/2) = 5, floor(9/2) = 4
Now first call (top call) of binarySum(array, 0, 9)
now n = size is not 1
hence the recursive call....
return binarySum(array, 0, 5) + binarySum(array, 5, 4)
now the first binarySum(array, 0 ,5) operates on the first 5 elements of the array and the second binarySum(array,5,4) operates on the last 4 elements of the array
hence the array division can be seen like this: 1 2 3 4 5 | 6 7 8 9
The first function finds the sum of the elements: 1 2 3 4 5
and the second function finds the sum of the elements 6 7 8 9
and these two are added together and returned as the answer to the top call!
now how does this 1+2+3+4+5 and 6+7+8+9 work? we recurse again....
so the tracing will look like
1 2 3 4 5 | 6 7 8 9
1 2 3 | 4 5 6 7 | 8 9
1 2 | 3 4 | 5 6 | 7 8 | 9
[1 | 2]___[3]___[4 5]___[6 7]___[8 9]
Till this we are fine..we are just calling the functions recursively.
But now, we hit the base case!
if (n == 1)
return arr[i];
[1 + 2]____[3]____[4 + 5]____[6 + 7]____[8 + 9]
[3 + 3] ____ [9] ____[13 + 17]
[6 + 9] [30]
[15 + 30]
[45]
which is the sum.
So for understanding see what is done to the major instance of the problem and you can be sure that the same thing is going to happen to the minor instance of the problem.
This example explains binary sum with trace in java
the trace is based on index of array , where 0 - is yours starting index and 8 is length of the array
int sum(int* arr, int p, int k) {
if (p == k)
return arr[k];
int s = (p + k) / 2;
return sum(arr, p, s) + sum(arr, s + 1, k);
}

What does bitwise XOR (exclusive OR) mean?

I'm trying to understand the binary operators in C# or in general, in particular ^ - exclusive or.
For example:
Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time and constant space.
This can be done with ^ as follows: Do bitwise XOR of all the elements. Finally we get the number which has odd occurrences.
How does it work?
When I do:
int res = 2 ^ 3;
res = 1;
int res = 2 ^ 5;
res = 7;
int res = 2 ^ 10;
res = 8;
What's actually happening? What are the other bit magics? Any reference I can look up and learn more about them?
I know this is a rather old post but I wanted simplify the answer since I stumbled upon it while looking for something else.
XOR (eXclusive OR/either or), can be translated simply as toggle on/off.
Which will either exclude (if exists) or include (if nonexistent) the specified bits.
Using 4 bits (1111) we get 16 possible results from 0-15:
decimal | binary | bits (expanded)
0 | 0000 | 0
1 | 0001 | 1
2 | 0010 | 2
3 | 0011 | (1+2)
4 | 0100 | 4
5 | 0101 | (1+4)
6 | 0110 | (2+4)
7 | 0111 | (1+2+4)
8 | 1000 | 8
9 | 1001 | (1+8)
10 | 1010 | (2+8)
11 | 1011 | (1+2+8)
12 | 1100 | (4+8)
13 | 1101 | (1+4+8)
14 | 1110 | (2+4+8)
15 | 1111 | (1+2+4+8)
The decimal value to the left of the binary value, is the numeric value used in XOR and other bitwise operations, that represents the total value of associated bits. See Computer Number Format and Binary Number - Decimal for more details.
For example: 0011 are bits 1 and 2 as on, leaving bits 4 and 8 as off. Which is represented as the decimal value of 3 to signify the bits that are on, and displayed in an expanded form as 1+2.
As for what's going on with the logic behind XOR here are some examples
From the original post
2^3 = 1
2 is a member of 1+2 (3) remove 2 = 1
2^5 = 7
2 is not a member of 1+4 (5) add 2 = 1+2+4 (7)
2^10 = 8
2 is a member of 2+8 (10) remove 2 = 8
Further examples
1^3 = 2
1 is a member of 1+2 (3) remove 1 = 2
4^5 = 1
4 is a member of 1+4 (5) remove 4 = 1
4^4 = 0
4 is a member of itself remove 4 = 0
1^2^3 = 0Logic: ((1^2)^(1+2))
(1^2) 1 is not a member of 2 add 2 = 1+2 (3)
(3^3) 1 and 2 are members of 1+2 (3) remove 1+2 (3) = 0
1^1^0^1 = 1 Logic: (((1^1)^0)^1)
(1^1) 1 is a member of 1 remove 1 = 0
(0^0) 0 is a member of 0 remove 0 = 0
(0^1) 0 is not a member of 1 add 1 = 1
1^8^4 = 13 Logic: ((1^8)^4)
(1^8) 1 is not a member of 8 add 1 = 1+8 (9)
(9^4) 1 and 8 are not members of 4 add 1+8 = 1+4+8 (13)
4^13^10 = 3 Logic: ((4^(1+4+8))^(2+8))
(4^13) 4 is a member of 1+4+8 (13) remove 4 = 1+8 (9)
(9^10) 8 is a member of 2+8 (10) remove 8 = 2
1 is not a member of 2+8 (10) add 1 = 1+2 (3)
4^10^13 = 3 Logic: ((4^(2+8))^(1+4+8))
(4^10) 4 is not a member of 2+8 (10) add 4 = 2+4+8 (14)
(14^13) 4 and 8 are members of 1+4+8 (13) remove 4+8 = 1
2 is not a member of 1+4+8 (13) add 2 = 1+2 (3)
To see how it works, first you need to write both operands in binary, because bitwise operations work on individual bits.
Then you can apply the truth table for your particular operator. It acts on each pair of bits having the same position in the two operands (the same place value). So the leftmost bit (MSB) of A is combined with the MSB of B to produce the MSB of the result.
Example: 2^10:
0010 2
XOR 1010 8 + 2
----
1 xor(0, 1)
0 xor(0, 0)
0 xor(1, 1)
0 xor(0, 0)
----
= 1000 8
And the result is 8.
The other way to show this is to use the algebra of XOR; you do not need to know anything about individual bits.
For any numbers x, y, z:
XOR is commutative: x ^ y == y ^ x
XOR is associative: x ^ (y ^ z) == (x ^ y) ^ z
The identity is 0: x ^ 0 == x
Every element is its own inverse: x ^ x == 0
Given this, it is easy to prove the result stated. Consider a sequence:
a ^ b ^ c ^ d ...
Since XOR is commutative and associative, the order does not matter. So sort the elements.
Now any adjacent identical elements x ^ x can be replaced with 0 (self-inverse property). And any 0 can be removed (because it is the identity).
Repeat as long as possible. Any number that appears an even number of times has an integral number of pairs, so they all become 0 and disappear.
Eventually you are left with just one element, which is the one appearing an odd number of times. Every time it appears twice, those two disappear. Eventually you are left with one occurrence.
[update]
Note that this proof only requires certain assumptions about the operation. Specifically, suppose a set S with an operator . has the following properties:
Assocativity: x . (y . z) = (x . y) . z for any x, y, and z in S.
Identity: There exists a single element e such that e . x = x . e = x for all x in S.
Closure: For any x and y in S, x . y is also in S.
Self-inverse: For any x in S, x . x = e
As it turns out, we need not assume commutativity; we can prove it:
(x . y) . (x . y) = e (by self-inverse)
x . (y . x) . y = e (by associativity)
x . x . (y . x) . y . y = x . e . y (multiply both sides by x on the left and y on the right)
y . x = x . y (because x . x = y . y = e and the e's go away)
Now, I said that "you do not need to know anything about individual bits". I was thinking that any group satisfying these properties would be enough, and that such a group need not necessarily be isomorphic to the integers under XOR.
But #Steve Jessup proved me wrong in the comments. If you define scalar multiplication by {0,1} as:
0 * x = 0
1 * x = x
...then this structure satisfies all of the axioms of a vector space over the integers mod 2.
Thus any such structure is isomorphic to a set of vectors of bits under component-wise XOR.
This is based on the simple fact that XOR of a number with itself results Zero.
and XOR of a number with 0 results the number itself.
So, if we have an array = {5,8,12,5,12}.
5 is occurring 2 times.
8 is occurring 1 times.
12 is occurring 2 times.
We have to find the number occurring odd number of times. Clearly, 8 is the number.
We start with res=0 and XOR with all the elements of the array.
int res=0;
for(int i:array)
res = res ^ i;
1st Iteration: res = 0^5 = 5
2nd Iteration: res = 5^8
3rd Iteration: res = 5^8^12
4th Iteration: res = 5^8^12^5 = 0^8^12 = 8^12
5th Iteration: res = 8^12^12 = 8^0 = 8
The bitwise operators treat the bits inside an integer value as a tiny array of bits. Each of those bits is like a tiny bool value. When you use the bitwise exclusive or operator, one interpretation of what the operator does is:
for each bit in the first value, toggle the bit if the corresponding bit in the second value is set
The net effect is that a single bit starts out false and if the total number of "toggles" is even, it will still be false at the end. If the total number of "toggles" is odd, it will be true at the end.
Just think "tiny array of boolean values" and it will start to make sense.
The definition of the XOR (exclusive OR) operator, over bits, is that:
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
One of the ways to imagine it, is to say that the "1" on the right side changes the bit from the left side, and 0 on the right side doesn't change the bit on the left side. However, XOR is commutative, so the same is true if the sides are reversed.
As any number can be represented in binary form, any two numbers can be XOR-ed together.
To prove it being commutative, you can simply look at its definition, and see that for every combination of bits on either side, the result is the same if the sides are changed. To prove it being associative, you can simply run through all possible combinations of having 3 bits being XOR-ed to each other, and the result will stay the same no matter what the order is.
Now, as we proved the above, let's see what happens if we XOR the same number at itself. Since the operation works on individual bits, we can test it on just two numbers: 0 and 1.
0 XOR 0 = 0
1 XOR 1 = 0
So, if you XOR a number onto itself, you always get 0 (believe it or not, but that property of XOR has been used by compilers, when a 0 needs to be loaded into a CPU register. It's faster to perform a bit operation than to explicitly push 0 into a register. The compiler will just produce assembly code to XOR a register onto itself).
Now, if X XOR X is 0, and XOR is associative, and you need to find out what number hasn't repeated in a sequence of numbers where all other numbers have been repeated two (or any other odd number of times). If we had the repeating numbers together, they will XOR to 0. Anything that is XOR-ed with 0 will remain itself. So, out of XOR-ing such a sequence, you will end up being left with a number that doesn't repeat (or repeats an even number of times).
This has a lot of samples of various functionalities done by bit fiddling. Some of can be quite complex so beware.
What you need to do to understand the bit operations is, at least, this:
the input data, in binary form
a truth table that tells you how to "mix" the inputs to form the result
For XOR, the truth table is simple:
1^1 = 0
1^0 = 1
0^1 = 1
0^0 = 0
To obtain bit n in the result you apply the rule to bits n in the first and second inputs.
If you try to calculate 1^1^0^1 or any other combination, you will discover that the result is 1 if there is an odd number of 1's and 0 otherwise. You will also discover that any number XOR'ed with itself is 0 and that is doesn't matter in what order you do the calculations, e.g. 1^1^(0^1) = 1^(1^0)^1.
This means that when you XOR all the numbers in your list, the ones which are duplicates (or present an even number of times) will XOR to 0 and you will be left with just the one which is present an odd number of times.
As it is obvious from the name(bitwise), it operates between bits.
Let's see how it works,
for example, we have two numbers a=3 and b=4,
the binary representation of 3 is 011 and of 4 is 100, so basically xor of the same bits is 0 and for opposite bits, it is 1.
In the given example 3^4, where "^" is a xor symbol, will give us 111 whose decimal value will be 7.
for another example, if you've given an array in which every element occurs twice except one element & you've to find that element.
How can you do that? simple xor of the same numbers will always be 0 and the number which occur exactly once will be your output. because the output of any one number with 0 will be the same name number because the number will have set bits which zero don't have.

How to analyze this pseudocode

I have the following pseudocode:
sum<-0
inc<-0
for i from 1-n
for j from 1 to i
sum<-sum+inc
inc<-inc+1
I am asked to find a closed formula. The hint is to use common summations. No matter how I look at it I cannot write this code in summation form. Can someone give me an idea of what the summations would look like or even a recursive formula?
Assuming the for i from 1-n means:
for i from 1 to n
A closed formula for that can be obtained through some numerical analysis. Let's examine the number of times through the loop for a couple of values of n (5 and 6).
The outer loop is always n times and the inner loop is whatever i is for each iteration, so for values of n, here are the iteration counts:
n count
= ===========================================
1 (1) = 1
2 (1),(12) = 3
3 (1),(12),(123) = 6
4 (1),(12),(123),(1234) = 10
5 (1),(12),(123),(1234),(12345) = 15
6 (1),(12),(123),(1234),(12345),(123456) = 21
The closed formula for these is best illustrated as follows:
n = 5: 5 + 4 + 3 + 2 + 1
| | | | |
| | V | |
| | 3 | | Formula is: (n+1)*((n-1)/2) + ((n+1)/2)
| +-> 6 <-+ | [outer pair sets] + [inner value]
+-----> 6 <-----+
--
15
This is a formula for all odd values of n. For even values, a similar method can be used:
n = 6: 6 + 5 + 4 + 3 + 2 + 1
| | | | | |
| | +-> 7 <-+ | | Formula is: (n+1)*(n/2)
| +-----> 7 <-----+ | [outer pair sets]
+---------> 7 <---------+
--
21
This tells you the number of iterations of the nested loop for each value of n (we'll call this x).
The calculation of the final value of sum is very similar. On the first iteration you add zero. On the second iteration, you add one. On the third iteration, you add two. That's pretty much exactly the same thing you had to do to figure out the number of iterations, only now it's based on x rather than n and it's 0+1+2+... rather than 1+2+3+..., meaning we can use exactly the same formula just by applying it to x-1 rather than x.
So we can use:
if n is odd:
x <- (n+1) * ((n-1)/2) + ((n+1)/2)
else:
x <- (n+1) * (n/2)
x <- x - 1
if x is odd:
sum <- (x+1) * ((x-1)/2) + ((x+1)/2)
else:
sum <- (x+1) * (x/2)
Checking this against the algorithm for the first few values on n:
n algorithm formula
- --------- -------
0 0 0
1 0 0
2 3 3
3 15 15
4 45 45
5 105 105
So, a perfect match, at least withing the sample space chosen. You could actually go further and turn that into a single formula based on n alone rather than working out an intermediate value, but I'll leave that as an exercise for the reader.
Hint: A C formula which works for both odd and even numbers is:
x <- ((n+1) * ((n-(n%2))/2)) + ((n%2) * ((n+1)/2))
(though still not tested for negative values of n - you should put a check for that before you use the formulaic version).
Innermost loop (let's just call i a fixed number):
inc is incremented i times.
sum has inc added to it i times. (i*(i-1)/2, right?)
If we assume that inc and sum start art value 0, then that's valid. If we assume that they start at some different value, let's call them k and l, then we know that inc will end up at value k+i. We know that sum will end up at l+k*i + i*(i-1)/2.
Now, i itself is going from 1 to n. Um... hum. Let me think about this a bit more.

Resources