Finding X & Y based off of Index - math

Good day all
I am having a math issue, it may be due to the lack of sleep but I am totally drawing a blank.
I need to find the x and y coordinates based off of the index.
So I know the width of the grid, the height and the index. But I dont know the X and Y coordinates. i need build a formula to get that data.
For example. I know the index of 9. Through a formula i need to be able to get the number 4 for X and 2 for Y
int numOfRows = 4
int numOfCols = 5
int index = 13
int X = ?
int Y = ?
//perform math magic
x = 4
y = 3

It is very simple:
public static void foo(int i) {
int x = i % 5 + 1;
int y = i / 5 + 1;
}

It gets much easier if you start counting with 0:
| 0 1 2 3 4
-----------------
0| 0 1 2 3 4
1| 5 6 7 8 9
2|10 11 12 13 14
3|...
4|
Let a be the number in the grid and numberOfCols the number of columns (5 in this example).
In that case, it's plain to see that
the row number is a / numberOfCols (without remainder) and
the column number is a modulo numberOfCols.
You can reduce your case to this case by adding 1 to the resulting row/col numbers.

Related

Best way to find least standard deviation

I have a spreadsheet where I put numbers that represent number of verses on each paragraph of a book.
I manually distribute sequential paragraphs by number of verses, so in the spreadsheet I'll have something like this:
Verses Day
5 1
6 1
3 1
10 2
8 3
4 3
2 3
6 4
3 4
10 5
3 5
2 6
5 6
10 7
= 2,7080128015
By summing the total of verses for each day - in this case, 7 days - I get the standard deviation and try to reduce it for a better distribution of paragraphs.
The question is: what is the best way to find the least standard deviation?
I thought on using brute force to generate all possible combinations, but that is not a good idea if the number increases.
EDIT: The standard deviation is based on total number of verses of each day, which are identified sequentialy. Day 1 has total of 14 verses, day 2, 10 and so on.
1 14
2 10
3 14
4 9
5 13
6 7
7 10
= 2,7080128015
Since the total number of verses and the number of days is constant, you want to minimize
sum (avg verse count - verse count of day i)^2
i
avg verse count is a constant and simply the total number of verses divided by the number of days.
This problem can be solved with a dynamic program over the days. Let us build the partial solution function f(days, paragraph) that gives us the minimal sum of squares for distributing paragraphs 0 through paragraph over days days. We are interested in the last value of this function.
We can build the function incrementally. Calculating f(1, p) for any p is straight-forward since we just need to calculate the differences to the average and square. Then, for all other days, we can calculate
f(d, p) = min f(d - 1, i) + (avg verse count - sum verse count of paragraph j)^2
i<p j:i+1..p
That means, we check the solutions for one day less and fill up the current day with the paragraphs between the previous day's end paragraph and p. While we calculate this function, we keep a pointer to the chosen minimum element (as usual for a dynamic program). When we are done calculating the entire function, we just follow the pointers back to the start, which will give us the partitioning.
The algorithm has a running time of O(d * p^2), where d is the number of days and p is the number of paragraphs.
Example Code
Here is some example C# code that implements the above algorithm:
struct Entry
{
public double minCost;
public int predecessor;
}
public static void Main()
{
//input data
int[] versesPerParagraph = { 5, 6, 3, 10, 8, 4, 2, 6, 3, 10, 3, 2, 5, 10 };
int days = 7;
//calculate constants
double avgVerses = (double)versesPerParagraph.Sum() / days;
//set up DP table (f(d,p))
int paragraphs = versesPerParagraph.Length;
Entry[,] dp = new Entry[days, paragraphs];
//initialize table
int verseCount = 0;
for(int p = 0; p < paragraphs; ++p)
{
verseCount += versesPerParagraph[p];
double diff = avgVerses - verseCount;
dp[0, p].minCost = diff * diff;
dp[0, p].predecessor = -1;
}
//run dynamic program
for(int d = 1; d < days; ++d)
{
for(int p = d; p < paragraphs; ++p)
{
verseCount = 0;
dp[d, p].minCost = double.MaxValue;
for(int i = p; i >= d; --i)
{
verseCount += versesPerParagraph[i];
double diff = avgVerses - verseCount;
double cost = dp[d - 1, i - 1].minCost + diff * diff;
if(cost < dp[d, p].minCost)
{
dp[d, p].minCost = cost;
dp[d, p].predecessor = i - 1;
}
}
}
}
//reconstruct the partitioning
{
int p = paragraphs - 1;
for (int d = days - 1; d >= 0; --d)
{
int predecessor = dp[d, p].predecessor;
//calculate number of verses, just to show them
verseCount = 0;
for (int i = predecessor + 1; i <= p; ++i)
verseCount += versesPerParagraph[i];
Console.WriteLine($"Day {d} ranges from paragraph {predecessor + 1} to {p} and has {verseCount} verses.");
p = predecessor;
}
}
}
The output is:
Day 6 ranges from paragraph 13 to 13 and has 10 verses.
Day 5 ranges from paragraph 10 to 12 and has 10 verses.
Day 4 ranges from paragraph 9 to 9 and has 10 verses.
Day 3 ranges from paragraph 6 to 8 and has 11 verses.
Day 2 ranges from paragraph 4 to 5 and has 12 verses.
Day 1 ranges from paragraph 2 to 3 and has 13 verses.
Day 0 ranges from paragraph 0 to 1 and has 11 verses.
This partitioning gives a standard deviation of 1.15.

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.

