Mathmatics to balance "multiple circuits" - math

I am building a game which allows the player to control "power flow" between 10 circuits.
Each of the 10 circuits is adjusted individually and the total must always equal 100%.
For example a perfectly balanced situation would be all 10 circuits at 10% (10x10=100)
Edit 2: If what I am trying to do here is know as things other than "balancing", please comment and I will research them.
Now the player also has the ability to lock circuits so that the power level cannot be changed by other circuits but it can still be changed directly.
EDIT 3: Sometimes the requested amount may not be possible to achieve (eg: example 3 and 6) in these situations the nearest possible result will be the result
EDIT: Seeing that my post is receiving down votes I will include what I have already tried
Sum of change divided by circuits requesting change adding to circuits requesting change and taken off circuits not changing - The problem with this method was negative and positive changes at the same time could balance and result in "deadlock" situations where no change happens
Looping circuit by circuit adding and taking as needed - The problem with this method is that it rarely balanced correctly
Applying subtractions and additions first and then balance all circuits back into range (so total becomes 100) - the problem with this was power would end where it shouldn't be with circuits that should be at 0 ending up with small amounts of power
To simplify my question we can work with just 5 circuits.
I need assistance to work out the math for calculating the following. After 20 or so attempts I am thinking I am over complicating it as I keep ending up with 200 line scripts or is this actually very complicated?
Example 1: Addition Example
20 20 20 20 20 Start values
+10 +10 0 0 0 Change
30 30 3.3 3.3 3.3 After first iteration
50 50 0 0 0 After x iterations (eg key held down)
Example 2: Subtraction Example
20 20 20 20 20 Start values
-10 -10 0 0 0 Change
10 10 26.6 26.6 26.6 After first iteration
0 0 33.3 33.3 33.3 After x iterations (eg key held down)
Example 3: Lock + Addition (L is locked)
L
2.5 90 2.5 2.5 2.5 Start values
0 0 +50 0 0 Change
0 90 10 0 0 After first iteration
0 90 10 0 0 After x iterations (eg key held down)
Example 4: Lock + Subtraction (L is locked)
L
2.5 90 2.5 2.5 2.5 Start values
0 -10 0 0 0 Change
5 80 5 5 5 After first iteration
25 0 25 25 25 After x iterations (eg key held down)
Example 5: Multi Lock + Subtraction (L is locked)
L L
2.5 90 2.5 2.5 2.5 Start values
0 -10 0 0 0 Change
5.8 80 2.5 5.8 5.8 After first iteration
32.5 0 2.5 32.5 32.5 After x iterations (eg key held down)
Example 6: Balancing change from unbalanced start (This math may be a bit off)
2.5 90 2.5 2.5 2.5 Start values
+10 +10 +10 0 0 Change
16.7 66.6 16.7 0 0 After first iteration
33.3 33.3 33.3 0 0 After x iterations (eg key held down)

Start by retrieving all circuits that may potentially be changed by the runtime:
Candidates = AllCircuits \ (LockedCircuits u ChangedCircuits)
Here, \ denotes the set minus operator and u is the union operator.
Calculate the average change per circuit:
targetTotalChange = totalChange
averageChange = totalChange / |Candidates|
Now, start to change the candidates. To account for limitations, order the candidates by their current power flow. If averageChange is negative, then order them in ascending order. If it is positive, order them in descending order.
And remember how many circuits you already have processed:
processedCircuits = 0
Now iterate all candidates in the specified order:
for each candidate in Candidates
Check if the the average change can be added to this circuit. Otherwise, adapt the values:
processedCircuits++
prevPower = candidate.PowerFlow
targetPower = prevPower + averageChange
if(targetPower < 0)
{
totalChange += prevPower
candidate.PowerFlow = 0
//recalculate average change
}
else if(targetPower > 100)
{
totalChange -= 100 - prevPower
candidate.PowerFlow = 100
//recalculate average change
}
else
{
totalChange -= averageChange
candidate.PowerFlow += averageChange
}
When you need to recalculate the average change, do the following:
averageChange = totalChange / (|Candidates| - processedCircuits)
Beware of division by zero.
Now you have adapted all other circuits. What remains is adapting the changed circuits. This is quite easy. We changed all other circuits by targetTotalChange - totalChange. This change can be added to the changed circuits. We can just add the according percentage:
percentage = (targetTotalChange - totalChange) / targetTotalChange
for each circuit in ChangedCircuits
circuit.PowerFlow += percentage * targetChange[circuit]
next

