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

# makafakachka's solution

## to All Your Base in the Delphi Pascal Track

Published at Apr 25 2019 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

Convert a number, represented as a sequence of digits in one base, to any other base.

Implement general base conversion. Given a number in base a, represented as a sequence of digits, convert it to base b.

## Note

• Try to implement the conversion yourself. Do not use something else to perform the conversion for you.

In positional notation, a number in base b can be understood as a linear combination of powers of b.

The number 42, in base 10, means:

(4 * 10^1) + (2 * 10^0)

The number 101010, in base 2, means:

(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)

The number 1120, in base 3, means:

(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0)

I think you got the idea!

Yes. Those three numbers above are exactly the same. Congratulations!

## 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`.

## Submitting Incomplete Solutions

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

### uAllYourBaseTest.pas

``````unit uAllYourBaseTest;

interface
uses
DUnitX.TestFramework, System.SysUtils;

const
CanonicalVersion = '2.3.0';

type
[TestFixture]
TAllYourBaseTest = class(TObject)
private
procedure CompareArrays(Array1, Array2: TArray<integer>);
public
[Test]
//    [Ignore('Comment the "[Ignore]" statement to run the test')]
procedure single_bit_one_to_decimal;

[Test]
[Ignore]
procedure binary_to_single_decimal;

[Test]
[Ignore]
procedure single_decimal_to_binary;

[Test]
[Ignore]
procedure binary_to_multiple_decimal;

[Test]
[Ignore]
procedure decimal_to_binary;

[Test]
[Ignore]

[Test]
[Ignore]

[Test]
[Ignore]
procedure integer_15_bit;

[Test]
[Ignore]
procedure empty_list;

[Test]
[Ignore]
procedure single_zero;

[Test]
[Ignore]
procedure multiple_zeros;

[Test]
[Ignore]

[Test]
[Ignore]
procedure input_base_is_one;

[Test]
[Ignore]
procedure input_base_is_zero;

[Test]
[Ignore]
procedure input_base_is_negative;

[Test]
[Ignore]
procedure negative_digit;

[Test]
[Ignore]
procedure invalid_positive_digit;

[Test]
[Ignore]
procedure output_base_is_one;

[Test]
[Ignore]
procedure output_base_is_zero;

[Test]
[Ignore]
procedure output_base_is_negative;

[Test]
[Ignore]
procedure both_bases_are_negative;
end;

implementation
uses uAllYourBase;

procedure TAllYourBaseTest.binary_to_multiple_decimal;
begin
CompareArrays([4, 2], TBase.Rebase(2, [1, 0, 1, 0, 1, 0], 10));
end;

procedure TAllYourBaseTest.binary_to_single_decimal;
begin
CompareArrays([5], TBase.Rebase(2, [1, 0, 1], 10));
end;

procedure TAllYourBaseTest.both_bases_are_negative;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(-2, [1], -7);
end, EArgumentOutOfRangeException, 'input base must be >= 2');
end;

procedure TAllYourBaseTest.CompareArrays(Array1, Array2: TArray<integer>);
var
i: integer;
begin
Assert.AreEqual(Length(Array1), Length(Array2), ' - Array lengths must be equal');
for i := Low(Array1) to High(Array1) do
Assert.AreEqual(Array1[i], Array2[i], format('Expecting element %d to = %d, Actual = %d',
[i, Array1[i], Array2[i]]));
end;

procedure TAllYourBaseTest.decimal_to_binary;
begin
CompareArrays([1, 0, 1, 0, 1, 0], TBase.Rebase(10, [4, 2], 2));
end;

procedure TAllYourBaseTest.empty_list;
begin
CompareArrays([0], TBase.Rebase(2, [], 10));
end;

begin
CompareArrays([1, 1, 2, 0], TBase.Rebase(16, [2, 10], 3));
end;

procedure TAllYourBaseTest.input_base_is_negative;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(-2, [1], 10);
end, EArgumentOutOfRangeException, 'input base must be >= 2');
end;

