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

skryukov's solution

to Secret Handshake in the Crystal Track

Published at May 14 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
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

Follow the setup instructions for Crystal here:

http://exercism.io/languages/crystal

More help installing can be found here:

http://crystal-lang.org/docs/installation/index.html

Making the Test Suite Pass

Execute the tests with:

$ crystal spec

In each test suite all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by changing pending 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_spec.cr

require "spec"
require "../src/*"

describe "SecretHandshake" do
  it "wink for 1" do
    SecretHandshake.commands(1).should eq(["wink"])
  end

  pending "double blink for 10" do
    SecretHandshake.commands(2).should eq(["double blink"])
  end

  pending "close your eyes for 100" do
    SecretHandshake.commands(4).should eq(["close your eyes"])
  end

  pending "jump for 1000" do
    SecretHandshake.commands(8).should eq(["jump"])
  end

  pending "combine two actions" do
    SecretHandshake.commands(3).should eq(["wink", "double blink"])
  end

  pending "reverse two actions" do
    SecretHandshake.commands(19).should eq(["double blink", "wink"])
  end

  pending "reversing one action gives the same action" do
    SecretHandshake.commands(24).should eq(["jump"])
  end

  pending "reversing no actions still gives no actions" do
    SecretHandshake.commands(16).should eq([] of String)
  end

  pending "all possible actions" do
    SecretHandshake.commands(15).should eq(["wink", "double blink", "close your eyes", "jump"])
  end

  pending "reverse all possible actions" do
    SecretHandshake.commands(31).should eq(["jump", "close your eyes", "double blink", "wink"])
  end

  pending "do nothing for zero" do
    SecretHandshake.commands(0).should eq([] of String)
  end
end
module SecretHandshake
  COMMANDS = {
    0b0001 => "wink",
    0b0010 => "double blink",
    0b0100 => "close your eyes",
    0b1000 => "jump"
  }
  REVERSE_MASK = 0b10000

  def self.commands(n : UInt8)
    actions = COMMANDS.select { |mask, _| n & mask > 0 }
                      .values

    if n & REVERSE_MASK > 0
      actions.reverse
    else
      actions
    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?