diff --git a/config.json b/config.json index f1637ad0..d61c6ab8 100644 --- a/config.json +++ b/config.json @@ -223,6 +223,18 @@ "sorting" ] }, + { + "slug": "pascals-triangle", + "uuid": "e5ec2940-ea15-475b-91b9-2caf85b73b35", + "core": false, + "unlocked_by": "grade-school", + "difficulty": 4, + "topics": [ + "arrays", + "control_flow_loops", + "math" + ] + }, { "slug": "collatz-conjecture", "uuid": "edfc2903-1165-4029-9901-0be72b32865f", diff --git a/exercises/pascals-triangle/PascalsTriangle.dpr b/exercises/pascals-triangle/PascalsTriangle.dpr new file mode 100644 index 00000000..f4cc7bed --- /dev/null +++ b/exercises/pascals-triangle/PascalsTriangle.dpr @@ -0,0 +1,60 @@ +program PascalsTriangle; + +{$IFNDEF TESTINSIGHT} +{$APPTYPE CONSOLE} +{$ENDIF}{$STRONGLINKTYPES ON} +uses + System.SysUtils, + {$IFDEF TESTINSIGHT} + TestInsight.DUnitX, + {$ENDIF } + DUnitX.Loggers.Console, + DUnitX.Loggers.Xml.NUnit, + DUnitX.TestFramework, + uPascalsTriangleTest in 'uPascalsTriangleTest.pas', + uPascalsTriangle in 'uPascalsTriangle.pas'; + +var + runner : ITestRunner; + results : IRunResults; + logger : ITestLogger; + nunitLogger : ITestLogger; +begin +{$IFDEF TESTINSIGHT} + TestInsight.DUnitX.RunRegisteredTests; + exit; +{$ENDIF} + try + //Check command line options, will exit if invalid + TDUnitX.CheckCommandLine; + //Create the test runner + runner := TDUnitX.CreateRunner; + //Tell the runner to use RTTI to find Fixtures + runner.UseRTTI := True; + //tell the runner how we will log things + //Log to the console window + logger := TDUnitXConsoleLogger.Create(true); + runner.AddLogger(logger); + //Generate an NUnit compatible XML File + nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile); + runner.AddLogger(nunitLogger); + runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests; + + //Run tests + results := runner.Execute; + if not results.AllPassed then + System.ExitCode := EXIT_ERRORS; + + {$IFNDEF CI} + //We don't want this happening when running under CI. + if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then + begin + System.Write('Done.. press key to quit.'); + System.Readln; + end; + {$ENDIF} + except + on E: Exception do + System.Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/exercises/pascals-triangle/README.md b/exercises/pascals-triangle/README.md new file mode 100644 index 00000000..efc66cf6 --- /dev/null +++ b/exercises/pascals-triangle/README.md @@ -0,0 +1,42 @@ +# Pascal's Triangle + +Compute Pascal's triangle up to a given number of rows. + +In Pascal's Triangle each number is computed by adding the numbers to +the right and left of the current position in the previous row. + +```text + 1 + 1 1 + 1 2 1 + 1 3 3 1 +1 4 6 4 1 +# ... etc +``` + +## Testing + +In order to run the tests for this track, you will need to install +DUnitX. Please see the [installation](http://www.exercism.io/languages/delphi/installation) instructions for more information. + +### Loading Exercises into Delphi + +If Delphi is properly installed, and `*.dpr` file types have been associated with Delphi, then double clicking the supplied `*.dpr` file will start Delphi and load the exercise/project. `control + F9` is the keyboard shortcut to compile the project or pressing `F9` will compile and run the project. + +Alternatively you may opt to start Delphi and load your project via. the `File` drop down menu. + +### When Questions Come Up +We monitor the [Pascal-Delphi](https://gitter.im/exercism/Pascal-Delphi) support room on [gitter.im](https://gitter.im) to help you with any questions that might arise. + +### Submitting Exercises + +Note that, when trying to submit an exercise, make sure the exercise file you're submitting is in the `exercism/delphi/` directory. + +For example, if you're submitting `ubob.pas` for the Bob exercise, the submit command would be something like `exercism submit /delphi/bob/ubob.pas`. + +## Source + +Pascal's Triangle at Wolfram Math World [http://mathworld.wolfram.com/PascalsTriangle.html](http://mathworld.wolfram.com/PascalsTriangle.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you may receive assistance from a mentor. diff --git a/exercises/pascals-triangle/uPascalsTriangleExample.pas b/exercises/pascals-triangle/uPascalsTriangleExample.pas new file mode 100644 index 00000000..efa70af7 --- /dev/null +++ b/exercises/pascals-triangle/uPascalsTriangleExample.pas @@ -0,0 +1,56 @@ +unit uPascalsTriangle; + +interface + +const + CanonicalVersion = '1.3.0'; + +type + PascalsTriangle = class + public + class function Calculate(ADepth : integer) : TArray>; + end; + +implementation + +uses System.SysUtils, System.Generics.Collections; + +{ PascalsTriangle } + +class function PascalsTriangle.Calculate(ADepth: integer): TArray>; + + function CalcNextRow(ADepth : integer) : TArray>; + var ALast : TArray; + ANew : TList; + i: integer; + begin + Result := []; + ANew := TList.Create; + while ADepth > 0 do + begin + ALast := []; + if Length(Result) > 0 then + ALast := Result[High(Result)]; + + for i := Low(ALast) to High(ALast) do + if i = Low(ALast) then + ANew.Add(1) + else + ANew.Add(ALast[i - 1] + ALast[i]); + ANew.Add(1); + + SetLength(Result, Length(Result) + 1); + Result[High(Result)] := ANew.ToArray; + dec(ADepth); + ANew.Clear; + end; + ANew.DisposeOf; + end; + +begin + if ADepth < 0 then + raise EArgumentOutOfRangeException.Create('Argument have to be positive'); + Result := CalcNextRow(ADepth); +end; + +end. diff --git a/exercises/pascals-triangle/uPascalsTriangleTest.pas b/exercises/pascals-triangle/uPascalsTriangleTest.pas new file mode 100644 index 00000000..d7c5f037 --- /dev/null +++ b/exercises/pascals-triangle/uPascalsTriangleTest.pas @@ -0,0 +1,168 @@ +unit uPascalsTriangleTest; + +interface +uses + DUnitX.TestFramework, uPascalsTriangle; + +const CanonicalVersion = '1.3.0'; + +type + TMatrix = TArray>; + + [TestFixture] + TPascalsTriangleTest = class(TObject) + private + procedure CompareIntMatrices(AExpected, AActual : TArray>); + + public + + [Test] +// [Ignore('Comment the "[Ignore]" statement to run the test')] + procedure zero_rows; + + [Test] + [Ignore] + procedure single_row; + + [Test] + [Ignore] + procedure two_rows; + + [Test] + [Ignore] + procedure three_rows; + + [Test] + [Ignore] + procedure four_rows; + + [Test] + [Ignore] + procedure five_rows; + + [Test] + [Ignore] + procedure six_rows; + + [Test] + [Ignore] + procedure ten_rows; + + [Test] + [Ignore] + procedure negative_rows; + end; + +implementation + +uses System.SysUtils; + +procedure TPascalsTriangleTest.CompareIntMatrices(AExpected, AActual: TArray>); +var i, j: integer; +begin + Assert.AreEqual(Length(AExpected), Length(AActual)); + for i := Low(AExpected) to High(AExpected) do + begin + Assert.AreEqual(Length(AExpected[i]), Length(AActual[i])); + for j := Low(AExpected[i]) to High(AExpected[i]) do + Assert.AreEqual(AExpected[i, j], AActual[i, j]); + end; +end; + +procedure TPascalsTriangleTest.zero_rows; +var Expected, Actual : TMatrix; +begin + Expected := []; + Actual := PascalsTriangle.Calculate(0); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.single_row; +var Expected, Actual : TMatrix; +begin + Expected := [[1]]; + Actual := PascalsTriangle.Calculate(1); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.two_rows; +var Expected, Actual : TMatrix; +begin + Expected := [[1], + [1, 1]]; + Actual := PascalsTriangle.Calculate(2); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.three_rows; +var Expected, Actual : TMatrix; +begin + Expected := [[1], + [1, 1], + [1, 2, 1]]; + Actual := PascalsTriangle.Calculate(3); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.four_rows; +var Expected, Actual : TMatrix; +begin + Expected := [[1], + [1, 1], + [1, 2, 1], + [1, 3, 3, 1]]; + Actual := PascalsTriangle.Calculate(4); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.five_rows; +var Expected, Actual : TMatrix; +begin + Expected := [[1], + [1, 1], + [1, 2, 1], + [1, 3, 3, 1], + [1, 4, 6, 4, 1]]; + Actual := PascalsTriangle.Calculate(5); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.six_rows; +var Expected, Actual : TMatrix; +begin + Expected := [[1], + [1, 1], + [1, 2, 1], + [1, 3, 3, 1], + [1, 4, 6, 4, 1], + [1, 5, 10, 10, 5, 1]]; + Actual := PascalsTriangle.Calculate(6); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.ten_rows; +var Expected, Actual : TMatrix; +begin + Expected := [[1], + [1, 1], + [1, 2, 1], + [1, 3, 3, 1], + [1, 4, 6, 4, 1], + [1, 5, 10, 10, 5, 1], + [1, 6, 15, 20 ,15, 6, 1], + [1, 7, 21, 35, 35, 21, 7, 1], + [1, 8, 28, 56, 70, 56, 28, 8, 1], + [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]]; + Actual := PascalsTriangle.Calculate(10); + CompareIntMatrices(Expected, Actual); +end; + +procedure TPascalsTriangleTest.negative_rows; +begin + Assert.WillRaise(procedure() begin PascalsTriangle.Calculate(-1) end, + EArgumentOutOfRangeException); +end; + +initialization + TDUnitX.RegisterTestFixture(TPascalsTriangleTest); +end.