Added binomial coefficient calculation
This commit is contained in:
parent
1d399cc5b6
commit
be0357befd
|
@ -161,6 +161,10 @@
|
|||
<Filename Value="UMultiIndexEnumerator.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="UBinomialCoefficients.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
Solutions to the Advent Of Code.
|
||||
Copyright (C) 2024 Stefan Müller
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
unit UBinomialCoefficients;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Generics.Collections;
|
||||
|
||||
type
|
||||
TCardinalArray = array of Cardinal;
|
||||
TCardinalArrays = specialize TList<TCardinalArray>;
|
||||
|
||||
{ TBinomialCoefficientCache }
|
||||
|
||||
TBinomialCoefficientCache = class
|
||||
private
|
||||
FCache: TCardinalArrays;
|
||||
procedure AddRow;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function Get(const AN, AK: Cardinal): Cardinal;
|
||||
function GetCachedRowsCount: Cardinal;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TBinomialCoefficientCache }
|
||||
|
||||
procedure TBinomialCoefficientCache.AddRow;
|
||||
var
|
||||
row: TCardinalArray;
|
||||
i: Cardinal;
|
||||
begin
|
||||
SetLength(row, FCache.Count + 1);
|
||||
row[0] := 1;
|
||||
if FCache.Count > 0 then
|
||||
begin
|
||||
row[FCache.Count] := 1;
|
||||
for i := 1 to FCache.Count - 1 do
|
||||
row[i] := FCache.Last[i - 1] + FCache.Last[i];
|
||||
end;
|
||||
FCache.Add(row);
|
||||
end;
|
||||
|
||||
constructor TBinomialCoefficientCache.Create;
|
||||
begin
|
||||
FCache := TCardinalArrays.Create;
|
||||
end;
|
||||
|
||||
destructor TBinomialCoefficientCache.Destroy;
|
||||
begin
|
||||
FCache.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TBinomialCoefficientCache.Get(const AN, AK: Cardinal): Cardinal;
|
||||
var
|
||||
i: Cardinal;
|
||||
begin
|
||||
if AN < AK then
|
||||
raise ERangeError.Create('Cannot calculate binomial coefficient "n choose k" with k larger than n.');
|
||||
|
||||
for i := FCache.Count to AN do
|
||||
AddRow;
|
||||
Result := FCache[AN][AK];
|
||||
end;
|
||||
|
||||
function TBinomialCoefficientCache.GetCachedRowsCount: Cardinal;
|
||||
begin
|
||||
Result := FCache.Count;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -152,6 +152,10 @@
|
|||
<Filename Value="USnowverloadTestCases.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="UBinomialCoefficientsTestCases.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -10,7 +10,7 @@ uses
|
|||
UFloorWillBeLavaTestCases, UClumsyCrucibleTestCases, ULavaductLagoonTestCases, UAplentyTestCases,
|
||||
UPulsePropagationTestCases, UStepCounterTestCases, USandSlabsTestCases, ULongWalkTestCases,
|
||||
UNeverTellMeTheOddsTestCases, USnowverloadTestCases, UBigIntTestCases, UPolynomialTestCases,
|
||||
UPolynomialRootsTestCases;
|
||||
UPolynomialRootsTestCases, UBinomialCoefficientsTestCases;
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
{
|
||||
Solutions to the Advent Of Code.
|
||||
Copyright (C) 2024 Stefan Müller
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
unit UBinomialCoefficientsTestCases;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fpcunit, testregistry, UBinomialCoefficients;
|
||||
|
||||
type
|
||||
|
||||
{ TBinomialCoefficientsTestCase }
|
||||
|
||||
TBinomialCoefficientsTestCase = class(TTestCase)
|
||||
private
|
||||
FBinomialCoefficientCache: TBinomialCoefficientCache;
|
||||
procedure RunRangeError;
|
||||
procedure AssertEqualsCalculation(const AN, AK, AExpected: Cardinal);
|
||||
procedure AssertEqualsCachedRowsCount(const AExpected: Cardinal);
|
||||
protected
|
||||
procedure SetUp; override;
|
||||
procedure TearDown; override;
|
||||
published
|
||||
procedure TestZeroChooseZero;
|
||||
procedure TestNChooseZero;
|
||||
procedure TestNChooseN;
|
||||
procedure TestNChooseK;
|
||||
procedure TestCombined;
|
||||
procedure TestFullRow;
|
||||
procedure TestRangeError;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TBinomialCoefficientsTestCase }
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.RunRangeError;
|
||||
begin
|
||||
FBinomialCoefficientCache.Get(1, 5);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.AssertEqualsCalculation(const AN, AK, AExpected: Cardinal);
|
||||
begin
|
||||
AssertEquals('Unexpected calculation result', AExpected, FBinomialCoefficientCache.Get(AN, AK));
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.AssertEqualsCachedRowsCount(const AExpected: Cardinal);
|
||||
begin
|
||||
AssertEquals('Unexpected cached rows count', AExpected, FBinomialCoefficientCache.GetCachedRowsCount);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.SetUp;
|
||||
begin
|
||||
FBinomialCoefficientCache := TBinomialCoefficientCache.Create;
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TearDown;
|
||||
begin
|
||||
FBinomialCoefficientCache.Free;
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestZeroChooseZero;
|
||||
begin
|
||||
AssertEqualsCalculation(0, 0, 1);
|
||||
AssertEqualsCachedRowsCount(1);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestNChooseZero;
|
||||
begin
|
||||
AssertEqualsCalculation(15, 0, 1);
|
||||
AssertEqualsCachedRowsCount(16);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestNChooseN;
|
||||
begin
|
||||
AssertEqualsCalculation(11, 11, 1);
|
||||
AssertEqualsCachedRowsCount(12);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestNChooseK;
|
||||
begin
|
||||
AssertEqualsCalculation(8, 3, 56);
|
||||
AssertEqualsCachedRowsCount(9);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestCombined;
|
||||
begin
|
||||
AssertEqualsCalculation(5, 1, 5);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
AssertEqualsCalculation(8, 4, 70);
|
||||
AssertEqualsCachedRowsCount(9);
|
||||
AssertEqualsCalculation(3, 1, 3);
|
||||
AssertEqualsCachedRowsCount(9);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestFullRow;
|
||||
begin
|
||||
AssertEqualsCalculation(5, 0, 1);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
AssertEqualsCalculation(5, 1, 5);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
AssertEqualsCalculation(5, 2, 10);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
AssertEqualsCalculation(5, 3, 10);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
AssertEqualsCalculation(5, 4, 5);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
AssertEqualsCalculation(5, 5, 1);
|
||||
AssertEqualsCachedRowsCount(6);
|
||||
end;
|
||||
|
||||
procedure TBinomialCoefficientsTestCase.TestRangeError;
|
||||
begin
|
||||
AssertException(ERangeError, @RunRangeError);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
RegisterTest('Helper', TBinomialCoefficientsTestCase);
|
||||
end.
|
||||
|
Loading…
Reference in New Issue