Home > database >  C# function to distribute weight in a list of numbers
C# function to distribute weight in a list of numbers

Time:08-25

I have a list of numbers that is something like this.

Name Amount
Val 1 500
Val 2 600
Val 3 350
Val 4 500
Val 5 450
Val 6 600

Sum of all Amount(s) is 3000 which will remain constant.

The problem I am trying to solve is if I remove one or more rows, amount in remaining rows should increase proportionally so that the sum of Amount(s) of all remaining rows should be 3000.

Any help would be appreciated. I am trying to code this in C#.

CodePudding user response:

There are several options, but this seems straightforward:

  • When removing a row, store the removed quantity in a variable. Let's call it removedAmount.
  • After removing the row, create an array (or some other data structure) to store what percentage of the remaining total each row represents. This will be something like: row.percent = (rowAmount / totalAmount);
  • Loop through the remaining rows and add (removedAmount * percent) to each of them.

There may be some edge cases, particularly if rounding is involved at any step, which could cause your total to end up as an amount that is slightly different from 3000. If this turns out to be the case, there is probably a mathematically perfect way to solve it, however... You could add a step where you detect this difference and remove it proportionally using those same percentages. It would force you to end up at 3000 to matter what, and it should be "pretty good" depending on what you're doing.

Seems workable.

CodePudding user response:

I have come to the same solution logic as Brian.
So if someone in future will be curious on this topic I just put my implementation here.

using System;
using System.Linq;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        double[] arr = {500,600,350,500,450,600};
        List<double> list = arr.ToList();
        
        PrintList(list);
        
        //get value of first element
        double removed = list.ElementAt(0);
        //remove first element
        list.RemoveAt(0);
        
        //calculate percentage distribution of all other elements
        List<double> perc = CalcPercentages(list);
        
        //add some portion of deleted value to each remaining element
        List<double> newList = list.Select( (x,i) => x   removed * perc[i]).ToList();
        
        PrintList(newList);
        
    }
    public static List<double> CalcPercentages(List<double> arr){
        double sum = arr.Sum();
        return arr.Select(x=> x / sum).ToList();
    }
    public static void PrintList(List<double> arr){
        string arrayToDisplay = String.Join(", ",arr);
        Console.WriteLine(arrayToDisplay);
    }
}

Here is a link to c# fiddle to play with this code

  •  Tags:  
  • c#
  • Related