Skip to content

Commit 90b89e4

Browse files
Added low memory static methods for PossibleAddends.
1 parent 3d56a7f commit 90b89e4

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

Open.Collections.Numeric.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<PackageProjectUrl>https://github.com/Open-NET-Libraries/Open.Collections.Numeric/</PackageProjectUrl>
1818
<RepositoryUrl>https://github.com/Open-NET-Libraries/Open.Collections.Numeric/</RepositoryUrl>
1919
<RepositoryType>git</RepositoryType>
20-
<Version>1.5.3</Version>
20+
<Version>1.5.4</Version>
2121
<PackageReleaseNotes></PackageReleaseNotes>
2222
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2323
<PublishRepositoryUrl>true</PublishRepositoryUrl>

PossibleAddends.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using Open.Disposable;
22
using System;
3+
using System.Buffers;
34
using System.Collections.Concurrent;
45
using System.Collections.Generic;
56
using System.Collections.Immutable;
7+
using System.Linq;
68

79
namespace Open.Collections.Numeric
810
{
@@ -44,16 +46,18 @@ public IEnumerable<IReadOnlyList<int>> GetUniqueAddends(int sum, int count)
4446

4547
{
4648
int i = 2;
49+
var c1 = count - 1;
50+
var c2 = c1 - 1;
4751
var builder = ImmutableArray.CreateBuilder<int>();
4852

4953
while (++i < sum)
5054
{
5155
var next = sum - i;
52-
var addends = UniqueAddendsFor(i, count - 1);
56+
var addends = UniqueAddendsFor(i, c1);
5357
foreach (var a in addends)
5458
{
5559
builder.Capacity = count;
56-
if (a[a.Count - 1] >= next) continue;
60+
if (a[c2] >= next) continue;
5761
builder.AddRange(a);
5862
builder.Add(next);
5963
yield return builder.MoveToImmutable();
@@ -73,5 +77,59 @@ protected override void OnDispose()
7377
}
7478
Cache.Clear();
7579
}
80+
81+
82+
public static IEnumerable<int[]> GetUniqueAddendsBuffered(int sum, int count)
83+
{
84+
if (count > int.MaxValue)
85+
throw new ArgumentOutOfRangeException(nameof(count), count, "Cannot be greater than signed 32 bit integer maximum.");
86+
if (count < 2 || sum < 3)
87+
yield break;
88+
89+
var pool = ArrayPool<int>.Shared;
90+
var result = pool.Rent(count);
91+
92+
try
93+
{
94+
if (count == 2)
95+
{
96+
int i = 0;
97+
loop2:
98+
i++;
99+
if (i * 2 >= sum) yield break;
100+
result[0] = i;
101+
result[1] = sum - i;
102+
yield return result;
103+
104+
goto loop2;
105+
}
106+
107+
{
108+
int i = 2;
109+
var c1 = count - 1;
110+
var c2 = c1 - 1;
111+
112+
while (++i < sum)
113+
{
114+
var next = sum - i;
115+
var addends = GetUniqueAddendsBuffered(i, c1);
116+
foreach (var a in addends)
117+
{
118+
if (a[c2] >= next) continue;
119+
a.CopyTo(result, 0);
120+
result[c1] = next;
121+
yield return result;
122+
}
123+
}
124+
}
125+
}
126+
finally
127+
{
128+
pool.Return(result);
129+
}
130+
}
131+
132+
public static IEnumerable<IEnumerable<int>> GetUniqueAddendsEnumerable(int sum, int count)
133+
=> GetUniqueAddendsBuffered(sum, count).Select(a => a.Take(count));
76134
}
77135
}

0 commit comments

Comments
 (0)