Introduction
You are starting a secret coding club with some friends and friends-of-friends.
Not everyone knows each other, so you and your friends have decided to create a secret handshake that you can use to recognize that someone is a member.
You don’t want anyone who isn’t in the know to be able to crack the code.
You’ve designed the code so that one person says a number between 1 and 31, and the other person turns it into a series of actions.
Instructions
Instructions
Your task is to convert a number between 1 and 31 to a sequence of actions in the secret handshake.
The sequence of actions is chosen by looking at the rightmost five digits of the number once it’s been converted to binary.
Start at the right-most digit and move left.
The actions for each number place are:
00001 = wink
00010 = double blink
00100 = close your eyes
01000 = jump
10000 = Reverse the order of the operations in the secret handshake.
Let’s use the number 9 as an example:
- 9 in binary is
1001.
- The digit that is farthest to the right is 1, so the first action is
wink.
- Going left, the next digit is 0, so there is no double-blink.
- Going left again, the next digit is 0, so you leave your eyes open.
- Going left again, the next digit is 1, so you jump.
That was the last digit, so the final code is:
wink, jump
Given the number 26, which is 11010 in binary, we get the following actions:
- double blink
- jump
- reverse actions
The secret handshake for 26 is therefore:
jump, double blink
If you aren't sure what binary is or how it works, check out [this binary tutorial][intro-to-binary].
[intro-to-binary]: https://medium.com/basecs/bits-bytes-building-with-binary-13cb4289aafa
Dig Deeper
Slice indexes
Slice indexes
// Package secret is a small library for interpreting signals for a secret greeting
package secrethandshake
// Handshake interprets what sequence of signals are contained within the number passed in
func Handshake(code uint) []string {
signs := []string{"wink", "double blink", "close your eyes", "jump"}
const reverseSigns = 16
action, actionIncr, end := 0, 1, len(signs)
if (code & reverseSigns) != 0 {
action = 3
actionIncr = -1
end = -1
}
output := []string{}
for ; action != end; action += actionIncr {
if (code & (1 << action)) != 0 {
output = append(output, signs[action])
}
}
return output
}
This approach starts by defining a slice of the signals in their normal order.
A const is defined to represent the signal for reversing the order of the other signals.
It is given a meaningful name so that 16 won’t be used as a magic number.
Some variables are defined with values for iterating the slice of signals in their normal order.
The bitwise AND operator is used to check if the input number contains the signal for reversing the order of the other signals.
For example, if the number passed in is 19, which is 10011 in binary, then it is ANDed with 16, which is 10000 in binary.
The 1 in 10000 is also at the same position in 10011, so the two values ANDed will not be 0.
If the number passed in is 3, which is 00011 in binary, then it is ANDed with 16, which is 10000 in binary.
The 1 in 10000 is not at the same position in 00011, so the two values ANDed will be 0.
If the number passed in contains the signal for reverse, then the iteration variables are set to iterate backwards through the slice of signals.
The output slice is defined, and then the for loop begins.
for ; action != end; action += actionIncr {
Normal iteration will start at index 0.
Reverse iteration will start at index 3.
Normal iteration will terminate when the index equals 4.
Reverse iteration will terminate when the index equals -1.
Normal iteration will increase the index by 1 for each iteration.
Reverse iteration will decrease the index by 1 for each iteration.
For each iteration, the AND operator is used to check if the number passed in contains 1 shifted left (<<) for the number of positions
as the value being iterated.
if (code & (1 << action)) != 0 {
output = append(output, signs[action])
}
For example, if the number being iterated is 0, then 1 is shifted left 0 times (so not shifted at all), and the number passed in is ANDed with 00001.
If the number passed in is 3, which is 00011 in binary, then it is ANDed with 00001.
00011 ANDed with 00001 is not equal to 0, so the signal at the index of the slice of signals is added to the output slice.
The index used is the number being iterated, which is 0, so the element at index 0 ("wink") would be added to the output slice
using the append function.
If the number being iterated is 1, then 1 is shifted left 1 time, and the number passed in is ANDed with 00010.
If the number passed in is 3, which is 00011 in binary, then it is ANDed with 00010.
00011 ANDed with 00010 is not equal to 0, so the signal at the index of the slice of signals is added to the output slice.
The index used is the number being iterated, which is 1, so the element at index 1 ("double blink") would be added to the output slice.
If the number passed in ANDed with the number being iterated is equal to 0, then the signal in the slice for that index is not added to the output slice.
After iterating through the slice of signals is done, the output slice is returned from the function.
Source: Exercism go/secret-handshake