Update 3: Added VB.Net versions
Here is another quick one:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LargestGroupSum
{
static class Program
{
static void Main(string[] args)
{
foreach (var test in new List<List<int>>()
{
new List<int>(),
new List<int>() { -1, -2, -5, -4, -5, -1, -2, -11 },
new List<int>() { 1, 2, 5, 4, 5, 1, 2, 11 },
new List<int>() { 1, 2, -5, 4, 5, -1, 2, -11 },
new List<int>() { 1, 2, 4, -20, 4, 2, 1, -15, 3, 2, 2 },
new List<int>() { 5, -5, 5, -10, 5, -5, 5 },
new List<int>() { 5, -5, 5, -5, 5 },
new List<int>() { 5, 5, -5, -6 },
new List<int>() { -1, -1, 1, -1, 2 }
})
{
var lg = test.LargestGroupSumList();
Console.WriteLine($"For [{string.Join(",", test)}], the largest group is [{string.Join(",", lg)}] with {(lg.Any() ? $"a sum of {lg.Sum()}" : "no value")}");
}
Console.WriteLine("\r\n-- Press any key to exit --");
Console.ReadKey();
}
}
public static class HelperExtensions
{
public static IList<int> LargestGroupSumList(this IList<int> list)
{
if (!list.Any(x => x >= 1))
return new List<int>();
else if (!list.Any(x => x < 1))
return list;
else
{
var groups = new List<List<int>>();
for (int i = 0; i < list.Count; i++)
for (int j = 0; j < list.Count - i; j++)
groups.Add(list.Skip(i).Take(j + 1).ToList());
return groups.OrderByDescending(X => X.Count).OrderByDescending(x => x.Sum()).First();
}
}
}
}
Imports System.Runtime.CompilerServices
Module Module1
Sub Main()
For Each test In New List(Of List(Of Integer))() From {
New List(Of Integer)(),
New List(Of Integer)() From {-1, -2, -5, -4, -5, -1, -2, -11},
New List(Of Integer)() From {1, 2, 5, 4, 5, 1, 2, 11},
New List(Of Integer)() From {1, 2, -5, 4, 5, -1, 2, -11},
New List(Of Integer)() From {1, 2, 4, -20, 4, 2, 1, -15, 3, 2, 2},
New List(Of Integer)() From {5, -5, 5, -10, 5, -5, 5},
New List(Of Integer)() From {5, -5, 5, -5, 5},
New List(Of Integer)() From {5, 5, -5, -6},
New List(Of Integer)() From {-1, -1, 1, -1, 2}}
Dim lg = test.LargestGroupSumList()
Console.WriteLine("For [{0}], the largest group is [{1}] with {2}", String.Join(",", test), String.Join(",", lg), If(lg.Any(), String.Format("a sum of {0}", lg.Sum()), "no value"))
Next
Console.WriteLine("{0}-- Press any key to exit --", vbCrLf)
Console.ReadKey()
End Sub
End Module
Public Module HelperExtensions
<Extension>
Public Function LargestGroupSumList(list As IList(Of Integer)) As IList(Of Integer)
If Not list.Any(Function(x) x >= 1) Then
Return New List(Of Integer)()
ElseIf Not list.Any(Function(x) x < 1) Then
Return list
Else
Dim groups = New List(Of List(Of Integer))()
For i As Integer = 0 To list.Count - 1
For j As Integer = 0 To list.Count - i - 1
groups.Add(list.Skip(i).Take(j + 1).ToList())
Next
Next
Return groups.OrderByDescending(Function(x) x.Count).OrderByDescending(Function(x) x.Sum()).First()
End If
End Function
End Module
Outputs:
For [], the largest group is [] with no value
For [-1,-2,-5,-4,-5,-1,-2,-11], the largest group is [] with no value
For [1,2,5,4,5,1,2,11], the largest group is [1,2,5,4,5,1,2,11] with a sum of 31
For [1,2,-5,4,5,-1,2,-11], the largest group is [4,5,-1,2] with a sum of 10
For [1,2,4,-20,4,2,1,-15,3,2,2], the largest group is [1,2,4] with a sum of 7
For [5,-5,5,-10,5,-5,5], the largest group is [5,-5,5] with a sum of 5
For [5,-5,5,-5,5], the largest group is [5,-5,5,-5,5] with a sum of 5
For [5,5,-5,-6], the largest group is [5,5] with a sum of 10
For [-1,-1,1,-1,2], the largest group is [1,-1,2] with a sum of 2
-- Press any key to exit --
And you can run it
online[
^]
Update
Here is another version that handles multiple return sets that are equally the largest possible sum of consecutive numbers.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LargestGroupSum
{
static class Program
{
static void Main(string[] args)
{
Console.WriteLine("Largest possible sum of consecutive numbers");
Console.WriteLine("===========================================");
foreach (var test in new List<List<int>>()
{
new List<int>(),
new List<int>() { -1, -2, -5, -4, -5, -1, -2, -11 },
new List<int>() { 1, 2, 5, 4, 5, 1, 2, 11 },
new List<int>() { 1, 2, -5, 4, 5, -1, 2, -11 },
new List<int>() { 1, 2, 4, -20, 4, 2, 1, -15, 3, 2, 2 },
new List<int>() { 5, -5, 5, -10, 5, -5, 5 },
new List<int>() { 5, -5, 5, -5, 5 },
new List<int>() { 5, 5, -5, -6 },
new List<int>() { -1, -1, 1, -1, 2 }
})
{
var results = test.LargestGroupSumList();
Console.WriteLine($"\r\nFor [{string.Join(", ", test)}], there {(results.Count() > 1 ? "are multiple sets" : results.FirstOrDefault() == null ? "are no sets" : "is one set")}");
foreach (var lg in results)
if (lg != null) Console.WriteLine($"... the largest group is [{string.Join(", ", lg)}] with a sum of {lg.Sum()}");
}
Console.WriteLine("\r\n-- Press any key to exit --");
Console.ReadKey();
}
}
public static class HelperExtensions
{
public static IEnumerable<IList<int>> LargestGroupSumList(this IList<int> list)
{
if (!list.Any(x => x >= 1))
yield return null;
else if (!list.Any(x => x < 1))
yield return list;
else
{
var groups = new List<List<int>>();
for (int i = 0; i < list.Count; i++)
for (int j = 0; j < list.Count - i; j++)
groups.Add(list.Skip(i).Take(j + 1).ToList());
var results = groups.OrderByDescending(X => X.Count).OrderByDescending(x => x.Sum()).ToList();
int sum = results.First().Sum(), count = results.First().Count;
foreach (var item in results)
if (item.Sum().Equals(sum) && item.Count.Equals(count)) yield return item;
}
}
}
}
Imports System.Runtime.CompilerServices
Module Module1
Sub Main()
Console.WriteLine("Largest possible sum of consecutive numbers")
Console.WriteLine("===========================================")
For Each test In New List(Of List(Of Integer))() From {
New List(Of Integer)(),
New List(Of Integer)() From {-1, -2, -5, -4, -5, -1, -2, -11},
New List(Of Integer)() From {1, 2, 5, 4, 5, 1, 2, 11},
New List(Of Integer)() From {1, 2, -5, 4, 5, -1, 2, -11},
New List(Of Integer)() From {1, 2, 4, -20, 4, 2, 1, -15, 3, 2, 2},
New List(Of Integer)() From {5, -5, 5, -10, 5, -5, 5},
New List(Of Integer)() From {5, -5, 5, -5, 5},
New List(Of Integer)() From {5, 5, -5, -6},
New List(Of Integer)() From {-1, -1, 1, -1, 2}
}
Dim results = test.LargestGroupSumList()
Console.WriteLine("{0}For [{1}], there {2}", vbCrLf, String.Join(", ", test), (If(results.Count > 1, "are multiple sets", If(results.FirstOrDefault() Is Nothing, "are no sets", "is one set"))))
For Each lg In results
If lg IsNot Nothing Then
Console.WriteLine("... the largest group is [{0}] with a sum of {1}", String.Join(", ", lg), lg.Sum())
End If
Next
Next
Console.WriteLine("{0}-- Press any key to exit --", vbCrLf)
Console.ReadKey()
End Sub
End Module
Public Module HelperExtensions
<Extension>
Public Iterator Function LargestGroupSumList(list As IList(Of Integer)) As IEnumerable(Of IList(Of Integer))
If Not list.Any() OrElse Not list.Any(Function(x) x > 1) Then
Yield Nothing
ElseIf Not list.Any(Function(x) x < 1) Then
Yield list
Else
Dim groups = New List(Of List(Of Integer))()
For i As Integer = 0 To list.Count - 1
For j As Integer = 0 To list.Count - i - 1
groups.Add(list.Skip(i).Take(j + 1).ToList())
Next
Next
Dim results = groups.OrderByDescending(Function(x) x.Count).OrderByDescending(Function(x) x.Sum()).ToList()
Dim sum As Integer = results.First().Sum(), count As Integer = results.First().Count
For Each item In results
If item.Sum().Equals(sum) AndAlso item.Count.Equals(count) Then
Yield item
End If
Next
End If
End Function
End Module
Outputs:
Largest possible sum of consecutive numbers
===========================================
For [], there are no sets
For [-1, -2, -5, -4, -5, -1, -2, -11], there are no sets
For [1, 2, 5, 4, 5, 1, 2, 11], there is one set
... the largest group is [1, 2, 5, 4, 5, 1, 2, 11] with a sum of 31
For [1, 2, -5, 4, 5, -1, 2, -11], there is one set
... the largest group is [4, 5, -1, 2] with a sum of 10
For [1, 2, 4, -20, 4, 2, 1, -15, 3, 2, 2], there are multiple sets
... the largest group is [1, 2, 4] with a sum of 7
... the largest group is [4, 2, 1] with a sum of 7
... the largest group is [3, 2, 2] with a sum of 7
For [5, -5, 5, -10, 5, -5, 5], there are multiple sets
... the largest group is [5, -5, 5] with a sum of 5
... the largest group is [5, -5, 5] with a sum of 5
For [5, -5, 5, -5, 5], there is one set
... the largest group is [5, -5, 5, -5, 5] with a sum of 5
For [5, 5, -5, -6], there is one set
... the largest group is [5, 5] with a sum of 10
For [-1, -1, 1, -1, 2], there is one set
... the largest group is [1, -1, 2] with a sum of 2
-- Press any key to exit --
And you can run it
online[
^]
Update #2
Looking at the extension method, I felt that I could reduce it from 12 lines of code into 1 using Linq! Here is the new single-line (split onto multiple lines to avoid wrapping) extension method using Linq Method Syntax:
public static List<List<int>> LargestGroupSumList(this List<int> list)
=> !list.Any(x => x >= 1) ? new List<List<int>>() :
!list.Any(x => x < 1) ? new List<List<int>>() { list } :
Enumerable.Range(0, list.Count).SelectMany(x =>
Enumerable.Range(1, list.Count - x).Select(y =>
list.Skip(x).Take(y).ToList()))
.OrderByDescending(x => x.Sum()).ThenByDescending(x => x.Count)
.GroupBy(x => x.Sum()).First()
.GroupBy(x => x.Count).First().ToList();
<Extension>
Public Function LargestGroupSumList(list As List(Of Integer)) As List(Of List(Of Integer))
Return If(Not list.Any(Function(x) x >= 1), New List(Of List(Of Integer))(),
If(Not list.Any(Function(x) x < 1), New List(Of List(Of Integer))() From {list},
Enumerable.Range(0, list.Count).SelectMany(Function(x) _
Enumerable.Range(1, list.Count - x).[Select](Function(y) _
list.Skip(x).Take(y).ToList())) _
.OrderByDescending(Function(x) x.Sum()) _
.ThenByDescending(Function(x) x.Count) _
.GroupBy(Function(x) x.Sum()).First() _
.GroupBy(Function(x) x.Count).First().ToList()))
End Function
And here is the Linq Query Syntax version (again: split onto multiple lines to avoid wrapping):
public static List<List<int>> LargestGroupSumList(this List<int> list)
=> !list.Any(x => x >= 1) ? new List<List<int>>() :
!list.Any(x => x < 1) ? new List<List<int>>() { list } :
(from gs in (from x in Enumerable.Range(0, list.Count)
from y in Enumerable.Range(1, list.Count - x)
let r = list.Skip(x).Take(y).ToList()
orderby r.Sum() descending, r.Count descending
group r by r.Sum()).First()
group gs by gs.Count).First().ToList();
<Extension>
Public Function LargestGroupSumList(list As List(Of Integer)) As List(Of List(Of Integer))
Return If(Not list.Any(Function(x) x >= 1), New List(Of List(Of Integer))(),
If(Not list.Any(Function(x) x < 1), New List(Of List(Of Integer))() From {list},
(From x In (From x In
(From x In Enumerable.Range(0, list.Count)
From y In Enumerable.Range(1, list.Count - x)
Let r = list.Skip(x).Take(y).ToList()
Order By r.Sum() Descending, r.Count Descending
Group By r.Sum() Into gs = Group).First().gs
Group By x.r.Count() Into gc = Group).First().gc
Select x.r).ToList()))
End Function
You can read more about the two Linq syntaxes in the
Query Syntax and Method Syntax in LINQ (C#)[
^] article on MSDN.
Note: If only a single result is required, then simply request it from the returned list:
test.LargestGroupSumList().FirstOrDefault()