# Neftali's solution

## to Secret Handshake in the Delphi Pascal Track

Published at Jan 23 2020 · 0 comments
Instructions
Test suite
Solution

There are 10 types of people in the world: Those who understand binary, and those who don't.

You and your fellow cohort of those in the "know" when it comes to binary decide to come up with a secret "handshake".

``````1 = wink
1000 = jump

10000 = Reverse the order of the operations in the secret handshake.
``````

Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.

Here's a couple of examples:

Given the input 3, the function would return the array ["wink", "double blink"] because 3 is 11 in binary.

Given the input 19, the function would return the array ["double blink", "wink"] because 19 is 10011 in binary. Notice that the addition of 16 (10000 in binary) has caused the array to be reversed.

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

Bert, in Mary Poppins http://www.imdb.com/title/tt0058331/quotes/qt0437047

## Submitting Incomplete Solutions

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

### uSecretHandshakeTests.pas

``````unit uSecretHandshakeTests;

interface
uses
DUnitX.TestFramework;

const
CanonicalVersion = '1.2.0.1';

type
[TestFixture]
SecretHandshakeTest = class(TObject)
private
procedure CompareArrays(aExpected, aActual: TArray<string>);
public
[Test]
//    [Ignore('Comment the "[Ignore]" statement to run the test')]
procedure wink_for_1;

[Test]
[Ignore]

[Test]
[Ignore]
procedure close_your_eyes_for_100;

[Test]
[Ignore]
procedure jump_for_1000;

[Test]
[Ignore]
procedure combine_two_actions;

[Test]
[Ignore]
procedure reverse_two_actions;

[Test]
[Ignore]
procedure reversing_one_action_gives_the_same_action;

[Test]
[Ignore]
procedure reversing_no_actions_still_gives_no_actions;

[Test]
[Ignore]
procedure all_possible_actions;

[Test]
[Ignore]
procedure reverse_all_possible_actions;

[Test]
[Ignore]
procedure do_nothing_for_zero;
end;

implementation
uses uSecretHandshake;

{ SecretHandshakeTest }

procedure SecretHandshakeTest.all_possible_actions;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 4);
Expected[0] := 'wink';
Expected[3] := 'jump';

Actual := TSecretHandshake.commands(15);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.close_your_eyes_for_100;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 1);

Actual := TSecretHandshake.commands(4);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.combine_two_actions;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 2);
Expected[0] := 'wink';

Actual := TSecretHandshake.commands(3);

CompareArrays(Expected, Actual);
end;

var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 1);

Actual := TSecretHandshake.commands(2);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.do_nothing_for_zero;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 0);

Actual := TSecretHandshake.commands(0);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.jump_for_1000;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 1);
Expected[0] := 'jump';

Actual := TSecretHandshake.commands(8);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.reverse_all_possible_actions;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 4);
Expected[0] := 'jump';
Expected[3] := 'wink';

Actual := TSecretHandshake.commands(31);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.reverse_two_actions;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 2);
Expected[1] := 'wink';

Actual := TSecretHandshake.commands(19);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.reversing_no_actions_still_gives_no_actions;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 0);

Actual := TSecretHandshake.commands(16);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.reversing_one_action_gives_the_same_action;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 1);
Expected[0] := 'jump';

Actual := TSecretHandshake.commands(24);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.wink_for_1;
var Expected,
Actual: TArray<string>;
begin
SetLength(Expected, 1);
Expected[0] := 'wink';

Actual := TSecretHandshake.commands(1);

CompareArrays(Expected, Actual);
end;

procedure SecretHandshakeTest.CompareArrays(aExpected, aActual: TArray<string>);
var i: integer;
begin
Assert.AreEqual(length(aExpected), length(aActual));
for i := Low(aExpected) to High(aExpected) do
Assert.AreEqual(aExpected[i], aActual[i]);
end;

initialization
TDUnitX.RegisterTestFixture(SecretHandshakeTest);
end.``````
``````unit uSecretHandshake;

interface

uses
System.Generics.Collections;

type
TSecretHandshake = class
private
class function InitializeHandShakeValues:TDictionary<Integer, string>;
class function IntToBin(ANumber:integer): string;
public
class function commands(const ANumber:integer):TArray<string>;
end;

implementation

uses
System.Sysutils, Data.FmtBcd;

{ TSecretHandshake }

class function TSecretHandshake.IntToBin(ANumber:integer): string;
begin
Result := '';
while (ANumber > 0) do begin
Result := Integer(Odd(ANumber)).ToString + Result;
ANumber := ANumber DIV 2;
end;
end;

class function TSecretHandshake.InitializeHandShakeValues:TDictionary<Integer, string>;
begin
Result := TDictionary<Integer, string>.Create(5);
end;

class function TSecretHandshake.commands(const ANumber: integer): TArray<string>;
var
i:integer;
sbin:string;
l:TList<string>;
HandshakeValues:TDictionary<Integer, string>;
begin
l := TList<string>.Create;      // List for result
HandshakeValues := TSecretHandshake.InitializeHandShakeValues;  // Dictionary

try
sbin := TSecretHandshake.IntToBin(ANumber);  // convert to binary
for i := High(sbin) downto Low(sbin) do
if sbin[i] = '1' then
// Must reverse ?
if (i = 1) and (Length(sbin) = (HandshakeValues.Count)) then
l.Reverse
else
// convert result
Result := l.ToArray;
finally
FreeAndNil(HandshakeValues);
FreeAndNil(l);
end;
end;

end.``````