Related

trouble converting index to row

I'm having trouble converting an index number into its respective column/row. The table goes like this
The graph scales in each dimension. Each square is surrounded by one blank space. I need to turn the number of the square into the x/y coordinates
I've figured out the column, but the row is still evading me.
This is what i have now:
#define IDtoX(n, w) ((2*(n%w))+1)
#define IDtoY(n, h) ((2*(n/h))+1)
IDtoX works as intended. IDtoY does not.
outputs should be as following.:
grid of width 7 and height 5:
n y
0 3
1 3
2 3
3 1
4 1
5 1
grid of width 9 and height 7:
0 5
1 5
2 5
3 5
4 3
5 3
6 3
7 3
8 1
9 1
10 1
11 1
The main reason why you are failing with your function IDtoY(n, h) is that the result also depends on the value of w. Therefore you must change your signature to something like IDtoY(n, w, h). To see this, try drawing more arrays with the same hs but varying ws and you will see that the ids will also change for each n. You were fooled by your successful function for IDtoX which does indeed not depend on h but only on n and w. Now, if your ids began at zero at the top, they would not depend on w, but as you drew the array, they do.
I found multiple formulae that work, but none of them are pretty. Here are two--if you do not like them, you could find some equivalent formulae.
#define IDtoY(n, w, h) (h - 2 - 2 * n // (w - 1) * 2)
or perhaps
#define IDtoY(n, w, h) (h - 2 - n // (w // 2) * 2)
where the // operator is integer division. You do not state which computing environment you are using--the simple / operator may work for you.

How to quickly tell if an "unknown" number is divisible by 3?

