Calculate if trend is up, down or stable - math

I'm writing a VBScript that sends out a weekly email with client activity. Here is some sample data:
a b c d e f g
2,780 2,667 2,785 1,031 646 2,340 2,410
Since this is email, I don't want a chart with a trend line. I just need a simple function that returns "up", "down" or "stable" (though I doubt it will ever be perfectly stable).
I'm terrible with math so I don't even know where to begin. I've looked at a few other questions for Python or Excel but there's just not enough similarity, or I don't have the knowledge, to apply it to VBS.
My goal would be something as simple as this:
a b c d e f g trend
2,780 2,667 2,785 1,031 646 2,340 2,410 ↘
If there is some delta or percentage or other measurement I could display that would be helpful. I would also probably want to ignore outliers. For instance, the 646 above. Some of our clients are not open on the weekend.

First of all, your data is listed as
a b c d e f g
2,780 2,667 2,785 1,031 646 2,340 2,410
To get a trend line you need to assign a numerical values to the variables a, b, c, ...
To assign numerical values to it, you need to have little bit more info how data are taken. Suppose you took data a on 1st January, you can assign it any value like 0 or 1. Then you took data b ten days later, then you can assign value 10 or 11 to it. Then you took data c thirty days later, then you can assign value 30 or 31 to it. The numerical values of a, b, c, ... must be proportional to the time interval of the data taken to get the more accurate value of the trend line.
If they are taken in regular interval (which is most likely your case), lets say every 7 days, then you can assign it in regular intervals a, b, c, ... ~ 1, 2, 3, ... Beginning point is entirely your choice choose something that makes it very easy. It does not matter on your final calculation.
Then you need to calculate the slope of the linear regression which you can find on this url from which you need to calculate the value of b with the following table.
On first column from row 2 to row 8, I have my values of a,b,c,... which I put 1,2,3, ...
On second column, I have my data.
On third column, I multiplied each cell in first column to corresponding cell in second column.
On fourth column, I squared the value of cell of first column.
On row 10, I added up the values of the above columns.
Finally use the values of row 10.
total_number_of_data*C[10] - A[10]*B[10]
b = -------------------------------------------
total_number_of_data*D[10]-square_of(A[10])
the sign of b determines what you are looking for. If it's positive, then it's up, if it's negative, then it's down, and if it's zero then stable.

This was a huge help! Here it is as a function in python
def trend_value(nums: list):
summed_nums = sum(nums)
multiplied_data = 0
summed_index = 0
squared_index = 0
for index, num in enumerate(nums):
index += 1
multiplied_data += index * num
summed_index += index
squared_index += index**2
numerator = (len(nums) * multiplied_data) - (summed_nums * summed_index)
denominator = (len(nums) * squared_index) - summed_index**2
if denominator != 0:
return numerator/denominator
else:
return 0
val = trend_value([2781, 2667, 2785, 1031, 646, 2340, 2410])
print(val) # -139.5

in python:
def get_trend(numbers):
rows = []
total_numbers = len(numbers)
currentValueNumber = 1
n = 0
while n < len(numbers):
rows.append({'row': currentValueNumber, 'number': numbers[n]})
currentValueNumber += 1
n += 1
sumLines = 0
sumNumbers = 0
sumMix = 0
squareOfs = 0
for k in rows:
sumLines += k['row']
sumNumbers += k['number']
sumMix += k['row']*k['number']
squareOfs += k['row'] ** 2
a = (total_numbers * sumMix) - (sumLines * sumNumbers)
b = (total_numbers * squareOfs) - (sumLines ** 2)
c = a/b
return c
trendValue = get_trend([2781,2667,2785,1031,646,2340,2410])
print(trendValue) # output: -139.5

Related

Is it possible to find a few common multiples of a list of numbers, without them having to be integers?

