object SecretHandshake {
val SIGNS = Vector("wink", "double blink", "close your eyes", "jump")
val REVERSE_SIGNS = 16
def commands(orders: Int): Seq[String] = {
val signs =
(0 until SIGNS.length)
.foldLeft(Seq(): Seq[String])((output, index) =>
if ((1 << index & orders) != 0) output :+ SIGNS(index)
else output
)
if ((orders & REVERSE_SIGNS) == 0) signs else signs.reverse
}
}
This approach starts by defining a Vector for holding the signs, and an Int
binding for the reverse value.
The command()
method starts by defining a Range
from 0
up to but not including the length of the signs Vector
.
Each number in the Range
is passed to the foldLeft()
method for an index value.
The foldLeft()
is initialized with an empty Seq[String]
for the output value.
The lambda in foldLeft
uses the bitwise shift left operator to see if the input number has a binary 1
in the same position
as 1
shifted left for the index value.
If so, then the element for that index in the signs Vector
is appended to the output Seq
.
If not, the output Seq
is passed as is to the next iteration of foldLeft()
.
After foldLeft()
is done, the signs
binding is set to the output Seq
.
The function uses a ternary expression to return either the Seq
as is or the Seq
in reverse()
,
depending if the input number has a bit set in the same position as binary 16
(10000
).
Example
If the input number is 26
, its value in binary is 11010
. The 1
bits are set at four from the right, three from the right and
one from the right.
- The element in the signs
Vector
at index1
is "double blink", so that would get appended to the outputSeq
. - The element in the signs
Vector
at index3
is "jump", so that would get appended to the outputSeq
, after "double blink". - Index
4
is beyond the length of theVector
, but1
shifted left 4 places is10000
, which is the binary value for16
, so "double blink" and "jump" would be reversed and returned fromcommands()
as("jump", "double blink")
.