Summing elems of array using binary recursion

I wasn't starting to understand linear recursion and then I thought I practice up on sorting algorithms and then quick sort was where I had trouble with recursion. So I decided to work with a simpler eg, a binary sum that I found online. I understand that recursion, like all function calls, are executed one # a time and not at the same time (which is what multi-threading does but is not of my concern when tracing). So I need to execute all of recursive call A BEFORE recursive call B, but I get lost in the mix. Does anyone mind tracing it completely. The e.g. I have used of size, n = 9 where elems are all 1's to keep it simple.
/**
* Sums an integer array using binary recursion.
* #param arr, an integer array
* #param i starting index
* #param n size of the array
* floor(x) is largest integer <= x
* ceil(x) is smallest integer >= x
*/
public int binarySum(int arr[], int i, int n) {
if (n == 1)
return arr[i];
return binarySum(arr, i, ceil(n/2)) + binarySum(arr,i + ceil(n/2), floor(n/2));
}
What I personally do is start with an array of size 2. There are two elements.
return binarySum(arr, i, ceil(n/2)) + binarySum(arr,i + ceil(n/2), floor(n/2)) will do nothing but split the array into 2 and add the two elements. - case 1
now, this trivial starting point will be the lowest level of the recursion for the higher cases.
now increase n = 4. the array is split into 2 : indices from 0-2 and 2-4.
now the 2 elements inside indices 0 to 2 are added in case 1 and so are the 2 elements added in indices 2-4.
Now these two results are added in this case.
Now we are able to make more sense of the recursion technique, some times understanding bottom up is easier as in this case!
Now to your question consider an array of 9 elements : 1 2 3 4 5 6 7 8 9
n = 9 => ceil(9/2) = 5, floor(9/2) = 4
Now first call (top call) of binarySum(array, 0, 9)
now n = size is not 1
hence the recursive call....
return binarySum(array, 0, 5) + binarySum(array, 5, 4)
now the first binarySum(array, 0 ,5) operates on the first 5 elements of the array and the second binarySum(array,5,4) operates on the last 4 elements of the array
hence the array division can be seen like this: 1 2 3 4 5 | 6 7 8 9
The first function finds the sum of the elements: 1 2 3 4 5
and the second function finds the sum of the elements 6 7 8 9
and these two are added together and returned as the answer to the top call!
now how does this 1+2+3+4+5 and 6+7+8+9 work? we recurse again....
so the tracing will look like
1 2 3 4 5 | 6 7 8 9
1 2 3 | 4 5 6 7 | 8 9
1 2 | 3 4 | 5 6 | 7 8 | 9
[1 | 2]___[3]___[4 5]___[6 7]___[8 9]
Till this we are fine..we are just calling the functions recursively.
But now, we hit the base case!
if (n == 1)
return arr[i];
[1 + 2]____[3]____[4 + 5]____[6 + 7]____[8 + 9]
[3 + 3] ____ [9] ____[13 + 17]
[6 + 9] [30]
[15 + 30]
[45]
which is the sum.
So for understanding see what is done to the major instance of the problem and you can be sure that the same thing is going to happen to the minor instance of the problem.
This example explains binary sum with trace in java
the trace is based on index of array , where 0 - is yours starting index and 8 is length of the array
int sum(int* arr, int p, int k) {
if (p == k)
return arr[k];
int s = (p + k) / 2;
return sum(arr, p, s) + sum(arr, s + 1, k);
}

How to analyze this pseudocode

