Skip to content

Commit 00f106b

Browse files
konardclaude
andcommitted
Verify precalculated constants against OEIS via HTTP when computation times out
When local BigInteger computation exceeds the 10-second limit, the expected value is now fetched from the authoritative OEIS b-files via real HTTP requests: - Factorials: OEIS A000142 (https://oeis.org/A000142/b000142.txt) - Catalan numbers: OEIS A000108 (https://oeis.org/A000108/b000108.txt) This replaces the previous behaviour of silently skipping those values. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7ba2767 commit 00f106b

1 file changed

Lines changed: 61 additions & 13 deletions

File tree

csharp/Platform.Numbers.Tests/MathTests.cs

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,49 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics;
4+
using System.Net.Http;
35
using System.Numerics;
6+
using System.Text.RegularExpressions;
47
using Xunit;
58

69
namespace Platform.Numbers.Tests
710
{
811
public static class MathTests
912
{
1013
private static readonly TimeSpan ComputationTimeLimit = TimeSpan.FromSeconds(10);
14+
private static readonly HttpClient HttpClient = new();
15+
16+
// Fetches all entries from an OEIS b-file (plain text format: "n value" per line).
17+
// Returns a dictionary mapping index -> value as BigInteger.
18+
// The b-file URL format is: https://oeis.org/AXXXXXX/b000XXX.txt
19+
private static Dictionary<ulong, BigInteger> FetchOeisSequence(string bFileUrl)
20+
{
21+
var result = new Dictionary<ulong, BigInteger>();
22+
string content = HttpClient.GetStringAsync(bFileUrl).GetAwaiter().GetResult();
23+
foreach (var line in content.Split('\n'))
24+
{
25+
var trimmed = line.Trim();
26+
if (trimmed.StartsWith("#") || trimmed.Length == 0)
27+
{
28+
continue;
29+
}
30+
var parts = Regex.Split(trimmed, @"\s+");
31+
if (parts.Length >= 2 && ulong.TryParse(parts[0], out var index) && BigInteger.TryParse(parts[1], out var value))
32+
{
33+
result[index] = value;
34+
}
35+
}
36+
return result;
37+
}
38+
39+
// Lazily-fetched OEIS sequences, cached for the lifetime of the test run.
40+
private static Dictionary<ulong, BigInteger>? _oeisFactorials;
41+
private static Dictionary<ulong, BigInteger> OeisFactorials =>
42+
_oeisFactorials ??= FetchOeisSequence("https://oeis.org/A000142/b000142.txt");
43+
44+
private static Dictionary<ulong, BigInteger>? _oeisCatalans;
45+
private static Dictionary<ulong, BigInteger> OeisCatalans =>
46+
_oeisCatalans ??= FetchOeisSequence("https://oeis.org/A000108/b000108.txt");
1147

1248
// Computes factorial of n using BigInteger so it never overflows.
1349
// Returns null if computation exceeds the time limit.
@@ -159,40 +195,52 @@ public static void MaximumConstantsTest()
159195
public static void PrecalculatedFactorialsMatchComputedValues()
160196
{
161197
// Verify that every precalculated factorial constant in Math._factorials is actually
162-
// a correct factorial value, computed independently using BigInteger arithmetic.
163-
// Only computes values that finish within 10 seconds; larger values would need
164-
// verification via an external trusted resource (e.g. OEIS A000142: https://oeis.org/A000142).
198+
// a correct factorial value. For values that can be computed locally within 10 seconds,
199+
// an independent BigInteger computation is used. For values that take longer, the
200+
// expected value is fetched from OEIS A000142 (https://oeis.org/A000142) via HTTP.
165201
for (ulong n = 0; n <= Math.MaximumFactorialNumber; n++)
166202
{
167203
var computed = ComputeFactorialWithTimeLimit(n);
204+
BigInteger expected;
168205
if (computed is null)
169206
{
170-
// Computation exceeded 10 seconds — skip and rely on external verification.
171-
continue;
207+
// Computation exceeded 10 seconds — verify against OEIS A000142.
208+
Assert.True(OeisFactorials.TryGetValue(n, out expected),
209+
$"OEIS A000142 did not contain a value for n={n}");
210+
}
211+
else
212+
{
213+
expected = computed.Value;
172214
}
173215
var precalculated = Math.Factorial<ulong>(n);
174-
Assert.Equal((ulong)computed, precalculated);
216+
Assert.Equal((ulong)expected, precalculated);
175217
}
176218
}
177219

178220
[Fact]
179221
public static void PrecalculatedCatalansMatchComputedFactorials()
180222
{
181223
// Verify that every precalculated Catalan constant in Math._catalans is actually
182-
// a correct Catalan number, computed from scratch using the formula:
183-
// C(n) = (2n)! / ((n+1)! * n!)
184-
// Only computes values that finish within 10 seconds; larger values would need
185-
// verification via an external trusted resource (e.g. OEIS A000108: https://oeis.org/A000108).
224+
// a correct Catalan number. For values that can be computed locally within 10 seconds
225+
// using the formula C(n) = (2n)! / ((n+1)! * n!), an independent BigInteger computation
226+
// is used. For values that take longer, the expected value is fetched from OEIS A000108
227+
// (https://oeis.org/A000108) via HTTP.
186228
for (ulong n = 0; n <= Math.MaximumCatalanIndex; n++)
187229
{
188230
var computed = ComputeCatalanWithTimeLimit(n);
231+
BigInteger expected;
189232
if (computed is null)
190233
{
191-
// Computation exceeded 10 seconds — skip and rely on external verification.
192-
continue;
234+
// Computation exceeded 10 seconds — verify against OEIS A000108.
235+
Assert.True(OeisCatalans.TryGetValue(n, out expected),
236+
$"OEIS A000108 did not contain a value for n={n}");
237+
}
238+
else
239+
{
240+
expected = computed.Value;
193241
}
194242
var precalculated = Math.Catalan<ulong>(n);
195-
Assert.Equal((ulong)computed, precalculated);
243+
Assert.Equal((ulong)expected, precalculated);
196244
}
197245
}
198246
}

0 commit comments

Comments
 (0)