I implemented the Collapsing Matrix Cipher decryption in Python. Cipher Specification Grid Initialization Create a 5×5 grid. Populate it with the unique letters of the keyword (ignore non-alphabetic characters), followed by the remaining letters of the alphabet in order. Treat i and j as the same letter; skip j during grid creation. When decrypting, i and j are interchangeable. Character Decryption For each ciphertext character C, find its position (row, col) in the current grid. The original plaintext character P is at (row+1, col) (wrap around so row 4 becomes row 0). Collapse Step After finding P, remove it from the grid. Shift all characters after P in row-major order (left-to-right, top-to-bottom) forward by one to fill the gap. Use the updated grid for the next character decryption. Here is the complete code I’m using: import sys def preprocess_keyword(keyword): seen = set() keyword = keyword.lower().replace('j', 'i') grid_letters = [] for c in keyword: if c.isalpha() and c not in seen: seen.add(c) grid_letters.append(c) for char_code in range(ord('a'), ord('z') + 1): c = chr(char_code) if c == 'j': continue if c not in seen: seen.add(c) grid_letters.append(c) return [grid_letters[i*5i+1)*5] for i in range(5)] def decrypt_char(grid, cipher_char): cipher_char = 'i' if cipher_char == 'j' else cipher_char trow, tcol = -1, -1 for r in range(5): try: c = grid[r].index(cipher_char) trow, tcol = r, c break except ValueError: continue if trow == -1: return None p_row = (trow + 1) % 5 p_col = tcol return grid[p_row][p_col] def collapse_grid(grid, removed_char): flat = [char for row in grid for char in row] try: idx = flat.index(removed_char) except ValueError: return grid for i in range(idx, 24): flat = flat[i + 1] flat[24] = None return [flat[i*5i+1)*5] for i in range(5)] def process_test_case(keyword, ciphertext): grid = preprocess_keyword(keyword) plaintext = '' for c in ciphertext: p = decrypt_char(grid, c) if p is not None: plaintext += p grid = collapse_grid(grid, p) return plaintext def main(): lines = sys.stdin.read().splitlines() line_idx = 0 while line_idx < len(lines) and not lines[line_idx].strip(): line_idx += 1 if line_idx >= len(lines): return num_test_cases = int(lines[line_idx]) line_idx += 1 outputs = [] for _ in range(num_test_cases): while line_idx < len(lines) and not lines[line_idx].strip(): line_idx += 1 if line_idx >= len(lines): break keyword = lines[line_idx] line_idx += 1 if line_idx >= len(lines): break ciphertext = lines[line_idx] line_idx += 1 outputs.append(process_test_case(keyword, ciphertext)) print('\n\n'.join(outputs)) if __name__ == "__main__": main() Test case: 2 crypto kcnarfm Expected output: hackathon Actual output: soxgbm I expected the decryption to match the example provided in the problem statement, but instead I’m getting incorrect plaintext. I’ve verified my grid initialization, so I suspect the issue is with my collapse_grid logic or the way I determine the plaintext character in decrypt_char. Continue reading...