I'm trying to tackle down a problem where the time limit is very low (1 second) and the number of cases is supposedly high.
You need to tell if a number is divisible by 3, but the problem is that you don't get the direct number, you get a number k, and then need to check if the concatenation of numbers from 1 to k (123...k) is divisible by 3.
Example input:
4 // The number of cases
2
6
15
130000000
Output:
YES // Because 12 is divisible by 3
YES // Because 123456 is divisible by 3
YES // Because 123456789101112131415 is divisible by 3
NO
I've found some topics about quickly checking the divisibility, but what most time takes I think is to build the number. There are cases where the initial number is as high as 130000000 (so the final is 1234...130000000) which I thinks overflows any numeric data type.
So, what am I missing here? Is there any way to know if something is divisible by 3 without concatenating the number? Any ideas?
PD: Someone also posted the triangular numbers formula which also is a correct solution and then deleted the answer, it was:
if ((1 + num) * num / 2) % 3 == 0 ? "YES" : "NO"
Every third number is divisible by three.
Every number divisible by three has a digit sum divisible by 3.
Every third number has a digit sum divisible by 3.
In between these, every third number has a digit sum congruent to 1 and then 2 mod 3.
Take a look:
n digit sum mod 3
0 0
1 1
2 2
3 0
4 1
5 2
6 0
...
10 1
11 2
12 0
...
19 1
20 2
21 0
...
Say we have a string of digits constructed as you describe, and the number we just added was divisible mod 3. When we append the next number's digits, we are appending digits whose sum is congruent to 1 mod 3, and when added to those in our number, we will get a combined digit sum congruent to 1 mod 3, so our answer for the next one will be "no". The next one will add a number with digit sum congruent to 2 mod 3, and this causes the total to become congruent to 0 again, so the answer here is "yes". Finally, adding the next number which must be divisible by 3 keeps the digit sum congruent to 0.
The takeaway?
if n is congruent to 0 modulo 3, then the answer is "yes"
if n is congruent to 1 modulo 3, then the answer is "no"
if n is congruent to 2 modulo 3, then the answer is "yes"
In particular, your example for n=15 is wrong; the digit string obtained represents a number that should be divisible by 3, and indeed it is (try it on a big enough calculator to verify).
All that is left is to find an implementation that is fast enough and handles all the required cases. If n is guaranteed to be under ~2 billion, then you are probably safe with something like
return (n % 3) != 1;
If n can be an arbitrarily large number, never fear; you can check whether the digit sum is congruent to 0 modulo 3 by adding up the digits in linear time. If not, you can add 1 from the number by coding addition like you do it by hand on paper and then check the result of that for divisibility by 3, again in linear time. So something like:
if (digit_sum_mod_3(n) == 0) return true;
else if (digit_sum_mod_3(add_one(n)) == 0) return false;
else return true;
Then you would have something like
digit_sum_mod_3(n[1...m])
sum = 0
for k = 1 to m do
sum = sum + n[k]
// keep sum from getting too big
if sum >= 18 then
sum = sum - 18
return sum % 3
add_one(n[1...m])
// work from right to left, assume big-endian
for k = m to 1 do
if n[k] < 9 then // don't need to carry
n[k] = n[k] + 1
break
else then // need to carry
n[k] = 0
if n[1] = 0 then // carried all the way to the front
n[1] = 1
n[m+1] = 0
return n
Any three consecutive numbers sum up to 0 == a + a + 1 + a + 2 mod 3.
The answer reduces to k%3 == 0, or 2k-1 % 3 == 0. The latter is equivalent to k%3 == 2, which leaves out k%3==1 which then simplifies further to k%3 != 1.
It is a known trick in mathematics that a number is divisible by three if the sum of its individual decimal digits is divisible by three.
Example:
2271
2+2+7+1 = 12
12 is divisible by 3, therefore so is 2271
Additionally, the sum of any three consecutive integers must be divisible by three. This is because:
((n)+(n+1)+(n+2))/3 = (3n+3)/3 = n+1 = integer
Therefore:
If k mod 3 == 0, then concatenation of 1 to k is divisible by three.
If k mod 3 == 1, then concatenation of 1 to k is not divisible by three.
If k mod 3 == 2, then it is a bit trickier. In this case, concatenation of 1 to k is divisible by three if the sum of k and the number before k (which evaluates to (k)+(k-1), which is 2k-1) is divisible by three.
Therefore, the final condition is:
(k mod 3 == 0) || ((k mod 3 == 2) && (2k-1 mod 3 == 0))
However, this can be even further simplified.
It turns out that k mod 3 can only equal 2 whenever 2k-1 mod 3 equals 0 and vice versa.
See simple graph below that shows cyclic pattern of this behavior.
Therefore, the formula can be further simplified just to:
(k mod 3 == 0) || (k mod 3 == 2)
Or, even more simply:
(k mod 3 != 1)
I realize answerer already provided this answer so I don't expect this to be the accepted answer, just giving a more thorough mathematical explanation.
A number is divisible by three if the sum of its digits is divisible by three (see here). Therefore, there is no need to "construct" your number, you need simply add the digits of the individual numbers. Thus for your 15 case, you do not need to "construct" 123456789101112131415, you just need to sum all of the digits in [1, 2, 3, 4, ... 14, 15].
This is simpler than it sounds because the problem only needs to check numbers of a very specific format: 12345789101112131415…k. You can use Gauss's method to quickly get the sum of the numbers 1 to k and then check if that sum is divisible by three using the usual methods. The code for that is:
'NO' if (k*(k+1)/2)%3 else 'YES'
If you look at the pattern that occurs as k increases (NO, YES, YES, NO, YES, YES, ...), you don't even need the multiplication or division. In short, all you need is:
'YES' if (k-1)%3 else 'NO'
Here is Python code which reads integers from a file and, if it wouldn't take too long also checks the answer the hard way so you can see that it is right. (Python numbers can be infinitely long, so you don't need to worry about overflow):
#!/usr/bin/python3
# Read integers from stdin, convert each int to a triangular number
# and output YES (or NO) if it is divisible by 3.
def sumgauss(x):
'''Return the sum from 1 to x using Gauss's shortcut'''
return (x*(x+1)/2)
def triangle(n):
'''Given an integer n, return a string with all the integers
from 1 to n concatenated. E.g., 15 -> 123456789101112131415'''
result=""
for t in range(1, k+1):
result+=str(t)
return result
import sys
for k in sys.stdin.readlines():
k=int(k)
print ( 'YES' if (k-1)%3 else 'NO', end='')
# If it wouldn't take too long, double check by trying it the hard way
if k<100000:
kstr=triangle(k)
print("\t// %s modulo 3 is %d" % (kstr, int(kstr)%3))
else:
print('\t// 123456789101112131415...%d%d%d modulo 3 is %d' %
tuple([k-2, k-1, k, sumgauss(k)%3]))
Speaking of Gauss's shortcut for summation, this problem seems a lot like a homework assignment. (Gauss invented it as a student when a teacher was trying to get the class out of his hair for a while by making them add up the numbers from 1 to 100.) If this is indeed a class assignment, please make sure the teacher knows to give the A to me and stackoverflow. Thanks!
Sample output:
$ cat data
2
6
15
130000000
130000001
$ ./k3.py < data
YES // 12 modulo 3 is 0
YES // 123456 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 123456789101112131415...129999998129999999130000000 modulo 3 is 1
YES // 123456789101112131415...129999999130000000130000001 modulo 3 is 0
The first 32 triangular numbers:
$ seq 32 | ./k3.py
NO // 1 modulo 3 is 1
YES // 12 modulo 3 is 0
YES // 123 modulo 3 is 0
NO // 1234 modulo 3 is 1
YES // 12345 modulo 3 is 0
YES // 123456 modulo 3 is 0
NO // 1234567 modulo 3 is 1
YES // 12345678 modulo 3 is 0
YES // 123456789 modulo 3 is 0
NO // 12345678910 modulo 3 is 1
YES // 1234567891011 modulo 3 is 0
YES // 123456789101112 modulo 3 is 0
NO // 12345678910111213 modulo 3 is 1
YES // 1234567891011121314 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 12345678910111213141516 modulo 3 is 1
YES // 1234567891011121314151617 modulo 3 is 0
YES // 123456789101112131415161718 modulo 3 is 0
NO // 12345678910111213141516171819 modulo 3 is 1
YES // 1234567891011121314151617181920 modulo 3 is 0
YES // 123456789101112131415161718192021 modulo 3 is 0
NO // 12345678910111213141516171819202122 modulo 3 is 1
YES // 1234567891011121314151617181920212223 modulo 3 is 0
YES // 123456789101112131415161718192021222324 modulo 3 is 0
NO // 12345678910111213141516171819202122232425 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627282930 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728293031 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829303132 modulo 3 is 0
Actually the answer is pretty straight forward, if the sum of the digits divisible by three then the number is also divisible by 3.
string ans=(((1 + num) * num) / 2) % 3 == 0 ? "YES" : "NO";
according to the problem sum of digit can be considered as sum of numbers from 1 to n, sum=(n*(n+1))/2
*Make sure you divide the whole thing by 2
Another approach:
string ans=n % 3 !=1 ? "YES" : "NO";
You can prove that if n or n-2 is divisible by 3, then the sum up to n is divisible by 3 (e.g., in your case sum(1...8), sum(1..9), sum(1..11), etc.).

