Avoiding while loops - algorithm

This isn't strictly speaking a coding question as I'm in charge of a spreadsheet rather than code, but the same principles apply.
I'm trying to create a piece of my spreadsheet that is an "average predictor". As an example: say a batsman has an average of 24 from 40 innings (in other words, has scored 960 runs). If he consistently performs at an average of 40 runs per innings from here on in, how many innings will it take for him to raise his career average to 30?
It's pretty easy to work this example out by hand, and just as easy to solve the general problem with a while loop. However, as mentioned, I can't use loops. Any ideas or suggestions?

You don't need a loop for this purpose. You can solve it by using the following formula (moving average):
(current_avg * current_innings + avg * x)/(current_innings + x) = goal_avg
You have to solve the equation for x.
Your example calculated on Wolfram Alpha:
Input: (24 * 40 + 40 * x)/(40 + x) = 30 solve x
Result: x=24
Link

As recommended by #StriplingWarrior in a comment on the question, write out the general equation, solve it algebraically, and use the resulting formula in your spreadsheet. The raw equation is given in the prior answer by #trylimits. I'm using slightly different identifiers to bring out the symmetry of the problem:
(old_avg * old_innings + new_avg * new_innings)/(old_innings + new_innings)
= goal_avg
old_avg * old_innings + new_avg * new_innings
= goal_avg * (old_innings + new_innings)
old_avg * old_innings + new_avg * new_innings
= goal_avg * old_innings + goal_avg * new_innings
new_avg * new_innings - goal_avg * new_innings
= goal_avg * old_innings - old_avg * old_innings
new_innings * (new_avg - goal_avg) = old_innings * (goal_avg - old_avg)
If new_avg - goal_avg is zero there is no solution unless goal_avg - old_avg is also zero, in which case no change is required and new_innings can be zero. If new_avg - goal_avg is non-zero:
new_innings = old_innings * (goal_avg - old_avg) / (new_avg - goal_avg)
The right hand side of this equation is a formula you could put in a spreadsheet.
The values from the example are:
old_avg = 24
old_innings = 40
new_avg = 40
goal_avg = 30
new_innings = 40 * (30 - 24) / (40 - 30)
= 240 / 10
= 24

Related

Creating Filter Co-Efficient Types for a biquad?

i have a biquad filter which i want to use with different filter types.
to calculate the biquad coefficients for a onepole lowpass with butterworth topology i am using the following:
**A0** = (1.0/(1.0 + sqrt(2.)*(1.0/tanh(pi*(F/SR))) + (1.0/tanh(pi*(F/SR))) * (1.0/tanh(pi*(F/SR)))))
**A1** = (1.0/(1.0 + sqrt(2.)*(1.0/tanh(pi*(F/SR))) + (1.0/tanh(pi*(F/SR))) * (1.0/tanh(pi*(F/SR))))) * 2.
**A2** = (1.0/(1.0 + sqrt(2.)*(1.0/tanh(pi*(F/SR))) + (1.0/tanh(pi*(F/SR))) * (1.0/tanh(pi*(F/SR)))))
**B1** = 2.0*(1.0/(1.0 + sqrt(2.)*(1.0/tanh(pi*(F/SR))) + (1.0/tanh(pi*(F/SR))) * (1.0/tanh(pi*(F/SR))))) * (1.0 - (1.0/tanh(pi*(F/SR)))*(1.0/tanh(pi*(F/SR))))
**B2** = (1.0/(1.0 + sqrt(2.)*(1.0/tanh(pi*(F/SR))) + (1.0/tanh(pi*(F/SR))) * (1.0/tanh(pi*(F/SR))))) * (1.0 - sqrt(2.0) * (1.0/tanh(pi*(F/SR))) + (1.0/tanh(pi*(F/SR)))*(1.0/tanh(pi*(F/SR))))
i also have butterworth highpass, bandpass, and bandreject working. (and of course, "classic" biquad coeffs)
in order to do the same for other filter types such as elliptic, chebychev, or whatever might exist i tried to derive code in the form i need from comparing existing code, e.g. from matlab - but i dont get it to work at all.
Would somebody be able to provide me the correct math for whatever other filter types in a similar manner than above?
(F = Frequency in Hertz, which is the only variable/input to this expression)

