Is there a way to do a nested FOR loop in Excel? - excel

If have the following two columns with the values:
A B
1 1
2 2
3 3
4 4
How can I multiply and return the sum:
1* 1 + 1 * 2 + 1* 3 + 1 * 4 + 2 * 1 + 2 * 2 + ... 4 * 4
exactly like a nested FOR loop?
Similarly, how can I multiply and sum only when first column value is bigger than second:
2 * 1 + 3 * 1 + 3 * 2 + 4 * 1 + 4 * 2 + 4 * 3 ?

With formula I think what is required, assuming A1:E1 and A1:A4 as shown, may be:
(1) The sum of B1:E4 where B2 copied across and down is:
=$A2*B$1
Alternatively the array formula with layout as you show:
=SUM(MMULT(A2:A5,TRANSPOSE(B2:B5)))
answer 100, and
(2) in B2 copied across and down and then B2:E4 summed:
=IF($A2>B$1,$A2*B$1,0)
answer 35.

Related

recursive function does not work as expected

Could someone explain the code? I just can not understand why this code gives output like this:
1
3
6
10
15
21
I expected the code to give something like this:
1
3
5
7
9
11
What am I missing here?
def tri_recursion(k):
if(k > 0):
result = k + tri_recursion(k-1)
print(result)
else:
result = 0
return result
tri_recursion(6)
For your recursive function, the termination condition is k=0.
It's clear that if k=0, tri_recursion(0) = 0.
If k=1, tri_recursion(1) = 1 + tri_recursion(0), which from above, is 1 + 0 or 1.
If k=2, tri_recursion(2) = 2 + tri_recursion(1), which from above, is 2 + 1 or 3.
If k=3, tri_recursion(3) = 3 + tri_recursion(2), which from above, is 3 + 3 or 6.
If k=4, tri_recursion(4) = 5 + tri_recursion(3), which from above, is 4 + 6 or 10.
If k=5, tri_recursion(5) = 4 + tri_recursion(4), which from above, is 5 + 10 or 15.
If k=6, tri_recursion(6) = 6 + tri_recursion(5), which from above, is 6 + 15 or 21.
See the pattern?
Your code is calculating the sum of numbers up to n where n is 6 in the above case. The print statement prints the intermediate results. Hence the output 1 3 6 10 15 21.
1 - The sum of numbers from 0 to 1
3 - The sum of numbers from 0 to 2
6 - The sum of numbers from 0 to 3
10 - The sum of numbers from 0 to 4
15 - The sum of numbers from 0 to 5
21 - The sum of numbers from 0 to 6

Multiple For Loop Iterations (Combination) with filter to achieve highest possible value