I don't even know if something like this is possible, but:
Let us say we have three numbers:
A = 6
B = 7.5
C = 24
I would like to find a few evenly spaced common multiples of these numbers between 0 and 2.
So the requirement is: one_of_these_numbers / common_multiple = an_integer (or almost an integer with a particular tolerance)
For example, a good result would be [0.1 , 0.5 , 1 , 1.5]
I have no idea if this is possible, because one can not iterate through a range of floats, but is there a smart way to do it?
I am using python, but a solution could be represented in any language of your preference.
Thank you for your help!
While I was writing my question, I actually came up with an idea for the solution.
To find common divisors using code, we have to work with integers.
My solution is to multiply all numbers by a factor = 1, 10, 100, ...
so that we can act as if they are integers, find their integer common divisors, and then redivide them by the factor to get a result.
Better explained in code:
a = 6
b = 7.5
c = 24
# Find a few possible divisors between 0 and 2 so that all numbers are divisible
by div.
# We define a function that finds all divisors in a range of numbers, supposing
all numbers are integers.
def find_common_divisors(numbers, range_start, range_end):
results = []
for i in range(range_start + 1, range_end + 1):
if all([e % i == 0 for e in numbers]):
results.append(i)
return results
def main():
nums = [a, b, c]
range_start = 0
range_end = 2
factor = 1
results = [1]
while factor < 11:
nums_i = [e * factor for e in nums]
range_end_i = range_end * factor
results += [e / factor for e in find_common_divisors(nums_i, range_start, range_end_i)]
factor *= 10
print(sorted(set(results)))
if __name__ == '__main__':
main()
For these particular numbers, I get the output:
[0.1, 0.3, 0.5, 1, 1.5]
If we need more results, we can adjust while factor < 11: to a higher number than 11 like 101.
I am curious to see if I made any mistake in my code.
Happy to hear some feedback.
Thank you!

The game with the marbles

Problem: There are R red marbles, G green marbles and B blue marbles (R≤G≤B) Count the number of ways to arrange them in a straight line so that the two marbles next to each other are of different colors.
For example, R=G=B=2, the answer is 30.
I have tried using recursion and of course TLE:
Define r(R,B,G) to be the number of ways of arranging them where the first marble is red. Define b(R,B,G),g(R,B,G) respectively.
Then r(R, B, G) = b(R-1,B,G) + g(R-1,B,G)
And the answer is r(R,B,G) + b(R,B,G) + g(R,B,G)
But we can see that r(R, B, G) = b(B, R, G) ...
So, we just need a function f(x,y,z)=f(y,x−1,z)+f(z,x−1,y)
And the answer is f(x,y,z) + f(y,z,x) + f(z,x,y).
The time limit is 2 seconds.
I don't think dynamic is not TLE because R, G, B <= 2e5
Some things to limit the recursion:
If R>G+B+1, then there is no way to avoid having 2 adjacent reds. (Similar argument for G>R+B+1 & B>R+G+1.)
If R=G+B+1, then you alternate reds with non-reds, and your problem is reduced to how many ways you can arrange G greens and B blacks w/o worrying about adjacency (and should thus have a closed-form solution). (Again, similar argument for G=R+B+1 and B=R+G+1.)
You can use symmetry to cut down the number of recursions.
For example, if (R, G, B) = (30, 20, 10) and the last marble was red, the number of permutations from this position is exactly the same as if the last marble was blue and (R, G, B) = (10, 20, 30).
Given that R ≤ G ≤ B is set as a starting condition, I would suggest keeping this relationship true by swapping the three values when necessary.
Here's some Python code I came up with:
memo = {}
def marble_seq(r, g, b, last):
# last = colour of last marble placed (-1:nothing, 0:red, 1:green, 2:blue)
if r == g == b == 0:
# All the marbles have been placed, so we found a solution
return 1
# Enforce r <= g <= b
if r > g:
r, g = g, r
last = (0x201 >> last * 4) & 0x0f # [1, 0, 2][last]
if r > b:
r, b = b, r
last = (0x012 >> last * 4) & 0x0f # [2, 1, 0][last]
if g > b:
g, b = b, g
last = (0x120 >> last * 4) & 0x0f # [0, 2, 1][last]
# Abort if there are too many marbles of one colour
if b>r+g+1:
return 0
# Fetch value from memo if available
if (r,g,b,last) in memo:
return memo[(r,g,b,last)]
# Otherwise check remaining permutations by recursion
result = 0
if last != 0 and r > 0:
result += marble_seq(r-1,g,b,0)
if last != 1 and g > 0:
result += marble_seq(r,g-1,b,1)
if last != 2 and b > 0:
result += marble_seq(r,g,b-1,2)
memo[(r,g,b,last)] = result
return result
marble_seq(50,60,70,-1) # Call with `last` set to -1 initially
(Result: 205435997562313431685415150793926465693838980981664)
This probably still won't work fast enough for values up to 2×105, but even with values in the hundreds, the results are quite enormous. Are you sure you stated the problem correctly? Perhaps you're supposed to give the results modulo some prime number?

