1

Got stuck on quite simple problem in my code. I need to count what I would call a nested sums of an array. Let's take as an example the array: [1,2,2,3,6] I want to sum them as:

0 + 1 = 1
1 + 2 = 3
1 + 2 + 2 = 5
1 + 2 + 2 + 3 = 8
1 + 2 + 2 + 3 + 6 = 14

sum = 1 + 3 + 5 + 8 + 14 = 31

Edit: I tried to do it with stack, but it failed

            int sums = 0;
            Stack<int> sum = new Stack<int>();

            for (int i = 0; i < queries.Length; i++)
            {
                sum.Push(queries[i]);
            }

            for (int i = 0; sum.Count != 0; i++)
            {
                if(i != 0)
                {
                    sums += sum.Pop();
                }
            }
4
  • 1
    Please add an attempt you have made and we will be glad to help. HINT You could use a recersive method or nested for loops, etc. Commented Jul 6, 2022 at 18:15
  • Added one of the attempts Commented Jul 6, 2022 at 18:16
  • @gunr2171 yea, I know how to do single array sum. But not this one :( Commented Jul 6, 2022 at 18:17
  • Kind of yea, tried to put it in some loop to do 2 times, but it failed Commented Jul 6, 2022 at 18:18

3 Answers 3

2

You can run this task in a single loop considering when you have an array of size 5, the first element is repeating 5 times, second element repeating 4 times and etc.

int[] arr = { 1, 2, 2, 3, 6 };

int mysum = 0;
for (int i = 0; i < arr.Length; i++)
    mysum += (arr.Length - i) * arr[i];

Console.WriteLine(mysum);

Output:

31

Explanation:

1                 = 1
1 + 2             = 3
1 + 2 + 2         = 5
1 + 2 + 2 + 3     = 8
1 + 2 + 2 + 3 + 6 = 14
========================
5*1 + 4*2 + 3*2 + 2*3 + 1*6 = 31
Sign up to request clarification or add additional context in comments.

3 Comments

Ohh thanks. Could you explain to me, how it works? It looks a bit odd ... You are just multiplying index by a element?
@raicha I rewrite your expected sum and as you can see, first element is repeating 5 times (which is length of array minus index) and etc.
Looping backwards would make more sense probably
1

You can do this much more efficiently and more easily, by multiplying each value by its reversed index + 1

For example, using LINQ

int[] arr = { 1, 2, 2, 3, 6 };
var result = arr.Reverse().Select((val, i) => val * (i + 1)).Sum();

Note that .Reverse on an array (or other Collection<T>) does not actually move any items, it just reads them backwards. So this is therefore an O(n) operation, as opposed to your original solution which is O(n2 / 2)

dotnetfiddle

You can also do this procedurally, this is almost the same as @aminrd's answer.

int[] arr = { 1, 2, 2, 3, 6 };
var result = 0;
for (var i = arr.Length - 1; i >= 0; i--)
    result += arr[i] * (i + 1);

1 Comment

Thanks :) More efficient way
1

Take advantage of Linq! .Sum() will add up everything in your collection. You run that twice, once per each slice, and once per each subtotal.

var input = new [] { 1, 2, 2, 3, 6 };
var totalSum = Enumerable.Range(1, input.Length).Sum(len => input[0..len].Sum());
// totalSum is 31

Enumerable.Range gets you a collection of numbers between (and including) 1 and 5 - the possible lengths of each slice of your sub arrays. You then use the range operator [0..#] to get increasingly larger slices.

Yes, this is not as clever as aminrd's solution - it's doing all the computations manually and you're performing many slices.

1 Comment

input.Take(len).Sum() would avoid slices (and possibly easier to read for old non-python folks).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.