Triangle stored as an array. Height and Length of each level? - c#

Assume we have a triangle that each node has K children.
An example for K = 2 is:
1
2 3
4 5 6
An example for K = 3 is:
1
2 3 4
5 6 7 8 9
An example for K = 4 is:
1
2 3 4 5
5 6 7 8 9 1 2
etc.
I would like to store those triangles in an array. I am looking to retrieve the total height of the triangle (assuming they are complete triangles) given the total number of elements T and the number of children per node K
I am also looking to find what is the offset for each element in an array to each children. I know that for the example above where K = 2 the array is [1, 2, 3, 4, 5, 6] where for each level L the offset is L * (L + 1) / 2 (because Level 1 has 1 element, Level 2 has 2, Level 3 has 3 ...)
EDIT: The example is correct. Each node has access to K child nodes. for K = 3 1 has access to 2 3 and 4. 2 has access to 5 6 and 7. 3 has access to 6 7 and 8.
These are triangles and not graphs or trees.

Now that you have clarified your requirement ...
For K=2 there are
1
1+1
1+1+1
...
elements in each level, this is the series 1,2,3,.... If n is the level number then there are n elements at each level. Note that this can also be written as 1+1(n-1)
For K=3 there are
1
1+2
1+2+2
...
elements in each level, this is the series 1,3,5,...; there are 1+2(n-1) elements at each level.
For K=4 there are
1
1+3
1+3+3
...
elements in each level, this is the series 1,4,7,.... There are 1+3(n-1) elements at each level.
At each level in each triangle there are 1+(K-1)(n-1) elements. I expect you can carry on from here.

The total number of elements T for a triangle of height h will be:
T = ∑1...h (1 + (K-1)(n-1))
T = h + (K-1) * ∑1...h (n-1)
T = h + (K-1) * ∑0..h-1 (n)
T = h + (K-1) * ((h-1)² + h-1) / 2
T = h + (K-1) * (h² + 1 - 2h + h-1) / 2
T = h + (K-1) * (h² - h) / 2
Calculating the height
So to get the height h you insert the value of K and solve the equation. Here's an example of an easy case where K equals 3.
T = h + (K-1) * (h² - h) / 2
T = h + (3-1) * (h² - h) / 2
T = h + (h² - h)
T = h²
h = √T
Calculating the offsets
As for the offsets you use the same equation we used to calculate the total number of elements but set h to height-1. Here's an example of getting the offset for row 3 in a triangle with a K of 4.
offset(h) = h-1 + (K-1) * ((h-1)² - (h-1)) / 2
offset(3) = 3-1 + (4-1) * ((3-1)² - (3-1)) / 2
offset(3) = 2 + 3 * (4 - 2) / 2
offset(3) = 5

Related

c# rules about: a mod b, while a is bigger than b

I was examining a code about operator overloading, and I saw an interesting way of use of % to convert seconds to minutes if second variable is bigger than 59.
It seems while a<b (both int) a%b returns a, I havent read a rule about this before, I wanna learn why it returns a, is it about they are declared as integers, are there any more rules about %?
Thanks
% is the modulo operator. The modulo operation a % b returns the remainder z in the division
a / b = x, remainder z
In other words, it returns y in this equation:
x * b + y = a
*The second equation also shows why this works for fractional numbers too.**
Thus, the following examples (not complete) are true:
-5 % 4 = -1
-4 % 4 = 0
-3 % 4 = -3
...
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
101.4 % 100.3 = 1.1
In your example converting seconds to minutes and seconds, you probably read something like this:
int totalseconds = 72;
int minutes = totalseconds / 60; // == 1
int seconds = totalseconds % 60; // == 12
This is the same thing: the minutes are calculated as totalseconds / 60, which is an integral division that "rounds" to the lower integer for positive numbers, thus the result of 1. The seconds left are calculated as the remainder of 72 and 60.
You could also calculate the seconds like
int seconds = totalseconds - (minutes * 60)
In general, for any a and any b:
a / b = (SomeConstant * b) + RemainderOfb*
So if a = 2 and b = 5 means a < b then:
How many SomeConstant do you need to multiply b with, in order to get close to a? And once you get close, what is your remainder?
so if
a / b = (5 * 0) + 2
Means Remainder = 2 out of 5.
Then: a % b means the Remainder with respect to b, which is = 2.
And if a = 3 and b = 2 means a > b then:
If you remove all the "b"s from a, what is the Remainder? You can do
it the easy way: Subtract "a" from "b" till you can't subtract
anymore. Or:
a / b = SomeConstant * a (which is how many "a"s did you subtract) + Remainder
Substitute:
a / b = (1 * 2) + 1
Means Remainder = 1 out of the 2
Then a % b equals the Remainder with respect to a, which is = 1
a mod b is the remainder of a a / b, therefore if a < b AND a > -b the remainder is always a.
The following rules are valid for C#, but might differ in other languages, refer to Modulo operation page on Wikipedia for more information.
0 mod 3 = 0
1 mod 3 = 1
2 mod 3 = 2
3 mod 3 = 0
4 mod 3 = 1
-1 mod 3 = -1 // 2 in some languages
-2 mod 3 = -2 // 1 in some languages
-3 mod 3 = 0
-4 mod 3 = -1 // 2 in some languages
// if your language supports mod of floats
1.5 mod 3 = 1.5
5.5 mod 3 = 2.5
-1.5 mod 3 = -1.5 // 1.5 in some languages
-5.5 mod 3 = -2.5 // 0.5 in some languages

