diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index 176cefb..ede578c 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -19,7 +19,7 @@ jobs: matrix: python-version: ["3.12"] steps: - - uses: "actions/checkout@v5" + - uses: "actions/checkout@v6" - name: Set up Python ${{ matrix.python-version }} # This is the version of the action for setting up Python, # not the Python version. diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index ff25eb1..9c435a1 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -15,7 +15,7 @@ jobs: matrix: python-version: ["3.12"] steps: - - uses: "actions/checkout@v5" + - uses: "actions/checkout@v6" - name: Set up Python ${{ matrix.python-version }} uses: "actions/setup-python@v6" with: diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 7737a16..55bc6ee 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 10 steps: - name: "Checkout code" - uses: "actions/checkout@v5" + uses: "actions/checkout@v6" - name: "Set up Python 3.12" uses: "actions/setup-python@v6" with: diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml index 7e4659c..63a7512 100644 --- a/.github/workflows/ruff.yml +++ b/.github/workflows/ruff.yml @@ -12,7 +12,7 @@ jobs: # indefinitely if something goes wrong timeout-minutes: 10 steps: - - uses: "actions/checkout@v5" + - uses: "actions/checkout@v6" - name: "Set up Python 3.12" uses: "actions/setup-python@v6" with: diff --git a/.github/workflows/yamllint.yml b/.github/workflows/yamllint.yml index 1d797de..81f7a49 100644 --- a/.github/workflows/yamllint.yml +++ b/.github/workflows/yamllint.yml @@ -12,7 +12,7 @@ jobs: # indefinitely if something goes wrong timeout-minutes: 10 steps: - - uses: "actions/checkout@v5" + - uses: "actions/checkout@v6" - name: "Set up Python 3.12" uses: "actions/setup-python@v6" with: diff --git a/solutions/python/secret-handshake/1/secret_handshake.py b/solutions/python/secret-handshake/1/secret_handshake.py new file mode 100644 index 0000000..e6a637b --- /dev/null +++ b/solutions/python/secret-handshake/1/secret_handshake.py @@ -0,0 +1,51 @@ +""" +Secret Handshake. + +Convert a number's binary representation (up to five bits) to a +sequence of actions in the secret handshake. + +The sequence of actions is determined by inspecting the rightmost five +binary digits (least-significant bit on the right): + +- 1 (..00001): "wink" +- 2 (..00010): "double blink" +- 4 (..00100): "close your eyes" +- 8 (..01000): "jump" +- 16(..10000): reverse the order of the operations selected above + +Only the presence of a bit matters; higher bits beyond the five listed +are ignored. The reverse bit (16) inverses the final list of actions. +""" + +ACTIONS: dict[int:tuple[str, str]] = { + 1: ("00001", "wink"), + 2: ("00010", "double blink"), + 3: ("00100", "close your eyes"), + 4: ("01000", "jump"), + 5: ("10000", "Reverse the order of the operations in the secret handshake"), +} + + +def commands(binary_str: str) -> list[str]: + """ + Return the list of secret-handshake actions for the given binary string. + + The input should be a binary string whose rightmost character is the + least-significant bit. Up to five bits are considered, mapping to the + actions defined by the classic Exercism "Secret Handshake" exercise. + If the fifth bit is set, the final list of actions is reversed. + + :param binary_str: Binary string (e.g. "10101"). Rightmost char is LSB. + :returns: A list of action strings in the computed order. + """ + results: list = [] + # Iterate from least- to most-significant bit by reversing the string. + for i, char in enumerate(binary_str[::-1]): + # Check if the corresponding bit position matches the expected "1". + if ACTIONS[i + 1][0][-(i + 1)] == char: + if i + 1 != 5: + results.append(ACTIONS[i + 1][1]) + else: + # Fifth bit indicates the final list should be reversed. + results = results[::-1] + return results diff --git a/solutions/python/secret-handshake/2/secret_handshake.py b/solutions/python/secret-handshake/2/secret_handshake.py new file mode 100644 index 0000000..c2d8971 --- /dev/null +++ b/solutions/python/secret-handshake/2/secret_handshake.py @@ -0,0 +1,49 @@ +""" +Secret Handshake. + +Convert a number's binary representation (up to five bits) to a +sequence of actions in the secret handshake. + +The sequence of actions is determined by inspecting the rightmost five +binary digits (least-significant bit on the right): + +- 1 (..00001): "wink" +- 2 (..00010): "double blink" +- 4 (..00100): "close your eyes" +- 8 (..01000): "jump" +- 16(..10000): reverse the order of the operations selected above + +Only the presence of a bit matters; higher bits beyond the five listed +are ignored. The reverse bit (16) inverses the final list of actions. +""" + +ACTIONS: dict[int : tuple[str, str]] = { + 0: ("00001", "wink"), + 1: ("00010", "double blink"), + 2: ("00100", "close your eyes"), + 3: ("01000", "jump"), +} + + +def commands(binary_str: str) -> list[str]: + """ + Return the list of secret-handshake actions for the given binary string. + + The input should be a binary string whose rightmost character is the + least-significant bit. Up to five bits are considered, mapping to the + actions defined by the classic Exercism "Secret Handshake" exercise. + If the fifth bit is set, the final list of actions is reversed. + + :param binary_str: Binary string (e.g. "10101"). Rightmost char is LSB. + :returns: A list of action strings in the computed order. + """ + results: list[str] = [] + # Iterate from least- to most-significant bit by reversing the string. + for i, char in enumerate(binary_str[::-1]): + # Check if the corresponding bit position matches the expected "1". + if char == "1" and i < 4: + results.append(ACTIONS[i][1]) + elif char == "1" and i == 4: + # Fifth bit indicates the final list should be reversed. + results = results[::-1] + return results diff --git a/solutions/python/secret-handshake/3/secret_handshake.py b/solutions/python/secret-handshake/3/secret_handshake.py new file mode 100644 index 0000000..74b082a --- /dev/null +++ b/solutions/python/secret-handshake/3/secret_handshake.py @@ -0,0 +1,44 @@ +""" +Secret Handshake. + +Convert a number's binary representation (up to five bits) to a +sequence of actions in the secret handshake. + +The sequence of actions is determined by inspecting the rightmost five +binary digits (least-significant bit on the right): + +- 1 (..00001): "wink" +- 2 (..00010): "double blink" +- 4 (..00100): "close your eyes" +- 8 (..01000): "jump" +- 16(..10000): reverse the order of the operations selected above + +Only the presence of a bit matters; higher bits beyond the five listed +are ignored. The reverse bit (16) inverses the final list of actions. +""" + +ACTIONS: tuple[str, str, str, str] = ("wink", "double blink", "close your eyes", "jump") + + +def commands(binary_str: str) -> list[str]: + """ + Return the list of secret-handshake actions for the given binary string. + + The input should be a binary string whose rightmost character is the + least-significant bit. Up to five bits are considered, mapping to the + actions defined by the classic Exercism "Secret Handshake" exercise. + If the fifth bit is set, the final list of actions is reversed. + + :param binary_str: Binary string (e.g. "10101"). Rightmost char is LSB. + :returns: A list of action strings in the computed order. + """ + results: list[str] = [] + # Iterate from least- to most-significant bit by reversing the string. + for i, char in enumerate(binary_str[::-1]): + # Check if the corresponding bit position matches the expected "1". + if char == "1" and i < 4: + results.append(ACTIONS[i]) + elif char == "1" and i == 4: + # Fifth bit indicates the final list should be reversed. + results = results[::-1] + return results