Explanation of 1 mod 3

So i've been looking into modulo recently. I'm trying to improve my math skills, which are not the best if i'm honest. But something i am trying to improve. I understand how this works i think. I am also quite competent with long division. However something is bugging me and i can't seem to find an answer for it online.
I know that 7 % 5 = 2 (5 goes into 7 once, with a remainder of 2).
What i don't understand is this;
1 % 3 = 1
How can this be, 3 goes into 1, 0 times, with a remainder of 3? Surely the answer to 1 % 3 = 3?
Can anyone explain this in its most simplest terms please?
Am i correct in thinking that if the dividend (1) is less than the devisor (3) which we know will equal 0 remainder x, it just uses the dividend as the result?
Thanks for your help.
The remainder in 1%3 refers to what remains of 1 (not 3) after you divide by 3. As you have already said, 3 goes into 1 zero times. So -- when you remove 0 multiples of 3 from 1, all of 1 remains. Thus 1 % 3 = 1.
The result of a modulo operation n % m is just that number r for which q * m + r = n (q may be anything). The only requirement we have is that 0 <= r < m.
So for instance:
7 % 5 --> 1 * 5 + 2 == 7 --> r = 2
1 % 3 --> 0 * 3 + 1 == 1 --> r = 1

how do i check even or odd in postscript