how to remove rows and cols from main matrix after SVD function?

I have :
A =
1 2 3
2 4 5
5 5 5
and
[U S V]=svd(A)
How can I remove the dimension of A matrix from SVD function?
I'm assuming you want to get a reduced version of the matrix A.
This is done by using PCA, search it. For example, if you want the reduced matrix A to have K dimensions:
[m, ~] = size(A);
Sigma = 1.0/m .* A' * A;
[U, S, ~] = svd(Sigma);
newA = zeros(size(A, 1), K);
for i = 1:size(A, 1),
for j = 1:K,
x = A(i, :)';
projection_k = x' * U(:, j);
newA(i, j) = projection_k;
end
end
end
So the matrix newA will be a reduced version of A with K dimensions.
It's better for you to search about PCA.

How to iterate through a grid algorithm

I am looking for an algorithm that can iterate through a grid and transform it into another grid with the indexes in a new order.
Basically, given a grid of size n*m:
1_1 1_2 1_3 ... 1_n
2_1 2_2 2_3 ... 2_n
.
.
.
m_1 m_2 m_3 ... m_m
How could I transform it to:
1_1 1_2 1_4 ...
1_3 1_5 ...
1_6 ...
...
.
.
.
Assume, you iterate through the first grid, going left to right in the top row, then
left to right in the second row, all the way to, left to right in the bottom row.
Basically I pushing the elements into an upper triangle.
Another problem is how do I figure out the length and width of the grid used to store the triangle just by knowing what n and m is?
Is there a formula for that?
For example, a grid of 5*6, gets changed to 8*7...
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
becomes:
1 2 4 7 11 16 22 29
3 5 8 12 17 23 30
6 9 13 18 24
10 14 19 25
15 20 26
21 27
28
The following seems to work for me:
public static T[,] ConvertToUpperTriangle<T>(T[,] arr)
{
// calculate the dimensions
int elements = arr.GetLength(0) * arr.GetLength(1);
double rows = 0.5 * (Math.Sqrt(8 * elements + 1) - 1);
int newHeight = (int)rows;
int newWidth = (int)Math.Ceiling(rows);
// create the new array
var arr2 = new T[newHeight, newWidth];
int j = 0;
int i = 0;
foreach (T element in arr)
{
arr2[j, i] = element;
i--;
j++;
if (i < 0)
{
i = j;
j = 0;
}
}
return arr2;
}
The 0.5 * (Math.Sqrt(8 * elements + 1) - 1) comes from running sum from 1 to n of n and then solve a = 0.5 * n * (n + 1) for n through Wolfram Alpha.
Edit:
You can get the indices i and j for a given index as follows:
int rows = (int)(0.5 * (Math.Sqrt(8 * index + 1) - 1));
int bottomLeft = (int)(0.5 * rows * (rows + 1));
int difference = index - bottomLeft;
int i;
int j;
if (bottomLeft == index)
{
i = 0;
j = rows - 1;
}
else
{
i = rows + 1 - difference;
j = difference - 1;
}
Let's define the "ordinal position" O(i,j) of each grid element (i,j) in a starting grid NxM, which is the function (i,j) -> i*N + j.
Now for the largest triangular number less than O(i,j), call it T == (k(k+1)/2 for some k, the new grid position for our (i,j) will be:
(i,j) -> ( O(i,j) - T, k + T - O(i,j) )
Now substitute for O(i,j) and T to get:
(i,j) -> ( i*N + j - k(k+1)/2, k + (k+1)(k+2)/2 - i*N + j)
= ( i*N + j - k(k+1)/2, (k+1)(k+2)/2 - i*N + j)
That's as far as I can get it just now.
Update:
Note again that k is the side-length for the triangualr number T == k(k+1)/2.

Order of growth of specific recursive function

What is the order of growth of the following function?
static int counter = 0;
static void Example(int n)
{
if (n == 1) return;
for (int i = 0; i < n; i++)
{
counter++;
}
Example(n / 2);
}
In order to solve it I have done the following:
I first got rid of the inner for loop in order to end up with:
static void Example(int n)
{
if (n == 1) return;
counter++;
Example(n / 2);
}
By analyzing that I was able to tell that the order of growth of that method was log base 2 of n .
so I am thinking that the final answer will be log base 2 times something else. How can I figure it out?
Let's look at both the original and the modified function. In the original function, you have the following amount of work done:
A constant amount of work for the base case check.
O(n) work to count up the number.
The work required for a recursive call to something half the size.
We can express this as a recurrence relation:
T(1) = 1
T(n) = n + T(n / 2)
Let's see what this looks like. We can start expanding this out by noting that
T(n) = n + T(n / 2)
= n + (n / 2 + T(n / 4)
= n + n/2 + T(n / 4)
= n + n/2 + (n / 4 + T(n / 8))
= n + n/2 + n/4 + T(n / 8)
We can start to see a pattern here. If we expand out the T(n / 2) bit k times, we get
T(n) = n + n/2 + n/4 + ... + n/2k + T(n/2k)
Eventually, this stops when n / 2k = 1. When this happens, we have
T(n) = n + n/2 + n/4 + n/8 + ... + 1
What does this evaluate to? Interestingly, this sum is equal to 2n + 1, because the sum n + n/2 + n/4 + n/8 + ... = 2n. Consequently, this first function is O(n). We could have also arrived at this conclusion by using the Master Theorem, but it's interesting to see this approach as well.
So now let's look at the new function. This one does
A constant amount of work for the base case check.
The work required for a recursive call to something half the size.
We can write this recurrence as
T(1) = 1
T(n) = 1 + T(n / 2)
Using the same trick as before, let's expand out T(n):
T(n) = 1 + T(n / 2)
= 1 + 1 + T(n / 4)
= 1 + 1 + 1 + T(n / 8)
More generally, after expanding out k times, we get
T(n) = k + T(n / 2k)
This stops when n / 2k = 1, which happens when k = log2 n (that is, lg n). In this case, we get that
T(n) = lg n + T(1) = lg n + 1
So T(n) = O(lg n) in this case.
Hope this helps!
Let's see now.. this will add 1 to the counter n times.
each call n is reduced by half until it reaches one.
You can get rid of the loop and use
counter+=n;
instead, because basically the loop adds n to counter, 1 by one.
This means that n will be added to the counter each time it runs, and then become smaller by 2 until it reaches one.
so say n = 40.
counter:
40 -> 60 -> 70 -> 75 -> 77 -> 77.
n:
40 -> 20 -> 10 -> 5 -> 2 -> 1.
Just a push in the right direction (counter+=n; being the important part)

Can someone abuse LINQ and solve this money puzzle?

For the fun of it, I would like to see someone use and abuse LINQ to solve this money problem.
I really have no idea how you would do it - I suppose Populating some set and then selecting off of it.
If given a total number of coins and give the total amount of all coins added together:
Show every possible combination of coins. Coins are Quarters(.25), Dimes(.10) Nickels(.05) and Pennies(.01)
Include the option so that there can be zero of a type of coin or there must be at least 1 of each.
Sample Problem: If I have 19 coins and the coins add up to $1.56 and there must be at least 1 of every type of coin.
The answer would be:
1 Quarters, 9 Dimes, 8 Nickels, 1 Pennies
2 Quarters, 5 Dimes, 11 Nickels, 1 Pennies
2 Quarters, 9 Dimes, 2 Nickels, 6 Pennies
3 Quarters, 1 Dimes, 14 Nickels, 1 Pennies
3 Quarters, 5 Dimes, 5 Nickels, 6 Pennies
4 Quarters, 1 Dimes, 8 Nickels, 6 Pennies
5 Quarters, 1 Dimes, 2 Nickels, 11 Pennies
And if we allowed zero for a coint we allowed get an additional
0 Quarters, 13 Dimes, 5 Nickels, 1 Pennies
Here is some sample C# code using a brute force method to solve the problem.
Don't bother improving the sample, let's just see a solution using Linq.
//Try not to use any regualar c# looping code if possible.
private void SolveCoinProblem(int totalNumberOfCoins, double totalAmount, int minimumNumberOfEachCoin)
{
int foundCount = 0;
long numberOfTries = 0;
Console.WriteLine(String.Format("Solving Coin Problem:TotalNumberOfCoins={0}TotalAmount={1}MinimumNumberOfEachCoin{2}", totalNumberOfCoins, totalAmount, minimumNumberOfEachCoin));
for (int totalQuarters = minimumNumberOfEachCoin; totalQuarters < totalNumberOfCoins; totalQuarters++)
{
for (int totalDimes = minimumNumberOfEachCoin; totalDimes < totalNumberOfCoins; totalDimes++)
{
for (int totalNickels = minimumNumberOfEachCoin; totalNickels < totalNumberOfCoins; totalNickels++)
{
for (int totalPennies = minimumNumberOfEachCoin; totalPennies < totalNumberOfCoins; totalPennies++)
{
numberOfTries++;
if (totalQuarters + totalDimes + totalNickels + totalPennies == totalNumberOfCoins)
{
if (Math.Round((totalQuarters * .25) + (totalDimes * .10) + (totalNickels * .05) + (totalPennies * .01),2) == totalAmount)
{
Console.WriteLine(String.Format("{0} Quarters, {1} Dimes, {2} Nickels, {3} Pennies", totalQuarters, totalDimes, totalNickels, totalPennies));
foundCount++;
}
}
}
}
}
}
Console.WriteLine(String.Format("{0} Combinations Found. We tried {1} combinations.", foundCount, numberOfTries));
}
Untested, but:
int minQuarters = 1, minDimes = 1,
minNickels = 1, minPennies = 1,
maxQuarters = 19, maxDimes = 19,
maxNickels = 19, maxPennies = 19,
coinCount = 19, total = 156;
var qry = from q in Enumerable.Range(minQuarters, maxQuarters)
from d in Enumerable.Range(minDimes, maxDimes)
from n in Enumerable.Range(minNickels, maxNickels)
from p in Enumerable.Range(minPennies, maxPennies)
where q + d + n + p == coinCount
where q * 25 + d * 10 + n * 5 + p == total
select new {q,d,n,p};
foreach (var row in qry)
{
Console.WriteLine("{0} quarter(s), {1} dime(s), {2} nickel(s) and {3} pennies",
row.q, row.d, row.n, row.p);
}
Actually, for retail purposes - perhaps a better query is "what is the fewest coins I can give out"? Replace with:
...
from p in Enumerable.Range(minPennies, maxPennies)
where q + d + n + p <= coinCount
where q * 25 + d * 10 + n * 5 + p == total
orderby q + d + n + p
...
and use either First() or Take(...) ;-p
You could also probably reduce the number of checked cases by subtracting (for example) q in the maxDimes test (and so on...) - something like (simplified):
int minCount = 1,
coinCount = 19, total = 156;
var qry = from q in Enumerable.Range(minCount, coinCount - (3 * minCount))
where q * 25 <= total
from d in Enumerable.Range(minCount, coinCount - (q + (2 * minCount)))
where q * 25 + d * 10 <= total
from n in Enumerable.Range(minCount, coinCount - (q + d + minCount))
where q * 25 + d * 10 + n * 5 <= total
from p in Enumerable.Range(minCount, coinCount - (q + d + n))
where q + d + n + p == coinCount
where q * 25 + d * 10 + n * 5 + p == total
select new { q, d, n, p };

Categories