Aashish
Aashish

Reputation: 81

Distribute integer value among the list values

I have an input and I want to modify the existing list values based on the input distribution with the following logic.

int distributeVal = 7;
List<int> validationList = new List<int>();

distributeVal can be any integer and should be distribute equally among the validationList. Few cases :

distributeVal               validationList               validationList(Updated)
   7                           {5,5,5}                     {5,2}
   7                           {5,6,5}                     {5,2}
   7                           {6,5,5}                     {6,1}
   8                           {2,2,2,3}                   {2,2,2,2}
   8                           {1}                         {1}    (remaining 7 ignored)
   8                           {5,2,7}                     {5,2,1}
   2                           {5,5,5}                     {2}
   3                           {1,1,5}                     {1,1,1}
   8                           {1,45,16}                   {1,7}
   0                           {1,50,50}                   {}

The allocation of validationList should be based on FCFS basis based on it's allowed list value. I tried doing this but with a lot of loops and conditions by dividing the distributeVal based on list values and then modifying it. How can I achieve this in best possible way? Thanks.

Upvotes: 2

Views: 289

Answers (3)

Er&#231;in Dedeoğlu
Er&#231;in Dedeoğlu

Reputation: 5383

Linq supported shortest way:

    private List<int> Validations(int value, List<int> validations)
    {
        List<int> outputList = new List<int>();
        int runningCount = 0;

        foreach (var nextValue in validations.Select(t => runningCount + t > value ? value - runningCount : t))
        {
            outputList.Add(nextValue);
            runningCount += nextValue;
            if (runningCount >= value) break;
        }

        return outputList;
    }

Usage:

var result = Validations(7, new List<int> { 1, 5, 1 });

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186688

You can try Linq in order to query validationList:

  using System.Linq;

  ... 

  int distributeVal = 7;

  List<int> validationList = new List<int>() { 2, 2, 2, 3 };

  ...

  // validationList = if you want to "update" validationList
  var result = validationList
    .TakeWhile(_ => distributeVal > 0)   // Keep on while we have a value to distribute
    .Select(item => {                    // Distribution
      int newItem = item > distributeVal // two cases: 
        ? distributeVal                  //   we can distribute partialy  
        : item;                          //   or take the entire item

      distributeVal -= newItem;          // newItem has been distributed  

      return newItem;
    })
    .ToList();

 Console.Write(string.Join(", ", result));

Outcome:

 2, 2, 2, 1

Upvotes: 3

Martin
Martin

Reputation: 16433

Here's a non-Linq answer that uses a straight-forward function to calculate these:

private List<int> GetValidationList(int distributeVal, List<int> validationList)
{
    List<int> outputList = new List<int>();
    int runningCount = 0;

    for (int i = 0; i < validationList.Count; i++)
    {
        int nextValue;

        if (runningCount + validationList[i] > distributeVal)
            nextValue = distributeVal - runningCount;
        else
            nextValue = validationList[i];

        outputList.Add(nextValue);
        runningCount += nextValue;
        if (runningCount >= distributeVal)
            break;
    }

    return outputList;
}

Essentially, go through each value and add it to the output if it's below the total required. If not, calculate the difference and add that to the output.

Running with these values:

List<int> result;
result = GetValidationList(7, new List<int> { 5, 5, 5 });
result = GetValidationList(7, new List<int> { 5, 6, 5 });
result = GetValidationList(7, new List<int> { 6, 5, 5 });
result = GetValidationList(8, new List<int> { 2, 2, 2, 3 });
result = GetValidationList(8, new List<int> { 1 });
result = GetValidationList(8, new List<int> { 5, 2, 7 });
result = GetValidationList(2, new List<int> { 5, 5, 5 });
result = GetValidationList(3, new List<int> { 1, 1, 5 });
result = GetValidationList(8, new List<int> { 1, 45, 16 });
result = GetValidationList(0, new List<int> { 1, 50, 50 });

Gives this output (in a List<int>):

5,2
5,2
6,1
2,2,2,2
1
5,2,1
2
1,1,1
1,7
0

Upvotes: 2

Related Questions