ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# Neftali's solution

## to Matrix in the Delphi Pascal Track

Published at Feb 05 2021 · 0 comments
Instructions
Test suite
Solution

Given a string representing a matrix of numbers, return the rows and columns of that matrix.

So given a string with embedded newlines like:

``````9 8 7
5 3 2
6 6 7
``````

representing this matrix:

``````    1  2  3
|---------
1 | 9  8  7
2 | 5  3  2
3 | 6  6  7
``````

your code should be able to spit out:

• A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows,
• A list of the columns, reading each column top-to-bottom while moving from left-to-right.

The rows for our example matrix:

• 9, 8, 7
• 5, 3, 2
• 6, 6, 7

And its columns:

• 9, 5, 6
• 8, 3, 6
• 7, 2, 7

## Testing

In order to run the tests for this track, you will need to install DUnitX. Please see the installation instructions for more information.

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 support room on 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/<exerciseName>` directory.

For example, if you're submitting `ubob.pas` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/delphi/bob/ubob.pas`.

## Source

Warmup to the `saddle-points` warmup. http://jumpstartlab.com

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you may request help from a mentor.

### uMatrixTests.pas

``````unit uMatrixTests;

interface

uses
DUnitX.TestFramework, System.Generics.Collections;

const
CanonicalVersion = '1.1.0.1';

type

[TestFixture]
TMatrixTest = class(TObject)
private
ExpectedRow : TList<integer>;
procedure CompareArrays(Array1, Array2: TArray<integer>);
public
[Setup]
procedure Setup;

[TearDown]
procedure TearDown;

[Test]
//    [Ignore('Comment the "[Ignore]" statement to run the test')]
procedure extract_row_from_one_number_matrix;

[Test]
[Ignore]
procedure can_extract_row;

[Test]
[Ignore]
procedure extract_row_where_numbers_have_different_widths;

[Test]
[Ignore]
procedure can_extract_row_from_non_square_matrix;

[Test]
[Ignore]
procedure extract_column_from_one_number_matrix;

[Test]
[Ignore]
procedure can_extract_column;

[Test]
[Ignore]
procedure can_extract_column_from_non_square_matrix;

[Test]
[Ignore]
procedure extract_column_where_numbers_have_different_widths;
end;

implementation
uses uMatrix;

procedure TMatrixTest.can_extract_column;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1 2 3\n4 5 6\n7 8 9');
Actual := CUT.column(3);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.can_extract_column_from_non_square_matrix;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1 2 3\n4 5 6\n7 8 9\n8 7 6');
Actual := CUT.column(3);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.can_extract_row;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1 2\n3 4');
Actual := CUT.Row(2);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.can_extract_row_from_non_square_matrix;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1 2 3\n4 5 6\n7 8 9\n8 7 6');
Actual := CUT.Row(3);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.extract_column_from_one_number_matrix;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1');
Actual := CUT.column(1);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.extract_column_where_numbers_have_different_widths;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('89 1903 3\n18 3 1\n9 4 800');
Actual := CUT.column(2);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.extract_row_from_one_number_matrix;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1');
Actual := CUT.Row(1);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.extract_row_where_numbers_have_different_widths;
var
CUT: TMatrix;
Expected, Actual : TArray<integer>;
i: Integer;
begin
Expected := ExpectedRow.ToArray;
CUT := TMatrix.Create('1 2\n10 20');
Actual := CUT.Row(2);
CompareArrays(Expected, Actual);
end;

procedure TMatrixTest.CompareArrays(Array1, Array2: TArray<integer>);
var
i: integer;
begin
Assert.AreEqual(Length(Array1), Length(Array2));
for i := Low(Array1) to High(Array1) do
Assert.AreEqual(Array1[i], Array2[i]);
end;

procedure TMatrixTest.Setup;
begin
ExpectedRow := TList<integer>.Create;
end;

procedure TMatrixTest.TearDown;
begin
ExpectedRow.DisposeOf;
end;

initialization
TDUnitX.RegisterTestFixture(TMatrixTest);
end.``````
``````unit uMatrix;

interface

type
TRow = string;
TColumn = TRow;
TRowColumn = TArray<integer>;

TMatrix = class
private
Rows:TArray<TRowColumn>;
// Extract items from the Matrix (as string)
function ParseItems(AMatrix: string):TArray<string>;
// Parse row as strign as an Array
function ParseRow(const ARow:string):TRowColumn;
public
constructor Create(const AMatrix: string);
function column(const AIndex:integer):TRowColumn;
function Row(const AIndex:integer):TRowColumn;
end;

implementation

uses
System.SysUtils, System.Classes;

function TMatrix.column(const AIndex: integer): TRowColumn;
var
i, l :integer;
begin
Result := [];
l := Length(Rows);
SetLength(Result, l);
for i := 0 to (l - 1) do
Result[i] := Rows[i][AIndex-1];
end;

function TMatrix.Row(const AIndex: integer): TRowColumn;
begin
Result := Rows[AIndex-1];
end;

constructor TMatrix.Create(const AMatrix: string);
var
r:TArray<string>;
i:integer;
begin
i := 0;
r := ParseItems(AMatrix);
for i := Low(r) to High(r) do begin
SetLength(Rows, i+1);
Rows[i] := ParseRow(r[i]);
end;
end;

function TMatrix.ParseItems(AMatrix: string): TArray<string>;
var
pos, i:integer;
begin
i := 0;
// Extract Rows from Matrix as Array
pos := AnsiPos('\n', AMatrix);
while (pos <> 0) do begin
SetLength(Result, i+1);
Result[i] := Copy(AMatrix, 1, pos-1);
AMatrix := Copy(AMatrix, pos+2, Length(AMatrix));
pos := AnsiPos('\n', AMatrix);
Inc(i);
end;
// The Last element
if (pos = 0) and (Trim(AMatrix)<>String.Empty) then begin
SetLength(Result, i+1);
Result[i] := AMatrix;
end;
end;

function TMatrix.ParseRow(const ARow: string): TRowColumn;
var
TS:TStrings;
i, l:integer;
begin
l := 0;
TS := TStringList.Create;
try
TS.DelimitedText := ARow;
for i := 0 to (TS.Count - 1) do begin
if (StrToIntDef(TS[i], -1) <> -1) then begin
Inc(l);
SetLength(Result , l);
Result[l - 1] := StrToInt(TS[i]);
end;
end;
finally
FreeAndNil(TS);
end;
end;

end.``````