Who's name is hidden in here?
Answer: MENDELEEV1
The circles in the puzzle are arranged in a $$26 \times 26$$ grid with 26 rows and 26 columns. If we identify the rows of the grid from top to bottom with successive uppercase letters and the columns from left to right with successive lowercase letters, then the position of each circle in the grid can be represented by two letters: the uppercase letter that identifies the row of the circle, followed by the lowercase letter that identifies its column. However, the position of a circle on the main diagonal is represented by a single letter: the uppercase letter that identifies the row (and thus also corresponds to the letter that identifies the column).
If you now take a closer look, you'll see that the red circles correspond to positions represented by one or two letters of symbols for chemical elements from the periodic table2: a systematic arrangement of all known chemical elements. These red circles must be ignored: only the green circles are important to find the answer.
Taking a look at what numbers are in the five green circles in the original puzzle (we have put them inside small black circles near the green circles), you'll see that the green circles are numbered sequentially, starting from 1. This determines the order in which the representations of the positions of the green circles must be concatenated: the green circle with number 1 is at position M, the green circle with number 2 at position En, the green circle with number 3 at position De, the green circle with number 4 at position Le and the green circle with number 5 at position Ev. Concatenating the representations of these positions yields the name MENDELEEV.
A puzzle file is a text file with 26 lines, each containing 26 digits (0–9). For example, this is the puzzle file corresponding to the puzzle from the introduction (puzzle.txt3):
00300080000450000528300000 37001006505000000500000000 60238400000773300910400000 07003000000000000020000010 00000000000002000540550000 00006200000290000700000000 70033000000000000000000000 00006526000000100040000000 00000000200006000800000000 00000000000000000000000000 00000000002000000100000000 50004000500000000600290000 00990070000019600003000000 42079006700001760000000000 00000010000000100060000000 57070000000030350808100000 00000000000000000000000000 45008316000002000000800000 04408080900026000470000000 21803001400380000040000000 00000000000000000000600000 00000000000000000000070000 00000000000000000000001000 00003000000000000000000000 07000000000000000000000040 00000000000004000300000000
Each zero (digit 0) in this file corresponds to a position where there is no circle in the puzzle and each other digit corresponds to a position where there is a black circle in the puzzle containing that digit. A puzzle file therefore corresponds to a representation of the puzzle where we would also draw circles containing a zero at positions where there are zeros in the file.
In the above representation of the puzzle we have numbered the rows from top to bottom, starting at zero. We have also numbered the columns from left to right, starting at zero. This allows us to represent any position in the $$26 \times 26$$ puzzle grid as a coordinate: a tuple $$(r, c)$$ with two integers $$r, c \in \mathbb{N}$$ (int; $$0 \leq r, c < 26$$). By identifying the rows and columns with letters as in the introduction, we can also represent each position in the puzzle grid symbolically as a single letter (str; for positions on the main diagonal) or two letters (str; for positions off the main diagonal).
Your task:
Write a function symbol2coordinate that takes the symbolic representation (str) of a position $$p$$ in the $$26 \times 26$$ puzzle grid. The function must return the coordinate (tuple) of position $$p$$. No distinction should be made between uppercase and lowercase letters when interpreting the symbolic representation of the position.
Write a function coordinate2symbol that takes the coordinate (tuple) of a position $$p$$ in the $$26 \times 26$$ puzzle grid. The function must return the symbolic representation (str; in uppercase) of position $$p$$.
Write a function symbols that takes two arguments: i) the location (str) of a CSV file4 with UTF-85 character encoding and ii) the number $$i$$ (int) of a field (column) in the CSV file. The first line in the CSV file contains a header. The fields of a CSV file are numbered sequentially starting from 1 and are separated by commas (,). A field that itself contains commas must be enclosed in double quotes ("). Other fields may optionally be enclosed in double quotes. The function must return a set containing the content (str) of the $$i$$-th field of all CSV records from the file (without the header) where this field consists of one or two letters. In addition, that content must be converted to uppercase, and the content must be reduced to a single letter if it consists of two of the same letters (for example, xx must be converted to X).
Use the csv module6 to process records of CSV files.
Write a function all_coordinates that takes the location (str) of a puzzle file. The function must return a dictionary (dict) that maps each coordinate (tuple) of a circle in the puzzle grid onto the digit (int) in that circle.
Write a function valid_coordinates that takes two arguments: i) the location (str) of a puzzle file and ii) a collection (list, tuple or set) containing the symbolic representation (str) of all invalid positions in the puzzle grid. The function must return a dictionary (dict) that maps each coordinate (tuple) of a circle in the puzzle grid that is not at an invalid position onto the digit (int) in that circle.
Write a function hidden_name that takes two arguments: i) the location (str) of a puzzle file and ii) a collection (list, tuple or set) containing the symbolic representation (str) of all invalid positions in the puzzle grid. The function must return the name (str; in uppercase) hidden in the puzzle.
In the following interactive session we assume that the text files symbols.csv7 and puzzle.txt8 are located in the current directory.
>>> symbol2coordinate('Ac')
(0, 2)
>>> symbol2coordinate('B')
(1, 1)
>>> symbol2coordinate('MG')
(12, 6)
>>> coordinate2symbol((0, 2))
'AC'
>>> coordinate2symbol((1, 1))
'B'
>>> coordinate2symbol((12, 6))
'MG'
>>> invalid_symbols = symbols('symbols.csv9', 2)
>>> invalid_symbols
{'AC', 'AG', 'AL', 'AM', 'AR', 'AS', 'AT', 'AU', 'B', 'BA', 'BE', 'BH', 'BI', 'BK', 'BR', 'C', 'CA', 'CD', 'CE', 'CF', 'CL', 'CM', 'CN', 'CO', 'CR', 'CS', 'CU', 'DB', 'DS', 'DY', 'ER', 'ES', 'EU', 'F', 'FE', 'FL', 'FM', 'FR', 'GA', 'GD', 'GE', 'H', 'HE', 'HF', 'HG', 'HO', 'HS', 'I', 'IN', 'IR', 'K', 'KR', 'LA', 'LI', 'LR', 'LU', 'LV', 'MC', 'MD', 'MG', 'MN', 'MO', 'MT', 'N', 'NA', 'NB', 'ND', 'NE', 'NH', 'NI', 'NO', 'NP', 'O', 'OG', 'OS', 'P', 'PA', 'PB', 'PD', 'PM', 'PO', 'PR', 'PT', 'PU', 'RA', 'RB', 'RE', 'RF', 'RG', 'RH', 'RN', 'RU', 'S', 'SB', 'SC', 'SE', 'SG', 'SI', 'SM', 'SN', 'SR', 'TA', 'TB', 'TC', 'TE', 'TH', 'TI', 'TL', 'TM', 'TS', 'U', 'V', 'W', 'XE', 'Y', 'YB', 'ZN', 'ZR'}
>>> all_coordinates('puzzle.txt10')
{(0, 2): 3, (0, 6): 8, (0, 11): 4, (0, 12): 5, (0, 17): 5, (0, 18): 2, (0, 19): 8, (0, 20): 3, (1, 0): 3, (1, 1): 7, (1, 4): 1, (1, 7): 6, (1, 8): 5, (1, 10): 5, (1, 17): 5, (2, 0): 6, (2, 2): 2, (2, 3): 3, (2, 4): 8, (2, 5): 4, (2, 11): 7, (2, 12): 7, (2, 13): 3, (2, 14): 3, (2, 17): 9, (2, 18): 1, (2, 20): 4, (3, 1): 7, (3, 4): 3, (3, 18): 2, (3, 24): 1, (4, 13): 2, (4, 17): 5, (4, 18): 4, (4, 20): 5, (4, 21): 5, (5, 4): 6, (5, 5): 2, (5, 11): 2, (5, 12): 9, (5, 17): 7, (6, 0): 7, (6, 3): 3, (6, 4): 3, (7, 4): 6, (7, 5): 5, (7, 6): 2, (7, 7): 6, (7, 14): 1, (7, 18): 4, (8, 8): 2, (8, 13): 6, (8, 17): 8, (10, 10): 2, (10, 17): 1, (11, 0): 5, (11, 4): 4, (11, 8): 5, (11, 17): 6, (11, 20): 2, (11, 21): 9, (12, 2): 9, (12, 3): 9, (12, 6): 7, (12, 12): 1, (12, 13): 9, (12, 14): 6, (12, 19): 3, (13, 0): 4, (13, 1): 2, (13, 3): 7, (13, 4): 9, (13, 7): 6, (13, 8): 7, (13, 13): 1, (13, 14): 7, (13, 15): 6, (14, 6): 1, (14, 14): 1, (14, 18): 6, (15, 0): 5, (15, 1): 7, (15, 3): 7, (15, 12): 3, (15, 14): 3, (15, 15): 5, (15, 17): 8, (15, 19): 8, (15, 20): 1, (17, 0): 4, (17, 1): 5, (17, 4): 8, (17, 5): 3, (17, 6): 1, (17, 7): 6, (17, 13): 2, (17, 20): 8, (18, 1): 4, (18, 2): 4, (18, 4): 8, (18, 6): 8, (18, 8): 9, (18, 12): 2, (18, 13): 6, (18, 17): 4, (18, 18): 7, (19, 0): 2, (19, 1): 1, (19, 2): 8, (19, 4): 3, (19, 7): 1, (19, 8): 4, (19, 11): 3, (19, 12): 8, (19, 18): 4, (20, 20): 6, (21, 21): 7, (22, 22): 1, (23, 4): 3, (24, 1): 7, (24, 24): 4, (25, 13): 4, (25, 17): 3}
>>> valid_coordinates('puzzle.txt11', invalid_symbols)
{(3, 4): 3, (4, 13): 2, (4, 21): 5, (11, 4): 4, (12, 12): 1}
>>> hidden_name('puzzle.txt12', invalid_symbols)
'MENDELEEV'