AS2: How to iterate X times through a percentage calculation (containing a circular reference)? - excel

Here is a question for the Excel / math-wizards.
I'm having trouble doing a calculation which is based on a formula with a circular reference. The calculation has been done in an Excel worksheet.
I've deducted the following equations from an Excel file:
a = 240000
b = 1400 + c + 850 + 2995
c = CEIL( ( a + b ) * 0.015, 100 )
After the iterations the total of A+B is supposed to be 249045 (where b = 9045).
In the Excel file this gives a circular reference, which is set to be allowed to iterate 4 times.
My problem: Recreate the calculation in AS2, going through 4 iterations.
I am not good enough at math to break this problem down.
Can anyone out there help me?
Edit: I've changed the formatting of the number in variable a. Sorry, I'm from DK and we use period as a thousand separator. I've removed it to avoid confusion :-)
2nd edit: The third equation, C uses Excels CEIL() function to round the number to nearest hundredth.

I don't know action script, but I think you want:
a = 240000
c = 0
for (i = 0; i < 4; i++){
b = 1400 + c + 850 + 2995
c = (a + b) * 0.015
}
But you need to determine what to use for the initial value of c. I assume that Excel uses 0, since I get the same value when running the above as I get in Excel with iterations = 4, c = 3734.69...
Where do you get the "A + B is supposed to be 249045" value? In Excel and in the above AS, b only reaches 8979 with those values.

function calcRegistrationTax( amount, iterations ) {
function roundToWhole( n, to ) {
if( n > 0 )
return Math.ceil( n/ to ) * to;
else if( n < 0)
return Math.floor( n/ to ) * to;
else
return to;
}
var a = amount;
var b = 0;
var c = 0
for (var i = 0; i < iterations; i++){
b = basicCost + ( c ) + financeDeclaration + handlingFee;
c = ( a + b ) * basicFeeRatio;
c = roundToWhole( c, 100 );
}
return b;
}
totalAmount = 240000 + calcRegistrationTax( 240000, 4 ); // This gives 249045
This did it, thanks to Benjamin for the help.

Related

Get If (condition), then (assign value), else (assign other value) statement in Linear Programming

I'm looking for a linear programming equation that satisfied the conditions;
Given that all variables here are binary variables
if A+B = 2; then C = 1; else C = 0
Also,
if A+B+D = 3; then E = 1; else E = 0
How would one phrase this and satisfy these conditions as well as linearity conditions?
I've tried
A + B - 2 <= M(1-y) and 1 - C <= My
for the first constraint but it doesn't seem to work
For the first equation, you can use:
C + 1 >= A + B
2C <= A + B
If there is a natural sense (max/min) for C in the problem, one of those is sufficient.
Similarly for the second:
E + 2 >= A + B + D
3E <= A + B + D

An internal unit of company XYZ provides services to other departments