Ruby algorithms loops codewars

I got stuck with below task and spent about 3 hours trying to figure it out.
Task description: A man has a rather old car being worth $2000. He saw a secondhand car being worth $8000. He wants to keep his old car until he can buy the secondhand one.
He thinks he can save $1000 each month but the prices of his old car and of the new one decrease of 1.5 percent per month. Furthermore this percent of loss increases by 0.5 percent at the end of every two months. Our man finds it difficult to make all these calculations.
How many months will it take him to save up enough money to buy the car he wants, and how much money will he have left over?
My code so far:
def nbMonths(startPriceOld, startPriceNew, savingperMonth, percentLossByMonth)
dep_value_old = startPriceOld
mth_count = 0
total_savings = 0
dep_value_new = startPriceNew
mth_count_new = 0
while startPriceOld != startPriceNew do
if startPriceOld >= startPriceNew
return mth_count = 0, startPriceOld - startPriceNew
end
dep_value_new = dep_value_new - (dep_value_new * percentLossByMonth / 100)
mth_count_new += 1
if mth_count_new % 2 == 0
dep_value_new = dep_value_new - (dep_value_new * 0.5) / 100
end
dep_value_old = dep_value_old - (dep_value_old * percentLossByMonth / 100)
mth_count += 1
total_savings += savingperMonth
if mth_count % 2 == 0
dep_value_old = dep_value_old - (dep_value_old * 0.5) / 100
end
affordability = total_savings + dep_value_old
if affordability >= dep_value_new
return mth_count, affordability - dep_value_new
end
end
end
print nbMonths(2000, 8000, 1000, 1.5) # Expected result[6, 766])
The data are as follows.
op = 2000.0 # current old car value
np = 8000.0 # current new car price
sv = 1000.0 # annual savings
dr = 0.015 # annual depreciation, both cars (1.5%)
cr = 0.005. # additional depreciation every two years, both cars (0.5%)
After n >= 0 months the man's (let's call him "Rufus") savings plus the value of his car equal
sv*n + op*(1 - n*dr - (cr + 2*cr + 3*cr +...+ (n/2)*cr))
where n/2 is integer division. As
cr + 2*cr + 3*cr +...+ (n/2)*cr = cr*((1+2+..+n)/2) = cr*(1+n/2)*(n/2)
the expression becomes
sv*n + op*(1 - n*dr - cr*(1+(n/2))*(n/2))
Similarly, after n years the cost of the car he wants to purchase will fall to
np * (1 - n*dr - cr*(1+(n/2))*(n/2))
If we set these two expressions equal we obtain the following.
sv*n + op - op*dr*n - op*cr*(n/2) - op*cr*(n/2)**2 =
np - np*dr*n - np*cr*(n/2) - np*cr*(n/2)**2
which reduces to
cr*(np-op)*(n/2)**2 + (sv + dr*(np-op))*n + cr*(np-op)*(n/2) - (np-op) = 0
or
cr*(n/2)**2 + (sv/(np-op) + dr)*n + cr*(n/2) - 1 = 0
If we momentarily treat (n/2) as a float division, this expression reduces to a quadratic.
(cr/4)*n**2 + (sv/(np-op) + dr + cr/2)*n - 1 = 0
= a*n**2 + b*n + c = 0
where
a = cr/4 = 0.005/4 = 0.00125
b = sv/(np-op) + dr + cr/(2*a) = 1000.0/(8000-2000) + 0.015 + 0.005/2 = 0.18417
c = -1
Incidentally, Rufus doesn't have a computer, but he does have an HP 12c calculator his grandfather gave him when he was a kid, which is perfectly adequate for these simple calculations.
The roots are computed as follows.
(-b + Math.sqrt(b**2 - 4*a*c))/(2*a) #=> 5.24
(-b - Math.sqrt(b**2 - 4*a*c))/(2*a) #=> -152.58
It appears that Rufus can purchase the new vehicle (if it's still for sale) in six years. Had we been able able to solve the above equation for n/2 using integer division it might have turned out that Rufus would have had to wait longer. That’s because for a given n both cars would have depreciated less (or at least not not more), and because the car to be purchased is more expensive than the current car, the difference in values would be greater than that obtained with the float approximation for 1/n. We need to check that, however. After n years, Rufus' savings and the value of his beater will equal
sv*n + op*(1 - dr*n - cr*(1+(n/2))*(n/2))
= 1000*n + 2000*(1 - 0.015*n - 0.005*(1+(n/2))*(n/2))
For n = 6 this equals
1000*6 + 2000*(1 - 0.015*6 - 0.005*(1+(6/2))*(6/2))
= 1000*6 + 2000*(1 - 0.015*6 - 0.005*(1+3)*3)
= 1000*6 + 2000*0.85
= 7700
The cost of Rufus' dream car after n years will be
np * (1 - dr*n - cr*(1+(n/2))*(n/2))
= 8000 * (1 - 0.015*n - 0.005*(1+(n/2))*(n/2))
For n=6 this becomes
8000 * (1 - 0.015*6 - 0.005*(1+(6/2))*(6/2))
= 8000*0.85
= 6800
(Notice that the factor 0.85 is the same in both calculations.)
Yes, Rufus will be able to buy the car in 6 years.
def nbMonths(old, new, savings, percent)
percent = percent.fdiv(100)
current_savings = 0
months = 0
loop do
break if current_savings + old >= new
current_savings += savings
old -= old * percent
new -= new * percent
months += 1
percent += 0.005 if months.odd?
end
[months, (current_savings + old - new).round]
end

work out how many seconds have expired in total during game play

~Why the hell has this had down votes.... you people are weird!
Ok so this is a very simply HTML5 and jQuery and PHP game. Sorry to the people who have answered, I forgot to say this is a php script, i have updated here to reflect.
the first level takes 1 minute. Every level after that takes an extra 10 seconds than the last level. like so;
level 1 = 60 seconds
level 2 = 70 seconds
level 3 = 80 seconds
level 4 = 90 seconds
and so on infinitely.
I need an equation that can figure out what is the total amount of seconds played based on the users level.
level = n
i started with (n * 10) + (n * 60) but soon realized that that doesn't account for the last level already being 10 seconds longer than the last. I have temporarily fixed it using a function calling a foreach loop stopping at the level number and returning the value. but i really want an actual equation.
SO i know you wont let me down :-)
Thanks in advance.
this is what i am using;
function getnumberofsecondsfromlevel($level){
$lastlevelseconds = 60;
while($counter < $level){
$totalseconds = $lastlevelseconds+$totalseconds;
$lastlevelseconds = $lastlevelseconds + 10;
$counter++;
}
return $totalseconds;
}
$level = $_SESSION['**hidden**']['thelevel'];
$totaldureationinseconds = getnumberofsecondsfromlevel($level);
but i want to replace with an actual equation
like so;(of course this is wrong, this is just the example of the format i want it in i.e an equation)
$n = $_SESSION['**hidden**']['thelevel']; (level to get total value of
in seconds)
$s = 60; (start level)
$totaldureationinseconds = ($n * 10) + ($s * $n);
SOLVED by Gopalkrishna Narayan Prabhu :-)
$totalseconds = 60 * $level + 5* (($level-1) * $level);
var total_secs = 0;
for(var i = 1; i<= n ;i++){
total_secs = total_secs + (i*10) + 50;
}
for n= 1, total_secs = 0 + 10 + 50 = 60
for n= 2, total_secs = 60 + 20 + 50 = 130
and so on...
For a single equation:
var n = level_number;
total_secs = 60 * n + 5* ((n-1) * n);
Hope this helps.
It seems as though you're justing looking for the equation
60 + ((levelN - 1) * 10)
Where levelN is the current level, starting at 1. If you make the first level 0, you can get rid of the - 1 part and make it just
60 + (levelN * 10)
Thought process:
What's the base/first number? What's the lowest it can ever be? 60. That means your equation will start with
60 + ...
Every time you increase the level, you add 10, so at some point you'll need something like levelN * 10. Then, it's just some fiddling. In those case, since you don't add any on the first left, and the first level is level 1, you just need to subtract 1 from the level number to fix that.
You can solve this with a really simple mathematical phrase (with factorial).
((n-1)! * 10) + (60 * n)
n is the level ofcourse.

