File: decode-the-message/solution.py

Date: 2026-06-06

Time: 16:11

decode-the-message/solution.py

Purpose

This file solves LeetCode 2325 — Decode the Message. It builds a substitution cipher from a key string and applies it to decode a message. The file is self-contained: solution function + inline unit tests, following the repo's standard pattern.

Key Components

valid_selections(key, message) -> str — Misleadingly named (likely a copy-paste artifact; should be decodeMessage). It does two things:

1. Builds a substitution table (lines 14–18): Iterates through key, mapping each novel lowercase letter to the next letter of the alphabet ('a', 'b', 'c', ...). Spaces are skipped, and duplicates are ignored via the ch not in table guard. The result is a dict[str, str] mapping cipher chars to plaintext chars.

2. Decodes the message (line 19): Replaces each character in message using the table. table.get(ch, ch) passes through any character not in the table (specifically spaces, since those were excluded from table construction).

TestValidSelections — Seven test cases covering the LeetCode examples, identity key, single character, trailing spaces, and keys with leading duplicates.

Patterns

Dependencies

Flow


key = "the quick brown fox jumps over the lazy dog"
       ↓
Iterate chars: t→a, h→b, e→c, q→d, u→e, i→f, c→g, k→h, ...
       ↓
table = {'t':'a', 'h':'b', 'e':'c', 'q':'d', ...}  (26 entries)
       ↓
message = "vkbs bs t suepuv"
       ↓
Each char looked up: v→t, k→h, b→i, s→s, ' '→' ', ...
       ↓
result = "this is a secret"

The idx counter advances from 0 to 25, mapping exactly 26 unique letters. Once all 26 are mapped, subsequent key characters are no-ops.

Invariants

Error Handling

None. The function trusts its inputs match LeetCode's constraints. No validation of key completeness, no handling of uppercase or non-alpha characters beyond spaces. This is appropriate for a LeetCode solution where inputs are guaranteed well-formed.