RosettaCodeData/Task/Periodic-table/Python/periodic-table.py

47 lines
1.4 KiB
Python

def perta(atomic) -> (int, int):
NOBLES = 2, 10, 18, 36, 54, 86, 118
INTERTWINED = 0, 0, 0, 0, 0, 57, 89
INTERTWINING_SIZE = 14
LINE_WIDTH = 18
prev_noble = 0
for row, noble in enumerate(NOBLES):
if atomic <= noble: # we are at the good row. We now need to determine the column
nb_elem = noble - prev_noble # number of elements on that row
rank = atomic - prev_noble # rank of the input element among elements
if INTERTWINED[row] and INTERTWINED[row] <= atomic <= INTERTWINED[row] + INTERTWINING_SIZE: # lantanides or actinides
row += 2
col = rank + 1
else: # not a lantanide nor actinide
# handle empty spaces between 1-2, 4-5 and 12-13.
nb_empty = LINE_WIDTH - nb_elem # spaces count as columns
inside_left_element_rank = 2 if noble > 2 else 1
col = rank + (nb_empty if rank > inside_left_element_rank else 0)
break
prev_noble = noble
return row+1, col
# small test suite
TESTS = {
1: (1, 1),
2: (1, 18),
29: (4,11),
42: (5, 6),
58: (8, 5),
59: (8, 6),
57: (8, 4),
71: (8, 18),
72: (6, 4),
89: (9, 4),
90: (9, 5),
103: (9, 18),
}
for input, out in TESTS.items():
found = perta(input)
print('TEST:{:3d} -> '.format(input) + str(found) + (f' ; ERROR: expected {out}' if found != out else ''))