I'm trying to check if the number on the top of the stack is even or odd without affecting my stack because I'm using it in a recursive function. I also tried to double pop but this code still messes up the function.
dup 2 0 mod eq
{ 0 0 0 setrgpcolor}
{0.6 0.6 0.6 setrgpcolor}ifelse
pop
You got the order of the arguments wrong. One step at a time (assuming the top stack number is 123):
123
dup 2 0 mod eq
do dup:
123 123 2 0 mod eq
do mod on 2 0 (!)
123 123 --undefined-- eq
and the eq is too little, too late...
Swap the 2 operands to get the right result:
dup 2 mod 0 eq
{ .. number is even ..}
{ .. number is odd ..} ifelse
(Note:
Is setrgpcolor a typo, or is there really a color model named so?)

Lua level formula

I'm trying to calculate a players level depending on the players experience.
This is what I have in text:
Start at level 0 with 0 XP
To reach level 1, you need 50 XP.
One kill gives 10 XP.
So, 5 kills = 50 XP = level 1.
Now, level 2 should require 50 XP more than last level.
So, level 2 requires a total of 150 XP.
Level 1: 50 XP (5 kills total, 5 kills to go from level 0 to 1).
Level 2: 150 XP(15 kills total, 10 kills to go from level 1 to 2).
Level 3: 300 XP(30 kills total, 15 kills to go from level 2 to 3).
So far, all I got is this:
math.Round( xp / 50 )
This is 50 xp per level which isn't what I wanted; but I have really no idea where to go from here.
Simply put, I want each level to require 50 more XP than last level, and I need to get the level from an xp variable.
A quick math calculation shows that the experience point to reach level lv would be:
(1 + 2 + 3 + ... + lv) * 50
which equals:
lv * (lv + 1) / 2 * 50
So the question becomes to find the maximum non-negative integer lv that qualifies:
lv * (lv + 1) / 2 * 50 <= xp
That's the formula needs to be solved. And the math solution is:
lv <= (math.sqrt(xp * 4 / 25 + 1) - 1) / 2
Since you are looking for a non-negative integer, in the words of Lua, that's:
local lv = math.floor((math.sqrt(xp * 4 / 25 + 1) - 1) / 2)
You can wrap it to a function and give it a quick test like this:
function xp_to_lv(xp)
return math.floor((math.sqrt(xp * 4 / 25 + 1) - 1) / 2)
end
assert(0 == xp_to_lv(0))
assert(0 == xp_to_lv(49))
assert(1 == xp_to_lv(50))
assert(2 == xp_to_lv(260))
assert(3 == xp_to_lv(310))

Resources