I have the following pseudocode:
sum<-0
inc<-0
for i from 1-n
for j from 1 to i
sum<-sum+inc
inc<-inc+1
I am asked to find a closed formula. The hint is to use common summations. No matter how I look at it I cannot write this code in summation form. Can someone give me an idea of what the summations would look like or even a recursive formula?
Assuming the for i from 1-n means:
for i from 1 to n
A closed formula for that can be obtained through some numerical analysis. Let's examine the number of times through the loop for a couple of values of n (5 and 6).
The outer loop is always n times and the inner loop is whatever i is for each iteration, so for values of n, here are the iteration counts:
n count
= ===========================================
1 (1) = 1
2 (1),(12) = 3
3 (1),(12),(123) = 6
4 (1),(12),(123),(1234) = 10
5 (1),(12),(123),(1234),(12345) = 15
6 (1),(12),(123),(1234),(12345),(123456) = 21
The closed formula for these is best illustrated as follows:
n = 5: 5 + 4 + 3 + 2 + 1
| | | | |
| | V | |
| | 3 | | Formula is: (n+1)*((n-1)/2) + ((n+1)/2)
| +-> 6 <-+ | [outer pair sets] + [inner value]
+-----> 6 <-----+
--
15
This is a formula for all odd values of n. For even values, a similar method can be used:
n = 6: 6 + 5 + 4 + 3 + 2 + 1
| | | | | |
| | +-> 7 <-+ | | Formula is: (n+1)*(n/2)
| +-----> 7 <-----+ | [outer pair sets]
+---------> 7 <---------+
--
21
This tells you the number of iterations of the nested loop for each value of n (we'll call this x).
The calculation of the final value of sum is very similar. On the first iteration you add zero. On the second iteration, you add one. On the third iteration, you add two. That's pretty much exactly the same thing you had to do to figure out the number of iterations, only now it's based on x rather than n and it's 0+1+2+... rather than 1+2+3+..., meaning we can use exactly the same formula just by applying it to x-1 rather than x.
So we can use:
if n is odd:
x <- (n+1) * ((n-1)/2) + ((n+1)/2)
else:
x <- (n+1) * (n/2)
x <- x - 1
if x is odd:
sum <- (x+1) * ((x-1)/2) + ((x+1)/2)
else:
sum <- (x+1) * (x/2)
Checking this against the algorithm for the first few values on n:
n algorithm formula
- --------- -------
0 0 0
1 0 0
2 3 3
3 15 15
4 45 45
5 105 105
So, a perfect match, at least withing the sample space chosen. You could actually go further and turn that into a single formula based on n alone rather than working out an intermediate value, but I'll leave that as an exercise for the reader.
Hint: A C formula which works for both odd and even numbers is:
x <- ((n+1) * ((n-(n%2))/2)) + ((n%2) * ((n+1)/2))
(though still not tested for negative values of n - you should put a check for that before you use the formulaic version).
Innermost loop (let's just call i a fixed number):
inc is incremented i times.
sum has inc added to it i times. (i*(i-1)/2, right?)
If we assume that inc and sum start art value 0, then that's valid. If we assume that they start at some different value, let's call them k and l, then we know that inc will end up at value k+i. We know that sum will end up at l+k*i + i*(i-1)/2.
Now, i itself is going from 1 to n. Um... hum. Let me think about this a bit more.

What math do I need to convert numbers according to this table?

Given an X, what math is needed to find its Y, using this table?
x
y
0
1
1
0
2
6
3
5
4
4
5
3
6
2
This is a language agnostic problem. I can't just store the array, and do the lookup. The input will always be the finite set of 0 to 6. It won't be scaling later.
This:
y = (8 - x) % 7
This is how I arrived at that:
x 8-x (8-x)%7
----------------
0 8 1
1 7 0
2 6 6
3 5 5
4 4 4
5 3 3
6 2 2
int f(int x)
{
return x["I#Velcro"] & 7;
}
0.048611x^6 - 0.9625x^5 + 7.340278x^4 - 26.6875x^3 + (45 + 1/9)x^2 - 25.85x + 1
Sometimes the simple ways are best. ;)
It looks like:
y = (x * 6 + 1) % 7
I don't really like the % operator since it does division so:
y = (641921 >> (x*3)) & 7;
But then you said something about not using lookup tables so maybe this doesn't work for you :-)
Update:
Since you want to actually use this in real code and cryptic numbers are not nice, I can offer this more maintainable variant:
y = (0x2345601 >> (x*4)) & 15;
Though it seems a bunch of correct answers have already appeared, I figured I'd post this just to show another way to have worked it out (they're all basically variations on the same thing):
Well, the underlying pattern is pretty simple:
x y
0 6
1 5
2 4
3 3
4 2
5 1
6 0
y = 6 - x
Your data just happens to have the y values shifted "down" by two indices (or to have the x values shifted "up").
So you need a function to shift the x value. This should do it:
x = (x + 5) % 7;
Resulting equation:
y = 6 - ((x + 5) % 7);
Combining the ideas in Dave and Paul's answer gives the rather elegant:
y = (8 - x) % 7`
(though I see I was beaten to the punch with this)
unsigned short convertNumber(unsigned short input) {
if (input <= 1) { return !input; } //convert 0 => 1, 1 => 0
return (8-input); //convert 2 => 6 ... 6 => 2
}
Homework?
How about:
y = (x <= 1 ? 1 : 8) - x
and no, i dont/cant just store the array, and do the lookup.
Why not?
yes, the input will always be the finite set of 0 to 6. it wont be scaling later.
Just use a bunch of conditionals then.
if (input == 0) return 1;
else if (input == 1) return 0;
else if (input == 2) return 6;
...
Or find a formula if it's easy to see one, and it is here:
if (input == 0) return 1;
else if (input == 1) return 0;
else return 8 - input;
Here's a way to avoid both modulo and conditionals, going from this:
y = (8 - x) % 7
We know that x % y = x - floor(x/y)*y
So we can use y = 8 - x - floor((8 - x) / 7) * 7
What about some bit-fu ?
You can get the result using only minus, logical operators and shifts.
b = (x >> 2) | ((x >> 1) & 1)
y = ((b << 3)|(b ^ 1)) - x

Resources