How do I find the expression for where the first derivative equals 0?

I have a simple function of time. If I take the first derivative and set it equal to 0.0 I get the extrema of that function. I'm not interested in a numerical result, I want an expresion involving time and the rest of the parameters in my equations.
Solve[] gives Solve::nsmet: This system cannot be solved with the methods available to Solve.
How do I get an expression by setting the first derivative equal to 0.0? My code is below. (I've solved this on paper. I want Mathematica to give some plots and typeset the equations.)
Related question: The step that computes the derivative gives a result that includes this expression: Sqr'[-p1x + p2x - t v1x + t v2x]. What is Sqr', the Sqr function followed by an apostrophe?
Thanks.
p1tx = p1x + v1x*t
p1ty = p1y + v1y*t
p1t = p1xt + p1yt
p2tx = p2x + v2x*t
p2ty = p2y + v2y*t
p2t = p2xt + p2yt
dt = Sqrt[Sqr[p2tx - p1tx] + Sqr[p2ty - p1ty]]
firstDeriv = D[dt,t]
Solve[firstDeriv==0,t]
What is Sqr', the Sqr function followed by an apostrophe
I think it is just a typo dt = Sqrt[Sqrt[p2tx - p1tx] + Sqrt[p2ty - p1ty]]
{{t -> (-p1y v1x^2 + p2y v1x^2 + p1x v1y^2 - p2x v1y^2 +
2 p1y v1x v2x - 2 p2y v1x v2x - p1y v2x^2 + p2y v2x^2 -
2 p1x v1y v2y + 2 p2x v1y v2y + p1x v2y^2 -
p2x v2y^2)/((v1y - v2y) (v1x^2 - v1x v1y - 2 v1x v2x + v1y v2x +
v2x^2 + v1x v2y - v2x v2y))}}
ps: I've solved this on paper So, how does your equation for derivative look like?

How to design search algorithm to find set of items that are most relevant to the query?

A store has 3 products in its catalogue. Each product has assigned probability of belonging to 4 classes: colour_yellow, colour_red, gender_male, gender_female.
product_1 = colour_yellow(p=0.7),colour_red(p=0.4),gender_male(p=0),gender_female(p=1)
product_2 = colour_yellow(p=0.3),colour_red(p=0.8),gender_male(p=1),gender_female(p=0)
product_3 = colour_yellow(p=0.1),colour_red(p=0.4),gender_male(p=1),gender_female(p=1)
Mary has access to an electronic catalogue where she is asked how does she feel about these 4 classes, so that store bot can recommend her best products. She answered, I like colour_yellow a lot, and colour_reda little, and I also seek gender_female products only.
How to calculate each products recommendation score to Mary's preferences ?:
I am thinking to solve it by by computing one value for each product by multiplying probability values for same category across products by 100, 1000, 10000 etc (to accommodate for positional values) and then sum it, so that the final value could be compared with query value. Example:
Product scores:
val product_1 = (0.7 * 100) + (0.4 * 1000) + (0 * 10000) + (1 * 100000)
val product_2 = (0.3 * 100) + (0.8 * 1000) + (1 * 10000) + (0 * 100000)
val product_3 = (0.1 * 100) + (0.4 * 1000) + (1 * 10000) + (0 * 100000)
and Mary's query score
val q = ((1 * 100) + weight 7) + ((1 * 1000) + weigh 3) + (0 * 10000) + (1 * 100000)
with results as:
product_1: 10,470
product_2: 1,830
product_3: 11,410
query: 11,100 (without weights)
Give these results store could infer to recommend product_3 and product_1 with confidence of perfect match for product_3 as query - product_3: 11,100 - 11,410
Am I on a right track ?
solved it by using cosine-similarity-algorithm

Resources