Skip to content

Commit 073f0e6

Browse files
author
n.bitounis
committed
Changed implementation to use BigInteger in order to have accuracy when using large inputs.
1 parent 2c87e51 commit 073f0e6

File tree

2 files changed

+16
-20
lines changed

2 files changed

+16
-20
lines changed

Algorithms/Numeric/CatalanNumbers.cs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* Wikipedia: https://en.wikipedia.org/wiki/Catalan_number
55
*/
66

7-
using System;
87
using System.Diagnostics;
98
using System.Collections.Generic;
9+
using System.Numerics;
1010

1111
namespace Algorithms.Numeric
1212
{
@@ -16,23 +16,23 @@ public static class CatalanNumbers
1616
/// Internal cache.
1717
/// By default contains the first two catalan numbers for the ranks: 0, and 1.
1818
/// </summary>
19-
private static Dictionary<uint, ulong> _catalanNumbers = new Dictionary<uint, ulong>() { { 0, 1 }, { 1, 1 } };
19+
private static readonly Dictionary<uint, BigInteger> _catalanNumbers = new Dictionary<uint, BigInteger> { { 0, 1 }, { 1, 1 } };
2020

2121
/// <summary>
2222
/// Helper function.
2323
/// </summary>
24-
private static ulong _recursiveHelper(uint rank)
24+
private static BigInteger _recursiveHelper(uint rank)
2525
{
2626
if (_catalanNumbers.ContainsKey(rank))
2727
return _catalanNumbers[rank];
2828

29-
ulong number = 0;
30-
uint lastRank = rank - 1;
29+
BigInteger number = 0;
30+
var lastRank = rank - 1;
3131

3232
for (uint i = 0; i <= lastRank; ++i)
3333
{
34-
ulong firstPart = _recursiveHelper(i);
35-
ulong secondPart = _recursiveHelper(lastRank - i);
34+
var firstPart = _recursiveHelper(i);
35+
var secondPart = _recursiveHelper(lastRank - i);
3636

3737
if (!_catalanNumbers.ContainsKey(i)) _catalanNumbers.Add(i, firstPart);
3838
if (!_catalanNumbers.ContainsKey(lastRank - i)) _catalanNumbers.Add(lastRank - i, secondPart);
@@ -46,7 +46,7 @@ private static ulong _recursiveHelper(uint rank)
4646
/// <summary>
4747
/// Public API
4848
/// </summary>
49-
public static ulong GetNumber(uint rank)
49+
public static BigInteger GetNumber(uint rank)
5050
{
5151
// Assert the cache is not empty.
5252
Debug.Assert(_catalanNumbers.Count >= 2);
@@ -57,31 +57,26 @@ public static ulong GetNumber(uint rank)
5757
/// <summary>
5858
/// Calculate the number using the Binomial Coefficients algorithm
5959
/// </summary>
60-
public static ulong GetNumberByBinomialCoefficients(uint rank)
60+
public static BigInteger GetNumberByBinomialCoefficients(uint rank)
6161
{
62-
// Calculate value of 2nCn
63-
var catalanNumber = BinomialCoefficients.Calculate(2 * rank, rank);
64-
65-
// return 2nCn/(n+1)
66-
return Convert.ToUInt64(catalanNumber / (rank + 1));
62+
// Calculate by binomial coefficient.
63+
return BinomialCoefficients.Calculate(rank);
6764
}
6865

6966
/// <summary>
7067
/// Return the list of catalan numbers between two ranks, inclusive.
7168
/// </summary>
72-
public static List<ulong> GetRange(uint fromRank, uint toRank)
69+
public static List<BigInteger> GetRange(uint fromRank, uint toRank)
7370
{
74-
List<ulong> numbers = new List<ulong>();
71+
var numbers = new List<BigInteger>();
7572

7673
if (fromRank > toRank)
7774
return null;
7875

79-
for (uint i = fromRank; i <= toRank; ++i)
76+
for (var i = fromRank; i <= toRank; ++i)
8077
numbers.Add(GetNumber(i));
8178

8279
return numbers;
8380
}
84-
8581
}
86-
8782
}

UnitTest/AlgorithmsTests/CatalanNumbersTest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Numerics;
23
using Algorithms.Numeric;
34
using Xunit;
45

@@ -10,7 +11,7 @@ public class CatalanNumbersTest
1011
public static void DoTest()
1112
{
1213
var list = CatalanNumbers.GetRange(0, 100);
13-
var list2 = new List<ulong>();
14+
var list2 = new List<BigInteger>();
1415

1516
// TRY CALCULATING FROM Bin.Coeff.
1617
for (uint i = 0; i < list.Count; ++i)

0 commit comments

Comments
 (0)