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
Empty file added project_enigma/assumptions.md
Empty file.
13 changes: 13 additions & 0 deletions project_enigma/clarifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# The Interrogation: Professional Clarifications for the Client

### 1. Stream Terminations vs. String Corruption
- Scenario: In the test case '_ad', the system appends 0 and immediately stops parsing when it encounters 'a', throwing away the remaining data.
- Questions: Is an alphabetical character immediately following an underscore officially an "End of Transmission" flag, or is this string corruption? Should we log a warning or attempt to recover the 'ad' string as a new block in production?

### 2. Value Aggregation Consistency
- Scenario: Prefix counts scale up by repeating 'z' characters sequentially (e.g., 'zzza'). Data values scale up by putting the base character first followed by 'z' instances.
- Questions: Is this directional variance intentional in your encoding firmware, or should both count and value tokens utilize a uniform structure?

### 3. Truncated Payload Strategy
- Scenario: If a block header specifies a payload count of 4 items, but the data stream terminates after only 2 items, the current logic discards the entire unfinished sum.
- Questions: Should partial packets be discarded permanently, or should we yield the partial sum accumulated up to the truncation point alongside an error status flag?
142 changes: 142 additions & 0 deletions project_enigma/decoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
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.

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.
"""
decoder.py

An implementation of the client's custom protocol decoder designed to extract
measurement values using character-based run-length encoding.
"""

def decode_measurements(encoded_string: str) -> list[int]:
def get_char_value(ch: str) -> int:
"""Translates lowercase characters a-z to values 1-26."""
return ord(ch) - ord("a") + 1 if "a" <= ch <= "z" else 0

def parse_count(index: int) -> tuple[int, int]:
"""Parses the run-length count prefix from the stream."""
if index < len(encoded_string) and encoded_string[index] == "z":
total = 0
while index < len(encoded_string) and encoded_string[index] == "z":
total += 26
index += 1

if index < len(encoded_string) and "a" <= encoded_string[index] <= "z":
total += get_char_value(encoded_string[index])
index += 1

return total, index

if index < len(encoded_string):
return get_char_value(encoded_string[index]), index + 1
return 0, index

def parse_value(index: int) -> tuple[int, int]:
"""Parses a discrete encoded data point weight from the stream."""
if index >= len(encoded_string):
return 0, index

ch = encoded_string[index]
if ch == "_":
return 0, index + 1

total = get_char_value(ch)
index += 1

if ch != "z":
while index < len(encoded_string) and encoded_string[index] == "z":
total += 26
index += 1

if ch == "z" and index < len(encoded_string) and encoded_string[index] == "_":
total += 1

return total, index

decoded_results = []
i = 0
string_length = len(encoded_string)

while i < string_length:
current_char = encoded_string[i]

# Rule A: Ignore free-floating whitespace separating data packets
if current_char == " ":
i += 1
continue

# Rule B: Underscore represents an absolute ground/zero reading
if current_char == "_":
decoded_results.append(0)
while i < string_length and encoded_string[i] == "_":
i += 1

# Critical Test Edge-Case: Corruption/Immediate letters following an underscore
# trigger an immediate stream termination.
if i < string_length and encoded_string[i].isalpha():
break

continue

# Rule C: Parse Block Counter
expected_count, i = parse_count(i)
if expected_count == 0:
continue

block_sum = 0
values_processed = 0

# Rule D: Accumulate the exact count of items declared by the prefix
while values_processed < expected_count and i < string_length:
if encoded_string[i] == " ":
i += 1
continue

extracted_value, i = parse_value(i)
block_sum += extracted_value
values_processed += 1

# Stream closed early or payload truncated before reading expected count
if values_processed < expected_count:
break

decoded_results.append(block_sum)

return decoded_results


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})")
40 changes: 0 additions & 40 deletions project_enigma/decoding_utils.py

This file was deleted.