🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of Neftali

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.

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 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
  ExpectedRow.AddRange([3, 6, 9]);
  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
  ExpectedRow.AddRange([3, 6, 9, 6]);
  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
  ExpectedRow.AddRange([3, 4]);
  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
  ExpectedRow.AddRange([7, 8, 9]);
  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
  ExpectedRow.AddRange([1]);
  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
  ExpectedRow.AddRange([1903, 3, 4]);
  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
  ExpectedRow.AddRange([1]);
  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
  ExpectedRow.AddRange([10, 20]);
  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.

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?