I have a set of "Points" & it's "Value".
I want to get highest possible "Value" from combination of "Points".
Example:
My Target Point: 100
Point Value
1 111
2 222
3 333
4 444
5 555
6 666
7 777
8 888
9 999
10 1110
11 1221
12 1332
13 1443
14 1554
15 1665
16 1776
17 1887
18 1998
19 2109
20 2220
There can be TRILLIONS of combination but I need only those combinations upto "My Target Point" yielding Highest "Value".
Possible Answers:
1. (Point 16)*2 + (Point 17)*4 = 100
(Value 1776)*2 + (Value 1887)*4 = 11100
2. (Point 1)*100 = 100
(Value 111)*100 = 11100
& so on.....
So finally I need just one (any) combination with highest value.
amt2 = 0
For i20 = 0 To 5 ' (Max multiple -> 100/20 = 5)
For i19 = 0 To 5 ' (Max multiple -> 100/19 = 5)
For i18 = 0 To 5
For i17 = 0 To 5
For i16 = 0 To 6
For i15 = 0 To 6
For i14 = 0 To 7
For i13 = 0 To 7
For i12 = 0 To 8
For i11 = 0 To 9
For i10 = 0 To 10
For i9 = 0 To 11
For i8 = 0 To 12
For i7 = 0 To 14
For i6 = 0 To 16
For i5 = 0 To 20
For i4 = 0 To 25
For i3 = 0 To 33
For i2 = 0 To 50
For i1 = 0 To 100 ' (Max multiple -> 100/1 = 1)
point1 = (1 * i1) + (2 * i2) + (3 * i3) + (4 * i4) + (5 * i5) + (6 * i6) + (7 * i7) + (8 * i8) + (9 * i9) + (10 * i10) + (11 * i11) + (12 * i12) + (13 * i13) + (14 * i14) + (15 * i15) + (16 * i16) + (17 * i17) + (18 * i18) + (19 * i19) + (20 * i20))
If point1 <= 100 Then
amt1 = (111 * i1) + (222 * i2) + (333 * i3) + (444 * i4) + (555 * i5) + (666 * i6) + (777 * i7) + (888 * i8) + (999 * i9) + (1110 * i1 + (1221 * i11) + (1332 * i12) + (1443 * i13) + (1554 * i14) + (1665 * i15) + (1776 * i16) + (1887 * i17) + (1998 * i18) + (2109 * i19) + (2220 * i20)
If amt2 < amt1 Then
amt2 = amt1
<Save Combination Details>
End If
End If
Next i1
Next i2
Next i3
Next i4
Next i5
Next i6
Next i7
Next i8
Next i9
Next i10
Next i11
Next i12
Next i13
Next i14
Next i15
Next i16
Next i17
Next i18
Next i19
Next i20
Problem with my code is that it iterates through ALL possible combinations which takes lots of time & produce little result.
"Trillions" underestimates how much work your code is trying to do. Your code would pass through the innermost loop 1.94*10^21 times, which at the rate of 10 million passes per second (about the most VBA could give) would take over 6 million years. Instead, just use the Solver add-in to solve what is a fairly straightforward integer programming problem.
Set up your spreadsheet something like this:
Your data is in columns A:B, I added a new column of decision variables, a constraint cell in D2, and an objective function in E2.
The formula in D2 is:
=SUMPRODUCT(A2:A21,C2:C21)
and in E2 it is:
=SUMPRODUCT(B2:B21,C2:C21)
Then I simply ask the solver to find the maximum of cell E2 by changing cells C2:C21 subject to the two constraints that D2 <= 100 and that C2:C21 are integers. I keep the default setting that variables are assumed to be nonnegative, and tell the solver to use the Simplex method (which under the hood will use branch-and-bound for solving this ILP). The optimal solution according to the Solver (found in less than a second as opposed to 6 million years) is 10*Point1 + 6*Point15 with a total value of 11100 -- which happens to be a value that you have already found, showing that this problem has multiple optima.
It is possible but not easy to do this all in VBA, since the solver add-in can be invoked in code. See this for a basic introduction.

Python recursive index changing

I am trying to arrange matrix in way that it will dynamically change the indexes.
I have tried to do it by means of for loop, however it only does once for each index.
def arrangeMatrix(progMatrix):
for l in range(len(progMatrix)):
for item in range(len(progMatrix[l])):
if indexExists(progMatrix,l + 1,item) and progMatrix[l + 1][item] == " ":
progMatrix[l + 1][item] = progMatrix[l][item]
progMatrix[l][item] = " "
The original list is:
1 0 7 6 8
0 5 5 5
2 1 6
4 1 3 7
1 1 1 7 5
And my code should fill all gapped indexes from up to bottom, however my result is:
1 0 6 8
0 5 5
2 1 7
4 1 3 7 6
1 1 1 7 5 5
The actual result should be:
1 0
0 5 8
2 1 7 5
4 1 3 7 6 6
1 1 1 7 5 5
Any help or hint is appreciated.Thanks in advance
It is probably easier if you first iterate the columns, since the change that happens in one column is independent on what happens in other columns. Then, per column, you could iterate the cells from the bottom to the top and keep track of the y-coordinate where the next non-space should "drop down" to.
No recursion is needed.
Here is how that could be coded:
def arrangeMatrix(progMatrix):
for x in range(len(progMatrix[0])):
targetY = len(progMatrix)-1
for y in range(len(progMatrix)-1,-1,-1):
row = progMatrix[y]
if row[x] != " ": # Something to drop down
if y < targetY: # Is it really to drop any lower?
progMatrix[targetY][x] = row[x] # copy it down
row[x] = " " # ...and clear the cell where it dropped from
targetY -= 1 # since we filled the target cell, the next drop would be higher

Excel sum only single or first duplicated value in a list

I've a formula in Excel which I've found on the net which gives the required result but I don't fully understand how it works. This is =SUMPRODUCT(B1:B9/COUNTIF(A1:A9,A1:A9)) and the result is 129 for the following data (it adds single occurrences in Column B of the data, this being 13 + 24 + 92 = 129 which is the required result).
Row A B
1 1 13
2 1 13
3 1 13
4 1 13
5 3 24
6 3 24
7 3 24
8 12 92
9 12 92
I understand the COUNTIF(A1:A9,A1:A9) is creating an array {4;4;4;4;3;3;3;2;2) but I don't know how the range B1:B9 numerator is working to create the result. If the numerator was say the number "1" (i.e. the formula being instead =SUMPRODUCT(1/COUNTIF(A1:A9,A1:A9)), the result is 3 and I think is worked out as the sum of 1/4 + 1/4 + 1/4 + 1/4 + 1/3 + 1/3 + 1/3 + 1/2 + 1/2. So how when the B1:B9 is in the formula how step by step is it working it out?
You are pretty close to the answer yourself. Given your example you have two arrays:
The first one is the numbers from column B and the other one from the countif in column A:
{13;13;13;13;24;24;24;92;92} and {4;4;4;4;3;3;3;2;2}
In the sumproduct formula you have the division and therefore you get the arrays divided:
{13/4; 13/4; 13/4; 13/4; 24/3; 24/3; 24/3; 92/2; 92/2} and the sum of these numbers are:
3,25 + 3,25 + 3,25 + 3,25 + 8 + 8 + 8 + 46 + 46 = 129
And there is the magic number :-)

Why does Excel average gives different result?

Here's the table:
Should not they have the same result mathematically? (the average score of the per column and per row average)
The missing cells mean that your cells aren't all weighted evenly.
For example, row 11 has only two cells 82.67 and 90. So for your row average for row 11 they are weighted much more heavily than in your column averages where they are 1/13 and 1/14 of a column instead of 1/2 of a row.
Try filling up all the empty cells with 0 and the averages should match.
Taking a more extreme version of Ruslan Karaev's example:
5 5 5 | 5
1 | 1 Average of Average of Rows = (5 + 1 + 0) / 3 = 2
0 | 0
-----
2 5 5
Average of Average of Columns = (2 + 5 + 5) / 3 = 4
Yes, for example, the following two expressions:
/ a + b X + Y \ / a + X b + Y \
( ----- + ----- ) ( ----- + ----- )
\ 2 2 / \ 2 2 /
------------------- -------------------
2 2
are indeed mathematically equivalent, both coming out to be (a + b + X + Y) / 4.
However, short of having enough sufficient precision to store values, you may find that rounding errors accumulate differently depending on the order of operations.
You can see this sort of effect in a much simpler example if you assume a 3-digit precision and divide one by three, then multiply the result of that by three again:
1 / 3 -> 0.333, 0.333 x 3 -> 0.999
Contrast that with doing the operations in the oppisite order:
1 x 3 = 3, 3 / 1 = 1

Resources