procedure TAllYourBaseTest.input_base_is_one;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(1, [0], 10);
end, EArgumentOutOfRangeException, 'input base must be >= 2');
end;

procedure TAllYourBaseTest.input_base_is_zero;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(0, [0], 10);
end, EArgumentOutOfRangeException, 'input base must be >= 2');
end;

procedure TAllYourBaseTest.integer_15_bit;
begin
CompareArrays([6, 10, 45], TBase.Rebase(97, [3, 46, 60], 73));
end;

procedure TAllYourBaseTest.invalid_positive_digit;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(2, [1, 2, 1, 0, 1, 0], 10);
end, EArgumentOutOfRangeException, 'all digits must satisfy 0 <= d < input base');
end;

begin
CompareArrays([4, 2], TBase.Rebase(7, [0, 6, 0], 10));
end;

procedure TAllYourBaseTest.multiple_zeros;
begin
CompareArrays([0], TBase.Rebase(10, [0, 0, 0], 2));
end;

procedure TAllYourBaseTest.negative_digit;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(2, [1, -1, 1, 0, 1, 0], 10);
end, EArgumentOutOfRangeException, 'all digits must satisfy 0 <= d < input base');
end;

procedure TAllYourBaseTest.output_base_is_negative;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(2, [1], -7);
end, EArgumentOutOfRangeException, 'output base must be >= 2');
end;

procedure TAllYourBaseTest.output_base_is_one;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(2, [1, 0, 1, 0, 1, 0], 1);
end, EArgumentOutOfRangeException, 'output base must be >= 2');
end;

procedure TAllYourBaseTest.output_base_is_zero;
begin
Assert.WillRaise(procedure
begin
TBase.Rebase(10, [7], 0);
end, EArgumentOutOfRangeException, 'output base must be >= 2');
end;

procedure TAllYourBaseTest.single_bit_one_to_decimal;
begin
CompareArrays([1], TBase.Rebase(2, [1], 10));
end;

procedure TAllYourBaseTest.single_decimal_to_binary;
begin
CompareArrays([1, 0, 1], TBase.Rebase(10, [5], 2));
end;

procedure TAllYourBaseTest.single_zero;
begin
CompareArrays([0], TBase.Rebase(10, [0], 2));
end;

begin
CompareArrays([2, 10], TBase.Rebase(3, [1, 1, 2, 0], 16));
end;

initialization
TDUnitX.RegisterTestFixture(TAllYourBaseTest);
end.``````
``````unit uAllYourBase;

interface

type
TBase = class
class function Rebase(oldBase: Integer;
digits: TArray<Integer>;
newBase: Integer): TArray<Integer>;
end;

implementation

uses
System.Sysutils,
System.Math;

function BaseToDec(base: Integer; digits: TArray<Integer>): Integer;
begin
Result := 0;
for var i := High(digits) downto Low(digits) do
begin
Result := Result + digits[i] * trunc(power(base, High(digits) - i));
end;
end;

function DecToBase(base, number: Integer): TArray<Integer>;
begin
repeat
Result := [number mod base] + Result;
number := number div base;
until number = 0;
end;

{ TBase }

class function TBase.Rebase(oldBase: Integer; digits: TArray<Integer>;
newBase: Integer): TArray<Integer>;

procedure CheckBases;
begin
if oldBase < 2 then
raise EArgumentOutOfRangeException.Create('input base must be >= 2');
if newBase < 2 then
raise EArgumentOutOfRangeException.Create('output base must be >= 2');
end;

procedure CheckDigits;
begin
for var digit in digits do
if (digit >= oldBase) or (digit < 0) then
raise EArgumentOutOfRangeException.Create(
'all digits must satisfy 0 <= d < input base');
end;

begin
CheckBases;
CheckDigits;
Result := DecToBase(newBase, BaseToDec(oldBase, digits));
end;

end.``````