Let's start form target array. What is it?
Having {7, 2, 2} we want to obtain {4, 4, 3}. So every item is at least 3 and some top items are 3 + 1 == 4.
The algorithm is
let sum = sum(original)
let rem = sum(original) % length(original) # here % stands for remainder
target[i] = sum / length(original) + (i < rem ? 1 : 0)
Having original and target
original: 7 2 2
target: 4 4 3
transfer: 3 2 1 (6 in total)
note, that
transfer[i] is just an absolute difference: abs(original[i] - target[i])
- we count each
transfer twice: once we subtract and then we add.
So the answer is
sum(transfer[i]) / 2 == sum(abs(original[i] - target[i])) / 2
Code (c#):
private static int Solve(int[] initial) {
// Don't forget about degenerated cases
if (initial is null || initial.Length <= 0)
return 0;
int sum = initial.Sum();
int rem = sum % initial.Length;
int result = 0;
for (int i = 0; i < initial.Length; ++i)
result += Math.Abs(sum / initial.Length + ((i < rem) ? 1 : 0) - initial[i]);
return result / 2;
}
Demo: (Fiddle)
int[][] tests = new int[][] {
new int[] {7, 2, 2},
new int[] {2, 2, 7},
new int[] {},
new int[] {2, 2, 2},
new int[] {1, 2, 3},
};
string report = string.Join(Environment.NewLine, tests
.Select(test => $"[{string.Join(", ", test)}] => {Solve(test)}"));
Console.Write(report);
Outcome:
[7, 2, 2] => 3
[2, 2, 7] => 4
[] => 0
[2, 2, 2] => 0
[1, 2, 3] => 1