Exercism v3 launches on Sept 1st 2021. Learn more! ๐Ÿš€๐Ÿš€๐Ÿš€
Avatar of rootulp

rootulp's solution

to Secret Handshake in the TypeScript Track

Published at Jun 05 2021 · 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
10 = double blink
100 = close your eyes
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.

Setup

Go through the setup instructions for TypeScript to install the necessary dependencies:

https://exercism.io/tracks/typescript/installation

Requirements

Install assignment dependencies:

$ yarn install

Making the test suite pass

Execute the tests with:

$ yarn test

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by changing xit to it.

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 can see how others have completed the exercise.

secret-handshake.test.ts

import HandShake from './secret-handshake'

describe('Create a handshake for a number', () => {
  it('wink for 1', () => {
    const handshake = new HandShake(1)
    const expected = ['wink']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('double blink for 10', () => {
    const handshake = new HandShake(2)
    const expected = ['double blink']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('close your eyes for 100', () => {
    const handshake = new HandShake(4)
    const expected = ['close your eyes']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('jump for 1000', () => {
    const handshake = new HandShake(8)
    const expected = ['jump']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('combine two actions', () => {
    const handshake = new HandShake(3)
    const expected = ['wink', 'double blink']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('reverse two actions', () => {
    const handshake = new HandShake(19)
    const expected = ['double blink', 'wink']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('reversing one action gives the same action', () => {
    const handshake = new HandShake(24)
    const expected = ['jump']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('reversing no actions still gives no actions', () => {
    const handshake = new HandShake(16)
    const expected: string[] = []
    expect(handshake.commands()).toEqual(expected)
  })

  xit('all possible actions', () => {
    const handshake = new HandShake(15)
    const expected = ['wink', 'double blink', 'close your eyes', 'jump']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('reverse all possible actions', () => {
    const handshake = new HandShake(31)
    const expected = ['jump', 'close your eyes', 'double blink', 'wink']
    expect(handshake.commands()).toEqual(expected)
  })

  xit('do nothing for zero', () => {
    const handshake = new HandShake(0)
    const expected: string[] = []
    expect(handshake.commands()).toEqual(expected)
  })
})
interface Event {
    binary: number;
    action: string;
}

export default class HandShake {

    private static REVERSE_EVENT: Event = { binary: 10000, action: '' }
    private static EVENTS: Event[] = [
        { binary: 1000, action: 'jump' },
        { binary: 100, action: 'close your eyes' },
        { binary: 10, action: 'double blink' },
        { binary: 1, action: 'wink' }
    ]

    constructor(private readonly number: number) {}

    public commands(): string[] {
        let result: string[] = []
        let binary = this.binary();
        let shouldReverse: boolean = false;

        if (binary >= HandShake.REVERSE_EVENT.binary) {
            shouldReverse = true;
            binary -= HandShake.REVERSE_EVENT.binary
        }

        HandShake.EVENTS.forEach(event => {
            if (binary >= event.binary) {
                binary -= event.binary
                result.unshift(event.action);
            }
        })

        if (shouldReverse) {
            return result.reverse();
        }
        return result;
    }

    private binary(): number {
        return parseInt(this.number.toString(2));
    }
}

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?