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

# jaeyson's solution

## to Secret Handshake in the Elixir Track

Published at Apr 12 2020 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

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.

use Bitwise (or div/rem)

If you use Bitwise, an easy way to see if a particular bit is set is to compare the binary AND (`&&&`) of a set of bits with the particular bit pattern you want to check, and determine if the result is the same as the pattern you're checking.

Example:

Flags: 0b11011 Check: 0b11010

Flags &&& Check: 0b11010 (All checked bits are set)

Another:

Flags: 0b11011 Check: 0b10110

Flags &&& Check: 0b10010 (Third bit not set)

## Running tests

Execute the tests with:

``````\$ elixir secret_handshake_test.exs
``````

### Pending tests

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

Once you get a test passing, you can unskip the next one by commenting out the relevant `@tag :pending` with a `#` symbol.

For example:

``````# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
``````

Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the test suite.

``````# ExUnit.configure exclude: :pending, trace: true
``````

For more detailed information about the Elixir track, please see the help page.

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

``````if !System.get_env("EXERCISM_TEST_EXAMPLES") do
end

ExUnit.start()
ExUnit.configure(trace: true, exclude: :pending)

defmodule SecretHandshakeTest do
use ExUnit.Case

describe "Create a handshake for a number" do
# @tag :pending
test "wink for 1" do
assert SecretHandshake.commands(1) == ["wink"]
end

@tag :pending
test "double blink for 10" do
end

@tag :pending
test "close your eyes for 100" do
assert SecretHandshake.commands(4) == ["close your eyes"]
end

@tag :pending
test "jump for 1000" do
assert SecretHandshake.commands(8) == ["jump"]
end

@tag :pending
test "combine two actions" do
assert SecretHandshake.commands(3) == ["wink", "double blink"]
end

@tag :pending
test "reverse two actions" do
assert SecretHandshake.commands(19) == ["double blink", "wink"]
end

@tag :pending
test "reversing one action gives the same action" do
assert SecretHandshake.commands(24) == ["jump"]
end

@tag :pending
test "reversing no actions still gives no actions" do
assert SecretHandshake.commands(16) == []
end

@tag :pending
test "all possible actions" do
end

@tag :pending
test "reverse all possible actions" do
end

@tag :pending
test "do nothing for zero" do
assert SecretHandshake.commands(0) == []
end

@tag :pending
test "do nothing if lower 5 bits not set" do
assert SecretHandshake.commands(32) == []
end
end
end``````

### secret_handshake.exs

``````defmodule SecretHandshake do
use Bitwise
@doc """
Determine the actions of a secret handshake based on the binary
representation of the given `code`.

If the following bits are set, include the corresponding action in your list
of commands, in order from lowest to highest.

1 = wink
1000 = jump

10000 = Reverse the order of the operations in the secret handshake
"""
@spec commands(code :: integer) :: list(String.t())
def commands(code) when code > 16, do: Enum.map(rem(code,16)..1, & gen(&1 &&& code)) |> Enum.filter(& &1!=nil) |> Enum.uniq
def commands(code), do: Enum.map(1..rem(code,16), & gen(&1 &&& code)) |> Enum.filter(& &1!=nil) |> Enum.uniq
def gen(1), do: "wink"
def gen(4), do: "close your eyes"
def gen(8), do: "jump"
def gen(_n), do: nil
end``````

### secret_handshake_test.exs

``````if !System.get_env("EXERCISM_TEST_EXAMPLES") do
end

ExUnit.start()
ExUnit.configure(trace: true, exclude: :pending)

defmodule SecretHandshakeTest do
use ExUnit.Case

describe "Create a handshake for a number" do
# @tag :pending
test "wink for 1" do
assert SecretHandshake.commands(1) == ["wink"]
end

@tag :pending
test "double blink for 10" do
end

@tag :pending
test "close your eyes for 100" do
assert SecretHandshake.commands(4) == ["close your eyes"]
end

@tag :pending
test "jump for 1000" do
assert SecretHandshake.commands(8) == ["jump"]
end

@tag :pending
test "combine two actions" do
assert SecretHandshake.commands(3) == ["wink", "double blink"]
end

@tag :pending
test "reverse two actions" do
assert SecretHandshake.commands(19) == ["double blink", "wink"]
end

@tag :pending
test "reversing one action gives the same action" do
assert SecretHandshake.commands(24) == ["jump"]
end

@tag :pending
test "reversing no actions still gives no actions" do
assert SecretHandshake.commands(16) == []
end

@tag :pending
test "all possible actions" do
end

@tag :pending
test "reverse all possible actions" do
end

@tag :pending
test "do nothing for zero" do
assert SecretHandshake.commands(0) == []
end

@tag :pending
test "do nothing if lower 5 bits not set" do
assert SecretHandshake.commands(32) == []
end
end
end``````