Skip to content

Commit 2230a17

Browse files
Added PossibleAddends utility.
1 parent 267f0d0 commit 2230a17

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

Open.Collections.Numeric.csproj

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<PackageProjectUrl>https://github.com/Open-NET-Libraries/Open.Collections.Numeric/</PackageProjectUrl>
1717
<RepositoryUrl>https://github.com/Open-NET-Libraries/Open.Collections.Numeric/</RepositoryUrl>
1818
<RepositoryType>git</RepositoryType>
19-
<Version>1.4.0</Version>
19+
<Version>1.5.0</Version>
2020
<PackageReleaseNotes></PackageReleaseNotes>
2121
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2222
<PublishRepositoryUrl>true</PublishRepositoryUrl>
@@ -46,9 +46,10 @@
4646
</ItemGroup>
4747

4848
<ItemGroup>
49-
<PackageReference Include="Open.Collections" Version="2.4.6" />
50-
<PackageReference Include="Open.Numeric" Version="1.2.1" />
51-
<PackageReference Include="Open.Threading" Version="1.4.2" />
49+
<PackageReference Include="Open.Collections" Version="2.10.1" />
50+
<PackageReference Include="Open.Numeric" Version="2.3.0" />
51+
<PackageReference Include="Open.Threading" Version="1.6.0" />
52+
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
5253
</ItemGroup>
5354

5455
</Project>

PossibleAddends.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
4+
using System.Collections.Immutable;
5+
6+
namespace Open.Collections.Numeric
7+
{
8+
public class PossibleAddends : IDisposable
9+
{
10+
public PossibleAddends()
11+
{
12+
}
13+
14+
readonly ConcurrentDictionary<int, ConcurrentDictionary<int, IReadOnlyList<IReadOnlyList<int>>>> Cache = new();
15+
16+
public IReadOnlyList<IReadOnlyList<int>> UniqueAddendsFor(int sum, int count)
17+
=> Cache
18+
.GetOrAdd(count, key => new ConcurrentDictionary<int, IReadOnlyList<IReadOnlyList<int>>>())
19+
.GetOrAdd(sum, key => GetUniqueAddends(sum, count).Memoize());
20+
21+
public IEnumerable<IReadOnlyList<int>> GetUniqueAddends(int sum, int count)
22+
{
23+
if (count > int.MaxValue)
24+
throw new ArgumentOutOfRangeException(nameof(count), count, "Cannot be greater than signed 32 bit integer maximum.");
25+
if(count<2 || sum < 3)
26+
yield break;
27+
28+
29+
if (count==2)
30+
{
31+
int i = 0;
32+
loop2:
33+
i++;
34+
if (i * 2 >= sum) yield break;
35+
yield return ImmutableArray.Create(i, sum - i);
36+
37+
goto loop2;
38+
}
39+
40+
{
41+
int i = 2;
42+
var builder = ImmutableArray.CreateBuilder<int>();
43+
44+
while (++i < sum)
45+
{
46+
var next = sum - i;
47+
var addends = UniqueAddendsFor(i, count - 1);
48+
foreach (var a in addends)
49+
{
50+
builder.Capacity = count;
51+
if (a[a.Count - 1] >= next) continue;
52+
builder.AddRange(a);
53+
builder.Add(next);
54+
yield return builder.MoveToImmutable();
55+
}
56+
}
57+
}
58+
}
59+
60+
public void Dispose() => Cache.Clear();
61+
}
62+
}

0 commit comments

Comments
 (0)