Number of action per year. Combinatorics question

I'm writing a diploma about vaccines. There is a region, its population and 12 month. There is an array of 12 values from 0 to 1 with step 0.01. It means which part of population should we vaccinate in every month.
For example if we have array = [0.1,0,0,0,0,0,0,0,0,0,0,0]. That means that we should vaccinate 0.1 of region population only in first month.
Another array = [0, 0.23,0,0,0,0,0,0, 0.02,0,0,0]. It means that we should vaccinate 0.23 of region population in second month and 0.02 of region population in 9th month.
So the question is: how to generate (using 3 loops) 12(months) * 12(times of vaccinating) * 100 (number of steps from 0 to 1) = 14_400 number of arrays that will contain every version of these combinations.
For now I have this code:
for(int month = 0;month<12;month++){
for (double step = 0;step<=1;step+=0.01){
double[] arr = new double[12];
arr[month] = step;
}
}
I need to add 3d loop that will vary number of vaccinating per year.
Have no idea how to write it.
Idk if it is understandable.
Hope u get it otherwise ask me, please.
You have 101 variants for the first month 0.00, 0.01..1.00
And 101 variants for the second month - same values.
And 101*101 possible combinations for two months.
Continuing - for all 12 months you have 101^12 variants ~ 10^24
It is not possible to generate and store so many combinations (at least in the current decade)
If step is larger than 0.01, then combination count might be reliable. General formula is P=N^M where N is number of variants per month, M is number of months
You can traverse all combinations representing all integers in range 0..P-1 in N-ric numeral system. Or make digit counter:
fill array D[12] with zeros
repeat
increment element at the last index by step value
if it reaches the limit, make it zero
and increment element at the next index
until the first element reaches the limit
It is similar to counting 08, 09, here we cannot increment 9, so make 10 and so on
s = 1
m = 3
mx = 3
l = [0]*m
i = 0
while i < m:
print([x/3 for x in l])
i = 0
l[i] += s
while (i < m) and l[i] > mx:
l[i] = 0
i += 1
if i < m:
l[i] += s
Python code prints 64 ((mx/s+1)^m=4^3) variants like [0.3333, 0.6666, 0.0]

How to find d, given p, q, and e in RSA?

