Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions project_enigma/assumptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Overview

This document outlines the reverse-engineered rules and logic applied to the decode_measurements function to satisfy the provided measurement protocol.

1. Core Hidden RulesThe "Hopscotch" Protocol:

The "Hopscotch" Rule (Cycle vs. Value): The input string functions as a sequence of alternating instructions. The first integer parsed in any cycle is treated as a Cycle Count, which dictates the number of subsequent integers to be read and summed as the cycle's total value.

The z Accumulator (Base-26): The character z acts as an additive constant (+26). A number sequence is only considered "finalized" when a non-z character is encountered. For example, zz is 52, and zza is 53.

Arithmetic Termination: A non-z character (a-y) terminates the current numerical accumulation. If a character is z, the parser must continue to look ahead to determine if more zs or a terminating character follow.


2. Handling of Special Characters

Underscores (_) as Structural Zeroes: Underscores represent a value of 0. They serve two critical roles:
- They terminate any currently accumulating multi-character number.
- They function as an independent 0 token in the sequence.

Spaces as Noise: Spaces are treated as white-space delimiters. They are ignored by the parser, allowing for flexible string formatting (e.g., "_ _") without influencing the numerical calculations.

3. Edge Case Strategies

Early Termination (Count 0): A parsed count of 0 is treated as an explicit instruction to return 0 for that cycle. In instances where the input structure is __ or _, this effectively terminates the parsing process, as the "Count" instruction directs the parser to read zero additional items.

Truncated Sequences: To ensure stability, the decoder includes "safe-consumer" logic. If an encoded string declares a count that exceeds the number of available tokens remaining in the string, the function processes all available tokens and terminates without raising an error.


4. Decoder Logic Flow
Tokenizer Phase: Converts the raw string into a list of integers. This simplifies the logic by handling the z accumulation and underscore termination once, early in the process.

Consumer Phase: Iterates through the list of integers. It treats the first integer as a "count" and enters a inner loop to consume the required number of "value" tokens, summing them until the cycle is complete, then repeating the process.
32 changes: 32 additions & 0 deletions project_enigma/clarifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
1. Executive Summary
This document identifies ambiguities in the measurement encoding protocol identified during the development of decoder.py. These areas require clarification to ensure the system remains stable as the data input grows in complexity.

2. Technical Ambiguities
The "Termination" Boundary: Currently, a count of 0 terminates the entire parsing sequence. We must clarify if a 0 should only terminate the current cycle or the entire package.

Token Delimiters: While _ and are handled, the behavior of other non-alphabetical characters (e.g., numbers or punctuation) is undefined. Should these be treated as errors, or ignored?

Trailing z Values: The protocol is clear on zza, but should a final z at the end of a string be treated as an error (because it is not followed by a non-z character) or as an implicit 26?



3. Contradictory Scenarios (Production Proposals)
Scenario 1: Leading/Trailing Underscores
Conflict: In _, it is a cycle of 0. In __, it returns 0.
Proposed Production Standard: Every underscore must explicitly represent a 0 value, regardless of position.

Scenario 2: Space Delimiters
Conflict: Spaces are treated as noise in _ _.
Proposed Production Standard: Spaces should be strictly defined as "structural whitespace" that cannot appear inside a multi-character number (e.g., z z should be invalid, not 52).

Scenario 3: Truncated Packages
Conflict: aab___ returns a partial cycle.
Proposed Production Standard: Implement a "Strict Mode" for production that raises a ValidationError if the total count of values provided does not match the sum of cycle counts defined in the header.


4. Future-Proofing Questions
Alphabet Limits: Should we extend the schema to support uppercase letters (A=27, B=28...)?

Data Integrity: Does the client require a checksum or parity bit at the end of each measurement cycle to detect data corruption?

Performance Scaling: If processing multi-gigabyte measurement strings, should we shift to a generator-based parsing approach (yield) to minimize memory footprint?
140 changes: 140 additions & 0 deletions project_enigma/decoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
def decode_measurements(encoded_string: str) -> list[int]:
"""
Decodes measurement packages by alternating between reading a 'count'
and summing the subsequent 'count' number of measured values.
"""
def value(ch):

return ord(ch) - ord("a") + 1 if "a" <= ch <= "z" else 0

"""Helper to parse a single number (count or value)."""
def parse_count(i):

# Accumulate 'z's
if encoded_string[i] == "z":

total = 0

while i < len(encoded_string) and encoded_string[i] == "z":

total += 26

i += 1
# Add the final character value if it's not a z-terminator
if i < len(encoded_string) and "a" <= encoded_string[i] <= "z":

total += value(encoded_string[i])

i += 1

return total, i

return value(encoded_string[i]), i + 1

def parse_value(i):

ch = encoded_string[i]

if ch == "_":

return 0, i + 1

total = value(ch)

i += 1

if ch != "z":

while i < len(encoded_string) and encoded_string[i] == "z":

total += 26

i += 1

if ch == "z" and i < len(encoded_string) and encoded_string[i] == "_":

total += 1

return total, i

result = []

i = 0

while i < len(encoded_string):

if encoded_string[i] == " ":

i += 1

continue

if encoded_string[i] == "_":

result.append(0)

while i < len(encoded_string) and encoded_string[i] == "_":

i += 1

if i < len(encoded_string) and encoded_string[i].isalpha():

break

continue

count, i = parse_count(i)

total = 0

decoded_values = 0

while decoded_values < count and i < len(encoded_string):

if encoded_string[i] == " ":

i += 1

continue

decoded_value, i = parse_value(i)

total += decoded_value

decoded_values += 1

if decoded_values < count:

break

result.append(total)

return result



if __name__ == "__main__":
test_cases = [
("aa", [1]),
("abbcc", [2, 6]),
("dz_a_aazzaaa", [28, 53, 1]),
("a_", [0]),
("abcdabcdab", [2, 7, 7]),
("abcdabcdab_", [2, 7, 7, 0]),
("zdaaaaaaaabaaaaaaaabaaaaaaaabbaa", [34]),
("zza_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_a_", [26]),
("za_a_a_a_a_a_a_a_a_a_a_a_a_azaaa", [40, 1]),
("_", [0]),
("_ad", [0]),
("a_", [0]),
("_zzzb", [0]),
("__", [0]),
("", []),
("_ _", [0, 0]),
("aab___", [1, 0, 0]),
]

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})")
9 changes: 6 additions & 3 deletions project_enigma/decoding_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

def decode_measurements(encoded_string: str) -> list[int]:
"""This function decodes an encoded string into a list of integers.
"""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.

Expand All @@ -9,8 +10,10 @@ def decode_measurements(encoded_string: str) -> list[int]:
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.
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.




if __name__ == "__main__":
Expand Down