From 5d6de8eab3ea2ccdc5c447968e94723b88c681db Mon Sep 17 00:00:00 2001 From: ghadeernaamani20 Date: Thu, 25 Jun 2026 10:48:00 +0400 Subject: [PATCH] feat: add eval task decoder, assumptions and clarifications --- project_enigma/assumptions..py | 31 ++++++++++++++++++ project_enigma/clarifications.py | 20 ++++++++++++ project_enigma/decoding_utils.py | 55 +++++++++++++++++++++++++------- 3 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 project_enigma/assumptions..py create mode 100644 project_enigma/clarifications.py diff --git a/project_enigma/assumptions..py b/project_enigma/assumptions..py new file mode 100644 index 0000000..e776ea5 --- /dev/null +++ b/project_enigma/assumptions..py @@ -0,0 +1,31 @@ +# Detective's Log – Reverse-Engineered Encoding Rules + +## Hidden Rules Discovered + +### 1. Letter-to-number mapping +Each lowercase letter maps to its alphabetical position: +`a=1, b=2, c=3 ... z=26` + +### 2. Numbers above 26 (multi-character encoding) +A sequence of one or more `z` characters followed by a single non-`z` +terminating character encodes a number by summing all parts. +Examples: +- `zb` = 26 + 2 = 28 +- `zza` = 26 + 26 + 1 = 53 +- `zd` = 26 + 4 = 30 + +### 3. Packet structure +Each packet follows the pattern: [header][values] +- The header is one encoded number = how many values follow. +- The values are read one character at a time and summed. +- The packet output = sum of its values. + +### 4. The underscore `_` character +- As a header: encodes 0, immediately terminates the segment, outputs 0. +- As a value slot: contributes 0 to the running sum. + +### 5. Spaces separate independent segments +A space splits the string into independent segments decoded separately. + +### 6. Empty string +An empty string produces an empty list. \ No newline at end of file diff --git a/project_enigma/clarifications.py b/project_enigma/clarifications.py new file mode 100644 index 0000000..230e19e --- /dev/null +++ b/project_enigma/clarifications.py @@ -0,0 +1,20 @@ +# Clarification Questions for Acme Metrics Corp + +## 1. What exactly does `_` mean? +Our assumption: `_` = 0. As a header it terminates immediately. +As a value it contributes 0. Please confirm. + +## 2. What about characters outside `a-z` and `_`? +Our assumption: treat them as 0. Should they raise an error instead? + +## 3. What if a header promises more values than exist in the string? +Our assumption: sum what is available, no error raised. +Should this be treated as malformed input? + +## 4. Can multiple consecutive spaces appear? +Our assumption: each space creates a new segment boundary. +Double spaces would create an empty segment contributing nothing. + +## 5. Is there a maximum number size? +Our assumption: unlimited `z` chaining is valid. +Is there a practical upper limit? \ No newline at end of file diff --git a/project_enigma/decoding_utils.py b/project_enigma/decoding_utils.py index 775b218..09e828d 100644 --- a/project_enigma/decoding_utils.py +++ b/project_enigma/decoding_utils.py @@ -1,16 +1,49 @@ def decode_measurements(encoded_string: str) -> list[int]: - """This function decodes an encoded string into a list of integers. - RULE 1: A generic logic should be implemented without handling edge cases using if statements for specific inputs. - RULE 2: The generic logic should handle all inputs and generate the expected outputs. - Args: - encoded_string (str): The encoded string to decode. + def letter_to_int(character: str) -> int: + if "a" <= character <= "z": + return ord(character) - 96 + return 0 - Returns: - list[int]: The list of decoded integers. - """ - pass # Remove this pass and place your logic here to decode the string into a list of integers based on the specified encoding rules. - return [] # Placeholder return statement; replace with actual decoding logic. + def extract_number(text: str, position: int): + accumulated = 0 + while position < len(text) and text[position] == "z": + accumulated += 26 + position += 1 + if position < len(text) and text[position] != "_": + accumulated += letter_to_int(text[position]) + position += 1 + elif position < len(text) and text[position] == "_": + position += 1 + return accumulated, position + + def process_segment(segment: str) -> list[int]: + output = [] + cursor = 0 + + while cursor < len(segment): + how_many, cursor = extract_number(segment, cursor) + + if how_many == 0: + output.append(0) + break + + running_sum = 0 + for _ in range(how_many): + if cursor >= len(segment): + break + next_val, cursor = extract_number(segment, cursor) + running_sum += next_val + + output.append(running_sum) + + return output + + final_output = [] + for part in encoded_string.split(" "): + final_output.extend(process_segment(part)) + + return final_output if __name__ == "__main__": @@ -37,4 +70,4 @@ def decode_measurements(encoded_string: str) -> list[int]: for encoded, expected in test_cases: result = decode_measurements(encoded) status = "PASS" if result == expected else "FAIL" - print(f"{status}: decode_measurements({encoded!r}) = {result} (expected {expected})") + print(f"{status}: decode_measurements({encoded!r}) = {result} (expected {expected})") \ No newline at end of file