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

# Greycoat21's solution

## to Matrix in the Delphi Pascal Track

Published at Nov 05 2019 · 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
TValue = Integer;
TVector = TArray<TValue>;
TVectors = TArray<TVector>; // A Matrix.

TMatrix = class
private
Matrix: TVectors;
function StrToMatrix(MatrixStr: string): TVectors;
public
function Column(Index: Integer): TVector;
function Row(Index: Integer): TVector;
end;

implementation

uses
Character, SysUtils;

{ TMatrix }

function TMatrix.Column(Index: Integer): TVector;
var
i: Integer;
begin
Result := [];
for i := Low(Matrix) to High(Matrix) do begin
Result := Result + [Matrix[i][Index - 1]];
end;
end;

function TMatrix.Row(Index: Integer): TVector;
begin
Result := Matrix[Index - 1];
end;

function TMatrix.StrToMatrix(MatrixStr: string): TVectors;

function IsEscapeChar(Chr: Char): Boolean;
const
cEscapeCharacter = '\';
begin
Result := Chr = cEscapeCharacter;
end;

var
Chr: Char;
DigitStr: string;
Vector: TVector;
begin
Result := [];
Vector := [];
DigitStr := '';

for Chr in MatrixStr do begin

if Chr.IsDigit then begin
// Concatenate subsequent digits
DigitStr := DigitStr + Chr;

end else if Chr.IsWhiteSpace then begin
// Whitespace seperates values
Vector := Vector + [StrToInt(DigitStr)];
DigitStr := '';

end else if IsEscapeChar(Chr) then begin
// EscapeChar seperates intraline rows
Vector := Vector + [StrToInt(DigitStr)];
Result := Result + [Vector];
Vector := [];
DigitStr := '';
end;
end;

Vector := Vector + [StrToInt(DigitStr)];
Result := Result + [Vector];
end;

constructor TMatrix.Create(MatrixStr: string);
begin
Matrix := StrToMatrix(MatrixStr);
end;

end.``````