Iterate once

Secret Handshake
Secret Handshake in C

secret_handshake.h

#ifndef SECRET_HANDSHAKE_H
#define SECRET_HANDSHAKE_H

#include <stddef.h>

const char **commands(size_t number);

#endif

secret_handshake.c

#include "secret_handshake.h"
#include <malloc.h>

static const char * signals[] = { "wink", "double blink", "close your eyes", "jump" };

const char **commands(size_t n) {
    const char **output = calloc(4, sizeof(char *));
    int signal = 0, signal_incr = 1, output_idx = 0, end = 4;
    if (n & 16) {signal = 3; signal_incr = -1; end = -1;}

    for (; signal != end; signal+=signal_incr)
        if (n & 1 << signal)
            output[output_idx++] = signals[signal];
    return output;
}

This approach starts by defining an array of pointers to const char strings. The const indicates that the content of the elements can't be changed. The static is to indicate that the array has internal linkage within the file, and is not declared in the header for external use.

The commands function starts by using the calloc function to allocate the memory for the output pointer to pointers of const chars, which can be thought of as an array of strings. It indicates that the array will have 4 elements, and each element will be the size of a pointer to char.

Variables are defined that control iterating through the signals array, setting their values to iterate in the normal order. Also, the index for the ouput array is set to start with 0.

The bitwise AND operator is used to check if the input number contains the signal for reversing the order of the other signals, given that the signal for reversing is decimal value 16 (10000 in binary).

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.

  • 10011 AND
  • 10000 =
  • 10000

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.

  • 00011 AND
  • 10000 =
  • 00000

If the number passed in contains the signal for reverse, then the iteration variables are set to iterate backwards through the array of signals.

The for loop begins.

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 of the for loop, the AND operator is used to check if the number passed in contains 1 shifted left (<<) for the number of positions as the index being iterated. It uses the falsiness of 0 and the truthiness of any value other than 0.

for (; signal != end; signal+=signal_incr)
    if (n & 1 << signal)
        output[output_idx++] = signals[signal];

For example, if the index being iterated is 0, then 1 is shifted left 0 times (so not shifted at all), and the signal 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 not false), so the string at index 0 of the array of signals is set to the element of the output array at the current output index. output_idx++ means that the value of output_idx is incremented after it is used for indexing into the output array.

If the index being iterated is 1, then 1 is shifted left 1 time, and the signal 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 not false), so the string at index 1 of the array of signals is added to the output array at the current output index.

If the number passed in, ANDed with 1 shifted left for the value of the index, is equal to 0, then the signal in the array for that index is not set in the output array.

After iterating through the array of signals is done, the output array is returned from the function.

17th Jul 2024 · Found it useful?