I know I need to use the extended euclidean algorithm, but I'm not sure exactly what calculations I need to do. I have huge numbers. Thanks
Well, d is chosen such that d * e == 1 modulo (p-1)(q-1), so you could use the Euclidean algorithm for that (finding the modular multiplicative inverse).
If you are not interested in understanding the algorithm, you can just call BigInteger#modInverse directly.
d = e.modInverse(p_1.multiply(q_1))
Given that, p=11, q=7, e =17, n=77, φ (n) = 60 and d=?
First substitute values from the formula:-
ed mod φ (n) =1
17 d mod 60 = 1
The next step: – take the totient of n, which is 60 to your left hand side and [e] to your right hand side.
60 = 17
3rd step: – ask how many times 17 goes to 60. That is 3.5….. Ignore the remainder and take 3.
60 = 3(17)
Step 4: – now you need to balance this equation 60 = 3(17) such that left hand side equals to right hand side. How?
60 = 3(17) + 9 <== if you multiply 3 by 17 you get 51 then plus 9, that is 60. Which means both sides are now equal.
Step 5: – Now take 17 to your left hand side and 9 to your right hand side.
17 = 9
Step 6:- ask how many times 9 goes to 17. That is 1.8…….
17 = 1(9)
Step 7:- Step 4: – now you need to balance this 17 = 1(9)
17 = 1(9) + 8 <== if you multiply 1 by 9 you get 9 then plus 8, that is 17. Which means both sides are now equal.
Step 8:- again take 9 to your left hand side and 8 to your right hand side.
9 = 1(8)
9 = 1(8) + 1 <== once you reached +1 to balance your equation, you may stop and start doing back substitution.
Step A:-Last equation in step 8 which is 9 = 1(8) + 1 can be written as follows:
1.= 9 – 1(8)
Step B:-We know what is (8) by simple saying 8 = 17 – 1(9) from step 7. Now we can re-write step A as:-
1=9 -1(17 – 1(9)) <== here since 9=1(9) we can re-write as:-
1=1(9)-1(17) +1(9) <== group similar terms. In this case you add 1(9) with 1(9) – that is 2(9).
1=2(9)-1(17)
Step C: – We know what is (9) by simple saying 9 = 60 – 3(17) from step 4. Now we can re-write step B as:-
1=2(60-3(17) -1(17)
1=2(60)-6(17) -1(17) <== group similar terms. In this case you add 6(17) with 1(17) – that is 7(17).
1=2(60)-7(17) <== at this stage we can stop, nothing more to substitute, therefore take the value next 17. That is 7. Subtract it with the totient.
60-7=d
Then therefore the value of d= 53.
I just want to augment the Sidudozo's answer and clarify some important points.
First of all, what should we pass to Extended Euclidean Algorthim to compute d ?
Remember that ed mod φ(n) = 1 and cgd(e, φ(n)) = 1.
Knowing that the Extended Euclidean Algorthim is based on the formula cgd(a,b) = as + bt, hence cgd(e, φ(n)) = es + φ(n)t = 1, where d should be equal to s + φ(n) in order to satisfy the
ed mod φ(n) = 1 condition.
So, given the e=17 and φ(n)=60 (borrowed from the Sidudozo's answer), we substitute the corresponding values in the formula mentioned above:
cgd(e, φ(n)) = es + φ(n)t = 1 ⇔ 17s + 60t = 1.
At the end of the Sidudozo's answer we obtain s = -7. Thus d = s + φ(n) ⇔ d = -7 + 60 ⇒ d = 53.
Let's verify the results. The condition was ed mod φ(n) = 1.
Look 17 * 53 mod 60 = 1. Correct!
The approved answer by Thilo is incorrect as it uses Euler's totient function instead of Carmichael's totient function to find d. While the original method of RSA key generation uses Euler's function, d is typically derived using Carmichael's function instead for reasons I won't get into. The math needed to find the private exponent d given p q and e without any fancy notation would be as follows:
d = e^-1*mod(((p-1)/GCD(p-1,q-1))(q-1))
Why is this? Because d is defined in the relationship
de = 1*mod(λ(n))
Where λ(n) is Carmichael's function which is
λ(n)=lcm(p-1,q-1)
Which can be expanded to
λ(n)=((p-1)/GCD(p-1,q-1))(q-1)
So inserting this into the original expression that defines d we get
de = 1*mod(((p-1)/GCD(p-1,q-1))(q-1))
And just rearrange that to the final formula
d = e^-1*mod(((p-1)/GCD(p-1,q-1))(q-1))
More related information can be found here.
Here's the code for it, in python:
def inverse(a, n):
t, newt = 0, 1
r, newr = n, a
while newr:
quotient = r // newr # floor division
t, newt = newt, t - quotient * newt
r, newr = newr, r - quotient * newr
if r > 1:
return None # there's no solution
if t < 0:
t = t + n
return t
inverse(17, 60) # returns 53
adapted from pseudocode found in wiki: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode
Simply use this formula,
d = (1+K(phi))/e. (Very useful when e and phi are small numbers)
Lets say, e = 3 and phi = 40
we assume K = 0, 1, 2... until your d value is not a decimal
assume K = 0, then
d = (1+0(40))/3 = 0. (if it is a decimal increase the K value, don't bother finding the exact value of the decimal)
assume K = 2, then
d = (1+2(40)/3) = 81/3 = 27
d = 27.
Assuming K will become exponentially easy with practice.
Taken the values p=7, q=11 and e=17.
then the value of n=p*q=77 and f(n)=(p-1)(q-1)=60.
Therefore, our public key pair is,(e,n)=(7,77)
Now for calvulating the value of d we have the constraint,
e*d == 1 mod (f(n)), [here "==" represents the **congruent symbol**].
17*d == 1 mod 60
(17*53)*d == 53 mod 60, [7*53=901, which gives modulus value 1]
1*d == 53 mod 60
hence,this gives the value of d=53.
Therefore our private key pair will be, (d,n)=(53,77).
Hope this help. Thank you!

Minimum number of element required to make a sequence that sums to a particular number

Suppose there is number s=12 , now i want to make sequence with the element a1+a2+.....+an=12.
The criteria is as follows-
n must be minimum.
a1 and an must be 1;
ai can differs a(i-1) by only 1,0 and -1.
for s=12 the result is 6.
So how to find the minimum value of n.
Algorithm for finding n from given s:
1.Find q = FLOOR( SQRT(s-1) )
2.Find r = q^2 + q
3.If s <= r then n = 2q, else n = 2q + 1
Example: s = 12
q = FLOOR( SQRT(12-1) ) = FLOOR(SQRT(11) = 3
r = 3^2 + 3 = 12
12 <= 12, therefore n = 2*3 = 6
Example: s = 160
q = FLOOR( SQRT(160-1) ) = FLOOR(SQRT(159) = 12
r = 12^2 + 12 = 156
159 > 156, therefore n = 2*12 + 1 = 25
and the 25-numbers sequence for
159: 1,2,3,4,5,6,7,8,9,10,10,10,9,10,10,10,9,8,7,6,5,4,3,2,1
Here's a way to visualize the solution.
First, draw the smallest triangle (rows containing successful odd numbers of stars) that has a greater or equal number of stars to n. In this case, we draw a 16-star triangle.
*
***
*****
*******
Then we have to remove 16 - 12 = 4 more stars. We do this diagonally starting from the top.
1
**2
****3
******4
The result is:
**
****
******
Finally, add up the column heights to get the final answer:
1, 2, 3, 3, 2, 1.
There are two cases: s odd and s even. When s is odd, you have the sequence:
1, 2, 3, ..., (s-1)/2, (s-1)/2, (s-1)/2-1, (s-1)/2-2, ..., 1
when n is even you have:
1, 2, 3, ..., s/2, s/2-1, s/2-2, ..., 1
The maximum possible for any given series of length n is:
n is even => (n^2+2n)/4
n is odd => (n+1)^2/4
These two results are arrived at easily enough by looking at the simple arithmetic sum of series where in the case of n even it is twice the sum of the series 1...n/2. In the case of n odd it is twice the sum of the series 1...(n-1)/2 and add on n+1/2 (the middle element).
Clearly you can generate any positive number that is less than this max as long as n>3.
So the problem then becomes finding the smallest n with a max greater than your target.
Algorithmically I'd go for:
Find (sqrt(4*s)-1) and round up to the next odd number. Call this M. This is an easy to work out value and will represent the lowest odd n that will work.
Check M-1 to see if its max sum is greater than s. If so then that your n is M-1. Otherwise your n is M.
Thank all you answer me. I derived a simpler solution. The algorithm looks like-
First find what is the maximum sum that can be made using n element-
if n=1 -> 1 sum=1;
if n=2 -> 1,1 sum=2;
if n=3 -> 1,2,1 sum=4;
if n=4 -> 1,2,2,1 sum=6;
if n=5 -> 1,2,3,2,1 sum=9;
if n=6 -> 1,2,3,3,2,1 sum=12;
So from observation it is clear that form any number,n 9<n<=12 can be
made using 6 element, similarly number
6<n<=9 can be made at using 5 element.
So it require only a binary search to find the number of
element that make a particular number.

Resources