koga1020's solution

to Secret Handshake in the Elixir Track

Published at Jun 09 2019 · 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

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

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
defmodule SecretHandshake do
@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
"""

use Bitwise

@spec commands(code :: integer) :: list(String.t())
def commands(code) do
[]
|> handshake(code &&& 0b00001)
|> handshake(code &&& 0b00010)
|> handshake(code &&& 0b00100)
|> handshake(code &&& 0b01000)
|> handshake(code &&& 0b10000)
end

def handshake(list, 0b00001), do: list ++ ["wink"]
def handshake(list, 0b00010), do: list ++ ["double blink"]
def handshake(list, 0b00100), do: list ++ ["close your eyes"]
def handshake(list, 0b01000), do: list ++ ["jump"]
def handshake(list, 0b10000), do: Enum.reverse(list)
def handshake(list, _), do: list
end