Example 1:
``
Given S="300.01" and B-["300.00", "200.00*,*100.00"].
R[0]="150.00" (=300.01 300.00/600.00) R[1]="100.00" (=150.01* 200.00/300.00)
R[2]="50.01" (=50.01*100.00/100.00)
Example 2 (Pay careful attention to this one).
Given S="1.00" and B=["0.05","1.00"]. 1. First we consider 1.00 because it is the largest,
a. 1.00*1.00/1.05~0.95238...
b. Round 0.95238... to "0.95". Rounding down to carry pennies to smaller departments. c. Set R[1]=0.95. Notice, this is in the same place as 1.00. It is the 2nd value in the result! 2. Now we have 0.05 left
Next we look at the smaller B[0]=0.05 department
a. 0.05 0.05/0.05 = 0.05 b. No rounding required
c. Set R[0]=0.05. R=["0.05", "0.95"]
`
Write a function:
class Solution { public String[] solution(String 5, String[] B); }
that, given a string S representing the total excess billables and an array B consisting of K strings representing the undiscounted bills for each customer. The return value should be an array of strings R (length M) in the same order as B representing the amount of the discount to each customer.
Notes:
The total S should be completely refunded. Neither more nor less than S should be
returned. Don't lose or gain a penny!
Be careful with the types you choose to represent currencies. Floating points numbers are notoriously error prone for precise calculations with currencies.
Test Output
Amounts should be rounded down to the nearest $0.01. By design, fractional pennies are pushed to groups with smaller unadjusted invoices.
Results should be represented with 2 decimal places of precision as strings, even if these are both zeroes. ex. "100.00" 5. You may assume sensible inputs. The total to be discounted will never exceed the total of the
unadjusted invoices.
Please do pay attention to returning the discounts in the same order as the incoming invoices.
Answer:::
def solution(A):
answer = 0
current_sum = 0
#Currently there is one empty subarray with sum 0
prefixSumCount = {0:1}
for list_element in A:
current_sum = current_sum + list_element
if current_sum in prefixSumCount:
answer = answer + prefixSumCount[current_sum]
if current_sum not in prefixSumCount:
prefixSumCount[current_sum] = 1
else:
prefixSumCount[current_sum] = prefixSumCount[current_sum] + 1
if answer > 1000000000:
return -1
else:
return answer
#Sample run
A = [2,-2,3,0,4,-7]
print(solution(A))
strong text
Find my solution for JavaScript
You can avoid function sumArray and use the sum funciton with reducer within solution function.
enter code here
function solution(S, B) {
// write your code in JavaScript (Node.js 8.9.4)
let copyArray=[...B];
let solutionObj={};
//ordered array to consider last first
copyArray.sort();
//calculating sum of values within array
let sumArray=B.reduce((acc,value)=> acc+Number(value),0);
//calculating values of array
//loop for ading on to solvin array
let initial=S;
for(i=copyArray.length-1;i>=0;i--){
//obtaining index of value addded to solution array
let index=B.indexOf(copyArray[i]);
let value=initial*copyArray[i]/sumArray;
value=i==0?Math.ceil(value*100)/100:Math.floor(value*100)/100;
solutionObj[index]=value.toFixed(2);
}
return Object.values(solutionObj) ;
}
console.log(solution(300.01,["300.00","200.00","100.00"]))
console.log(solution(1.00,["0.05","1.00"]))
These are the resulting entries
Solution in java for the same coding exercise
public String[] solution(String S, String[] B) {
List<Double> list = Arrays.stream(B).sorted(Comparator.comparingDouble(v->Double.valueOf((String) v)).reversed()).map(Double::parseDouble).collect(Collectors.toList());
Double S1 = Double.valueOf(S);
String R[] = new String[B.length];
Double total = 0.00;
for (int i = 0; i< list.size(); i++){
Double individualValue = list.get(i);
Double sumTotal = 0.0;
for(int j = i+1;j < list.size(); j++){
sumTotal+=list.get(j);
}
BigDecimal data = new BigDecimal(S1 * (individualValue / (individualValue + sumTotal)));
data = data.setScale(2, RoundingMode.FLOOR);
total+=data.doubleValue();
R[i] = String.valueOf(data);
S1 = S1 - Double.valueOf(R[i]);
}
Double diff = new BigDecimal(Double.valueOf(S) - total).setScale(2, RoundingMode.HALF_DOWN).doubleValue();
if (diff > 0) {
R[B.length - 1] = String.valueOf(Double.valueOf(R[B.length - 1]) + diff);
}
return R;
}

Why is this integer not incrementing twice? [duplicate]

This question already has answers here:
C# Increment operator (++) question:Why am i getting wrong output?
(5 answers)
Closed 8 years ago.
I am confused by the results of the code below. Why does 'b' retain a seemingly incorrect value when doing these operations?
int a = 0;
int b = 5;
a = b++;
b = b++;
Console.WriteLine("For b = b++; b=" + b.ToString()); // b should be 7 but it's 6
a = 0;
b = 5;
a = b--;
b = b--;
Console.WriteLine("For b = b--; b=" + b.ToString()); // b should be 3 but it's 4
a = 0;
b = 5;
a = b + 1;
b = b + 1;
Console.WriteLine("For b = b++; b=" + b.ToString());
Output
b=6
b=4
b=6
Can anyone explain this behavior in C# and how it's working?
That's indeed the behavior of postfix operators, as detailed here.
For instance, when you write:
b = b++;
The following happens:
The current value of b is saved,
b is incremented,
The saved value of b is produced by the postfix ++ operator,
The value produced by the operator is assigned to b.
Therefore, b will indeed be assigned its original value, and the incremented value is lost.
Because the ++ and -- operators when placed after the value will evaluate to the value itself, and then increment/decrement the value after the evaluation.
So:
int a = 0;
int b = a++;
After running this code, b will equal 0 and a will equal 1.
This is as opposed to using the operators as prefixes:
int a = 0;
int b = ++a;
After running this code, b will equal 1 and a will equal 1.
This is documented behavior and has been around for a long time.
The instruction a=b++ is stored on the stack but not evaluated because it was not used after that.
To get the correct result, make that instruction have a sense fro example change that line:
Console.WriteLine("For b = b++; b=" + b.ToString());
by that one:
Console.WriteLine("For a = b++; a=" + a.ToString());
Console.WriteLine("For b = b++; b=" + b.ToString()); //should give 7
When you use
int a = 0;
int b = 5;
a = b++;
b = b++;
You set a to be 6, and after that you set b to be 6.
When you write b to commandline, it presents 6 because a was never used when incrementing b.
If you want to use a as well, you'd have to make
int a = 1;
int b = 5;
b = b++;
b += a;
Console.WriteLine("For b = a + b++; b=" + b.ToString());
But overall I don't see any use in this kind of incrementation.

Minimum no. of comparisons to find median of 3 numbers

I was implementing quicksort and I wished to set the pivot to be the median or three numbers. The three numbers being the first element, the middle element, and the last element.
Could I possibly find the median in less no. of comparisons?
median(int a[], int p, int r)
{
int m = (p+r)/2;
if(a[p] < a[m])
{
if(a[p] >= a[r])
return a[p];
else if(a[m] < a[r])
return a[m];
}
else
{
if(a[p] < a[r])
return a[p];
else if(a[m] >= a[r])
return a[m];
}
return a[r];
}
If the concern is only comparisons, then this should be used.
int getMedian(int a, int b , int c) {
int x = a-b;
int y = b-c;
int z = a-c;
if(x*y > 0) return b;
if(x*z > 0) return c;
return a;
}
int32_t FindMedian(const int n1, const int n2, const int n3) {
auto _min = min(n1, min(n2, n3));
auto _max = max(n1, max(n2, n3));
return (n1 + n2 + n3) - _min - _max;
}
You can't do it in one, and you're only using two or three, so I'd say you've got the minimum number of comparisons already.
Rather than just computing the median, you might as well put them in place. Then you can get away with just 3 comparisons all the time, and you've got your pivot closer to being in place.
T median(T a[], int low, int high)
{
int middle = ( low + high ) / 2;
if( a[ middle ].compareTo( a[ low ] ) < 0 )
swap( a, low, middle );
if( a[ high ].compareTo( a[ low ] ) < 0 )
swap( a, low, high );
if( a[ high ].compareTo( a[ middle ] ) < 0 )
swap( a, middle, high );
return a[middle];
}
I know that this is an old thread, but I had to solve exactly this problem on a microcontroller that has very little RAM and does not have a h/w multiplication unit (:)). In the end I found the following works well:
static char medianIndex[] = { 1, 1, 2, 0, 0, 2, 1, 1 };
signed short getMedian(const signed short num[])
{
return num[medianIndex[(num[0] > num[1]) << 2 | (num[1] > num[2]) << 1 | (num[0] > num[2])]];
}
If you're not afraid to get your hands a little dirty with compiler intrinsics you can do it with exactly 0 branches.
The same question was discussed before on:
Fastest way of finding the middle value of a triple?
Though, I have to add that in the context of naive implementation of quicksort, with a lot of elements, reducing the amount of branches when finding the median is not so important because the branch predictor will choke either way when you'll start tossing elements around the the pivot. More sophisticated implementations (which don't branch on the partition operation, and avoid WAW hazards) will benefit from this greatly.
remove max and min value from total sum
int med3(int a, int b, int c)
{
int tot_v = a + b + c ;
int max_v = max(a, max(b, c));
int min_v = min(a, min(b, c));
return tot_v - max_v - min_v
}
There is actually a clever way to isolate the median element from three using a careful analysis of the 6 possible permutations (of low, median, high). In python:
def med(a, start, mid, last):
# put the median of a[start], a[mid], a[last] in the a[start] position
SM = a[start] < a[mid]
SL = a[start] < a[last]
if SM != SL:
return
ML = a[mid] < a[last]
m = mid if SM == ML else last
a[start], a[m] = a[m], a[start]
Half the time you have two comparisons otherwise you have 3 (avg 2.5). And you only swap the median element once when needed (2/3 of the time).
Full python quicksort using this at:
https://github.com/mckoss/labs/blob/master/qs.py
You can write up all the permutations:
1 0 2
1 2 0
0 1 2
2 1 0
0 2 1
2 0 1
Then we want to find the position of the 1. We could do this with two comparisons, if our first comparison could split out a group of equal positions, such as the first two lines.
The issue seems to be that the first two lines are different on any comparison we have available: a<b, a<c, b<c. Hence we have to fully identify the permutation, which requires 3 comparisons in the worst case.
Using a Bitwise XOR operator, the median of three numbers can be found.
def median(a,b,c):
m = max(a,b,c)
n = min(a,b,c)
ans = m^n^a^b^c
return ans

Partition line into equal parts

This is a geometry question.
I have a line between two points A and B and want separate it into k equal parts. I need the coordinates of the points that partition the line between A and B.
Any help is highly appreciated.
Thanks a lot!
You just need a weighted average of A and B.
C(t) = A * (1-t) + B * t
or, in 2-D
Cx = Ax * (1-t) + Bx * t
Cy = Ay * (1-t) + By * t
When t=0, you get A.
When t=1, you get B.
When t=.25, you a point 25% of the way from A to B
etc
So, to divide the line into k equal parts, make a loop and find C, for t=0/k, t=1/k, t=2/k, ... , t=k/k
for(int i=0;i<38;i++)
{
Points[i].x = m_Pos.x * (1 - (i/38.0)) + m_To.x * (i / 38.0);
Points[i].y = m_Pos.y * (1 - (i/38.0)) + m_To.y * (i / 38.0);
if(i == 0 || i == 37 || i == 19) dbg_msg("CLight","(%d)\nPos(%f,%f)\nTo(%f,%f)\nPoint(%f,%f)",i,m_Pos.x,m_Pos.y,m_To.x,m_To.y,Points[i].x,Points[i].y);
}
prints:
[4c7cba40][CLight]: (0)
Pos(3376.000000,1808.000000)
To(3400.851563,1726.714111)
Point(3376.000000,1808.000000)
[4c7cba40][CLight]: (19)
Pos(3376.000000,1808.000000)
To(3400.851563,1726.714111)
Point(3388.425781,1767.357056)
[4c7cba40][CLight]: (37)
Pos(3376.000000,1808.000000)
To(3400.851563,1726.714111)
Point(3400.851563,1726.714111)
which looks fine but then my program doesn't work :D.
but your method works so thanks

Resources