Populate array with incremental values topping grand total - c#

I have an array of floats that would be declared with a variable length. I would like to have a loop that would assign to each element a value proportioned to its position in the array, and the grand total of all the elements should be fixed (to 100).
int arrLength = 5; //this would variate
float grandTotal = 100; //the sum of all the elements should be equal to this
float[] arr = new float[arrLength]();
for(int i=1; i < arr.Length - 1; i++)
{
//logic to attribute values to the elements
}
What I want to achieve is for the elements to represent probabilistic values (in %). The idea is that the lower the index the higher the value they have. So for instance if the length would be equal to 5 the output array should have values like:
arr={30, 25, 20, 15, 10};
As you can see the values are decreasing and total of them is 100. I could I get this type of result regardless of the length of the array?
Thanks.

It seems you need to implement Arithmetic progression (https://en.wikipedia.org/wiki/Arithmetic_progression).
Arithmetic progression has to parameters, start element a0 and difference d.
In your case, the sum of arithmetic progression is grandTotal.
Here we have two unknown variables: a0 and d.
To handle this, we should play with different assumptions.
We could suppose that a0 = d.
In this case
d = 2*grandTotal/(n*(2+n-1))
(n is arrLength).
In your example it will be 2*200/(5*(5+1)) = 6.666666666..., and elements will be 6.66666666, 13.33333333333, 20, 26.666666666, 33.3333333333.
Looks not very pretty.
We could suppose that a0 = 2*d. In this case d = 5 (formula will be d = 2*grandTotal/(n*(2*2+n-1))), and progression is 10, 15, 20, 25, 30.
So, you should implement two loops. First should try different assumptions, e.g. a0 = d, a0 = 2*d, a0 = 3*d, to find "pretty" difference. And then, iterate to fill and array.
We could suppose that a0 = sqrt(grandTotal). In this case d = (2*grandTotal/n-2*a[0])/(n-1) (in your example, it will produce 10, 15, 20, 25, 30).
You may start with second way.
When you get a0 and n, the loop looks like:
for (int i = 0; i < n; ++i)
arr[i] = a0 + d*(n-i-1);

int arrLength = 5;
float grandTotal = 100;
float[] arr = new float[arrLength];
int arrLengthInc = arrLength + 1;
int sum = (arrLengthInc * arrLengthInc / 2) + (arrLengthInc / 2) - 1;
for (int i = 0; i < arr.Length; i++)
{
arr[i] = (i + 2) * grandTotal / sum;
}
// output: // [10, 15, 20, 25, 30]
Console.WriteLine("[{0}]", string.Join(", ", arr));
You need to determine the sum of the whole array, for normalize them.
for example:
2 + 3 + 4 = 9
+-+-+-+-+
| | | |/|
+-+-+-+-+
| | |/|#|
+-+-+-+-+
| |/|#|#|
+-+-+-+-+
|/|#|#|#|
+-+-+-+-+ 4*4 / 2 = 0.5 + 1.5 + 2.5 + 3.5 = 8
The items on the diagonal consume half space.
+-+-+-+-+
| | | |#|
+-+-+-+-+
| | |#|#|
+-+-+-+-+
| |#|#|#|
+-+-+-+-+
|#|#|#|#|
+-+-+-+-+ (4*4 / 2) + (4 / 2) = 0.5 + 1.5 + 2.5 + 3.5 = 10
Index one is missing.
+-+-+-+-+
| | | |#|
+-+-+-+-+
| | |#|#|
+-+-+-+-+
| |#|#|#|
+-+-+-+-+
| |#|#|#|
+-+-+-+-+ (4*4 / 2) + (4 / 2) - 1 = 0.5 + 1.5 + 2.5 + 3.5 = 9

for (int i = 0; i < arr.Length; i++)
{
arr[arr.Length -1 - i] = ((i+2) * arrLength)%grandTotal;
}

//sum of array length elements
int factor=((arrLength*arrlength)+arrLength)/2;
.......
ar[i]=grandTotal/factor*(arrLength-i+1);

Related

C# For loop index returns ascii instead of current iteration

I need to make a program that calculates the factorial of a number and sums the different numbers.
I'm stuck at the point where I need to take the current number in the for loop to do it's factorial (e.g. the number 145 and I can't take the 5). I've tried the following:
for (int i = length-1; i >= 0; i--)
{
int currentNumber = inputString[i];
currentSum = currentSum * i;
sum += currentSum;
}
inputString is the length of the given number.
The problem is that in this way currentNumber becomes the ascii equivalent (if i = 3 currentSum becomes 51). How do I make currentSum become 3?
Alternatively you could use:
int currentNumber = int.Parse(inputString[i].ToString());
I'd like to suggest an alternative:
int num = int.Parse(inputString); // Convert whole input to int
int sum = 0;
while( num != 0 ) // >0 is not enough, num could be negative.
{
sum += num % 10; // Sum up least significant place
num = num / 10; // "Decimal shift right"
}
With your example "145" this would mean:
Iteration 1:
sum += 145 % 10 => sum = 0 + 5 = 5
num = num / 10 => num = 145 / 10 = 14
Iteration 2:
sum += 14 % 10 => sum = 5 + 4 = 9
num = num / 10 => num = 14 / 10 = 1
Iteration 3:
sum += 1 % 10 => sum = 9 + 1 = 10
num = num / 10 => num = 1 / 10 = 0
num == 0 => end while , sum = 10
Disclaimer: This assumes, the input is in fact a valid integer value. I'd strongly suggest to validate that, first. "Never trust user input."
Assuming inputString is numeric only, you can get away with:
int currentNumber = inputString[i] - '0';
Short explanation: character representation of number '3' is 51, but they are in order (so '0' is 48, '1' is 49, etc.) and you can get the "numerical value" of a character by removing the offset (which is the value of '0').

Get range in multiplication of 5

I have a number. For instance, my number is 19 . Then I want to populate my drop down with range in multiplication of 5. So my dropdownlist will consist of items of:
1-5
6-10
11-15
16-19
I tried modulus and division, however, I can't seems to get the range. Is there a fixed method?
Sample code
List<string> range = new List<string>();
int number = 19;
int numOfOccur = (19/5);
for (int i = 1; i < numOfOccur ; i++)
{
range.Add(i + " - " + (i * 5))
}
Sometime I think that old school code, without fancy linq is a bit more clear
int maximum = 19;
int multiple = 5;
int init = 1;
while (init + multiple <= maximum )
{
string addToDDL = init.ToString() + "-" + (init + multiple - 1).ToString();
Console.WriteLine(addToDDL);
init += multiple;
}
if(init <= maximum)
{
string last = init.ToString() + "-" + maximum.ToString();
Console.WriteLine(last);
}
Linq solution (modern techs allow us to put it consize):
int number = 19;
int div = 5;
List<string> range = Enumerable
.Range(0, number / div + (number % div == 0 ? 0 : 1))
.Select(i => $"{i * div + 1} - {Math.Min((i + 1) * div, number)}")
.ToList();
Test
Console.Write(string.Join(Environment.NewLine, range));
Returns
1 - 5
6 - 10
11 - 15
16 - 19
When using modulo arithmetics, do not forget about remainders: you have an error in int numOfOccur = (19/5); line. It should be
int numOfOccur = 19 / 5 + (19 % 5 == 0 ? 0 : 1);
for the last incomplete 16 - 19 range to be proceeded.
Add this package to your project : https://www.nuget.org/packages/System.Interactive/
Then you can do this:
IEnumerable<IList<int>> buffers2 = Enumerable.Range(1, 19).Buffer(5);
IList<int>[] result2 = buffers2.ToArray();
// { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, ...
Don't forget to add System.Interactive namespace to your using block.

Dealing with large integers without BigInteger Library in Algorithm contests

Problem: Topcoder SRM 170 500
Consider a sequence {x0, x1, x2, ...}. A relation that defines some term xn in terms of previous terms is called a recurrence relation. A linear recurrence relation is one where the recurrence is of the form xn = c(k-1) * x(n-1) + c(k-2) * x(n-2) + ... + c(0) * x(n-k)
where all the c(i) are real-valued constants, k is the length of the recurrence relation, and n is an arbitrary positive integer which is greater than or equal to k.
You will be given a int[] coefficients, indicating, in order, c(0), c(1), ..., c(k-1). You will also be given a int[] initial, giving the values of x(0), x(1), ..., x(k-1), and an int N. Your method should return xN modulo 10.
More specifically, if coefficients is of size k, then the recurrence relation will be
xn = coefficients[k - 1] * xn-1 + coefficients[k - 2] * xn-2 + ... + coefficients[0] * xn-k.
For example, if coefficients = {2,1}, initial = {9,7}, and N = 6, then our recurrence relation is xn = xn-1 + 2 * xn-2 and we have x0 = 9 and x1 = 7. Then x2 = x1 + 2 * x0 = 7 + 2 * 9 = 25, and similarly, x3 = 39, x4 = 89, x5 = 167, and x6 = 345, so your method would return (345 modulo 10) = 5.
Constraints:
- Code must run in less than or equal to 2 seconds
- Memory utilization must not exceed 64 MB
My attempted Solution:
class RecurrenceRelation
{
public int moduloTen(int[] coefficients, int[] initial, int N)
{
double xn = 0; int j = 0;
int K = coefficients.Length;
List<double> xs = new List<double>(Array.ConvertAll<int, double>(initial,
delegate(int i)
{
return (double)i;
}));
if (N < K)
return negativePositiveMod(xs[N]);
while (xs.Count <= N)
{
for (int i = xs.Count - 1; i >= j; i--)
{
xn += xs[i] * coefficients[K--];
}
K = coefficients.Length;
xs.Add(xn);
xn = 0;
j++;
}
return negativePositiveMod(xs[N]);
}
public int negativePositiveMod(double b)
{
while (b < 0)
{
b += 10;
}
return (int)(b % 10);
}
}
My problem with this solution is the precision of the double representation, and since I can't use a third party library or the BigInteger library in .NET for this SRM, i need to find a way of solving it without them. I suspect I could use recursion but I'm a little clueless on how to go about that.
Here is a test case that shows when my code works and when it doesn't
{2,1}, {9,7}, 6 - Successfully returns 5
{9,8,7,6,5,4,3,2,1,0}, {1,2,3,4,5,6,7,8,9,10}, 654 - Unsuccessfully returns 8 instead of 5 due to precision of double type
Can anyone help me figure this out? I was going to consider using arrays to store the values but it is a little bit beyond me especially on how to cater for multiplication and still be within the time and space complexity set out in the problem. Perhaps my entire approach is wrong? I'd appreciate some pointers and direction (not fully fleshed out answers) answers please.
Thanks
Notice that we only need to return the modulo 10 of xn.
We also need to know that if a = b + c, we have a % 10 = (b % 10 + c % 10) %10.
And a = b*c, so we also have a % 10 = (b %10 * c % 10) % 10;
So, for
xn = c(k-1) * x(n-1) + c(k-2) * x(n-2) + ... + c(0) * x(n-k)
= a0 + a1 + .... + an
(with a0 = c(k - 1)*x(n-1), a1 = ...)
we have xn % 10 = (a0 % 10 + a1 % 10 + ...)%10
And for each ai = ci*xi, so ai % 10 = (ci % 10 * xi % 10)% 10.
So by doing all of these math calculations, we can avoid to use double and keep the result in manageable size.
As Pham has answered, the trick is to realize that you only need to return a modulo, thereby bypassing the problem of overflow. Here is my quick attempt. I use a queue to put in the last result xN, and evict the oldest one.
static int solve(int[] coefficients, int[] seed, int n)
{
int k = coefficients.Count();
var queue = new Queue<int>(seed.Reverse().Take(k).Reverse());
for (int i = k; i <= n; i++)
{
var xn = coefficients.Zip(queue, (x, y) => x * y % 10).Sum() % 10;
queue.Enqueue(xn);
queue.Dequeue();
}
return (int) (queue.Last() );
}
Edit:
Getting the same results as you expect, however I don't guarantee that there is no bug in this example.

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.

Every possible combination of X split into N stacks

I am sure this problem has a formal name, and knowing that name would probably help me find the solution, but I don't know it, and wording the problem for Google keeps pointing me to the Knapsack Problem, which isn't the same thing.
I want to take some value X and find every possible combination of splitting that value into N stacks of whole integers.
In case my wording is confusing, here is an example of X = 4, N = 3
Stack -> 1 | 2 | 3 |
----------------------
#1-----> 4 | 0 | 0 |
----------------------
#2-----> 3 | 1 | 0 |
----------------------
#3-----> 2 | 1 | 1 |
----------------------
#4-----> 2 | 2 | 0 |
Duplication is acceptable, since its easy to remove, but ideally it would not be calculated. An algorithm for solving the problem would be perfect, but even finding out of the problem has a name would make research easier. Thanks.
These are in fact integer partitions as a deleted answer remarks. Using Mathematica:
IntegerPartitions[4, 3] // PadRight //Grid
Output:
4 0 0
3 1 0
2 2 0
2 1 1
I could not find a C# implementation but here are a couple of related questions:
Elegant Python code for Integer Partitioning
Integer Partition in Java
Algorithm for generating integer partitions
Google hits:
Integer Partition Algorithm by Jerome Kelleher
Integer Partition Algorithm by Daniel Scocco
Fast Algorithms for Generating Integer Partitions (PDF) (looks heavy-duty)
Stony Brook Algorithm Repository - Partitions
This seems to do the trick:
vector<vector<int> > partitions(int X, int N, int Y)
{
vector<vector<int> > v;
if(X<=1 || N==1)
{
if(X<=Y)
{
v.resize(1);
v[0].push_back(X);
}
return v;
}
for(int y=min(X, Y); y>=1; y--)
{
vector<vector<int> > w = partitions(X-y, N-1, y);
for(int i=0; i<w.size(); i++)
{
w[i].push_back(y);
v.push_back(w[i]);
}
}
return v;
}
int main()
{
vector<vector<int> > v = partitions(5, 3, 5);
int i;
for(i=0; i<v.size(); i++)
{
int x;
for(x=0; x<v[i].size(); x++)
printf("%d ", v[i][x]);
printf("\n");
}
return 0;
}
This is user434507's answer in C#:
class Program
{
static void Main(string[] args)
{
var v = Partitions(5, 3, 5);
for (int i = 0; i < v.Count; i++)
{
for (int x = 0; x < v[i].Count; x++)
Console.Write(v[i][x] + " ");
Console.WriteLine();
}
}
static private List<List<int>> Partitions(int total, int stacks, int max)
{
List<List<int>> partitions = new List<List<int>>();
if (total <= 1 || stacks == 1)
{
if (total <= max)
{
partitions.Add(new List<int>());
partitions[0].Add(total);
}
return partitions;
}
for (int y = Math.Min(total, max); y >= 1; y--)
{
var w = Partitions(total - y, stacks - 1, y);
for (int i = 0; i < w.Count; i++)
{
w[i].Add(y);
partitions.Add(w[i]);
}
}
return partitions;
}
}

Categories