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

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.

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
  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;
    constructor Create(MatrixStr: string); overload;
  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;

  // Add the final row
  Vector := Vector + [StrToInt(DigitStr)];
  Result := Result + [Vector];
end;

constructor TMatrix.Create(MatrixStr: string);
begin
  Matrix := StrToMatrix(MatrixStr);
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?