mapping: dict[int, list[int]] = {
0: [127, 136, 145, 190, 235, 280, 370, 389, 460, 479, 569, 578, 118, 226, 244, 299, 334, 488, 668, 677, 0, 550],
1: [128, 137, 146, 236, 245, 290, 380, 470, 489, 560, 678, 579, 119, 155, 227, 335, 344, 399, 588, 669, 100, 777],
2: [129, 138, 147, 156, 237, 246, 345, 390, 480, 570, 679, 589, 110, 228, 255, 336, 499, 660, 688, 778, 200, 444],
3: [120, 139, 148, 157, 238, 247, 256, 346, 490, 580, 670, 689, 166, 229, 337, 355, 445, 599, 779, 788, 300, 111],
4: [130, 149, 158, 167, 239, 248, 257, 347, 356, 590, 680, 789, 112, 220, 266, 338, 446, 455, 699, 770, 400, 888],
5: [140, 159, 168, 230, 249, 258, 267, 348, 357, 456, 690, 780, 113, 122, 177, 339, 366, 447, 799, 770, 500, 555],
6: [123, 150, 169, 178, 240, 259, 268, 349, 358, 457, 367, 790, 114, 277, 330, 448, 466, 556, 880, 899, 600, 222],
7: [124, 160, 179, 250, 269, 278, 340, 359, 368, 458, 467, 890, 115, 133, 188, 223, 377, 449, 557, 566, 700, 999],
8: [125, 134, 170, 189, 260, 279, 350, 369, 378, 459, 567, 468, 116, 224, 233, 288, 440, 477, 558, 990, 800, 666],
9: [126, 135, 180, 234, 270, 289, 360, 379, 450, 469, 117, 478, 568, 144, 199, 225, 388, 559, 577, 667, 900, 333],
}
msgs: list[str] = [
5,
"238-3X458-7",
"667-9X560-1",
"170-8X233-8",
"570-2X155-1"
]
def validate(msg: str) -> bool:
return all([
isinstance(msg, str),
len(msg) == 11,
msg[:3].isdigit(),
msg[4].isdigit(),
msg[6:9].isdigit(),
msg[10].isdigit(),
msg[3] == "-",
msg[5] == "X",
msg[9] == "-"
])
def search(num: int, mapping: dict[int, list[int]]) -> list[int]:
groups: list[int] = []
for i, values in enumerate(mapping.values()):
if num in values:
groups.append(i)
return groups
def prepare_data(msg: str) -> list[int]:
if not validate(msg):
raise ValueError(f"There is error in format of msg: {msg}")
return [int(num) for num in [msg[:3], msg[4], msg[6:9], msg[10]]]
def analysis(
msg: str, mapping: dict[int, list[int]]
) -> dict[int, list[int] | None]:
nums: list[int] = prepare_data(msg)
return {num: search(num, mapping) for num in nums}
def display(msg: str, mapping: dict[int, list[int]]) -> str:
analysed: str = ""
for num, group in analysis(msg, mapping).items():
group = [str(item) for item in group or ["None"]]
analysed += f" {num} -> group {', '.join(group)}.\n\n"
return f"Message {msg}\n\n{analysed}"
def display_all(msgs: list[str], mapping: dict[int, list[int]]) -> str:
return "\n".join([display(msg, mapping) for msg in msgs])
if __name__ == "__main__":
try:
print(display_all(msgs, mapping))
except Exception as e:
print(e)
bWFwcGluZzogZGljdFtpbnQsIGxpc3RbaW50XV0gPSB7CiAgICAwOiBbMTI3LCAxMzYsIDE0NSwgMTkwLCAyMzUsIDI4MCwgMzcwLCAzODksIDQ2MCwgNDc5LCA1NjksIDU3OCwgMTE4LCAyMjYsIDI0NCwgMjk5LCAzMzQsIDQ4OCwgNjY4LCA2NzcsIDAsIDU1MF0sCiAgICAxOiBbMTI4LCAxMzcsIDE0NiwgMjM2LCAyNDUsIDI5MCwgMzgwLCA0NzAsIDQ4OSwgNTYwLCA2NzgsIDU3OSwgMTE5LCAxNTUsIDIyNywgMzM1LCAzNDQsIDM5OSwgNTg4LCA2NjksIDEwMCwgNzc3XSwKICAgIDI6IFsxMjksIDEzOCwgMTQ3LCAxNTYsIDIzNywgMjQ2LCAzNDUsIDM5MCwgNDgwLCA1NzAsIDY3OSwgNTg5LCAxMTAsIDIyOCwgMjU1LCAzMzYsIDQ5OSwgNjYwLCA2ODgsIDc3OCwgMjAwLCA0NDRdLAogICAgMzogWzEyMCwgMTM5LCAxNDgsIDE1NywgMjM4LCAyNDcsIDI1NiwgMzQ2LCA0OTAsIDU4MCwgNjcwLCA2ODksIDE2NiwgMjI5LCAzMzcsIDM1NSwgNDQ1LCA1OTksIDc3OSwgNzg4LCAzMDAsIDExMV0sCiAgICA0OiBbMTMwLCAxNDksIDE1OCwgMTY3LCAyMzksIDI0OCwgMjU3LCAzNDcsIDM1NiwgNTkwLCA2ODAsIDc4OSwgMTEyLCAyMjAsIDI2NiwgMzM4LCA0NDYsIDQ1NSwgNjk5LCA3NzAsIDQwMCwgODg4XSwKICAgIDU6IFsxNDAsIDE1OSwgMTY4LCAyMzAsIDI0OSwgMjU4LCAyNjcsIDM0OCwgMzU3LCA0NTYsIDY5MCwgNzgwLCAxMTMsIDEyMiwgMTc3LCAzMzksIDM2NiwgNDQ3LCA3OTksIDc3MCwgNTAwLCA1NTVdLAogICAgNjogWzEyMywgMTUwLCAxNjksIDE3OCwgMjQwLCAyNTksIDI2OCwgMzQ5LCAzNTgsIDQ1NywgMzY3LCA3OTAsIDExNCwgMjc3LCAzMzAsIDQ0OCwgNDY2LCA1NTYsIDg4MCwgODk5LCA2MDAsIDIyMl0sCiAgICA3OiBbMTI0LCAxNjAsIDE3OSwgMjUwLCAyNjksIDI3OCwgMzQwLCAzNTksIDM2OCwgNDU4LCA0NjcsIDg5MCwgMTE1LCAxMzMsIDE4OCwgMjIzLCAzNzcsIDQ0OSwgNTU3LCA1NjYsIDcwMCwgOTk5XSwKICAgIDg6IFsxMjUsIDEzNCwgMTcwLCAxODksIDI2MCwgMjc5LCAzNTAsIDM2OSwgMzc4LCA0NTksIDU2NywgNDY4LCAxMTYsIDIyNCwgMjMzLCAyODgsIDQ0MCwgNDc3LCA1NTgsIDk5MCwgODAwLCA2NjZdLAogICAgOTogWzEyNiwgMTM1LCAxODAsIDIzNCwgMjcwLCAyODksIDM2MCwgMzc5LCA0NTAsIDQ2OSwgMTE3LCA0NzgsIDU2OCwgMTQ0LCAxOTksIDIyNSwgMzg4LCA1NTksIDU3NywgNjY3LCA5MDAsIDMzM10sCn0KCm1zZ3M6IGxpc3Rbc3RyXSA9IFsKICAgIDUsCiAgICAiMjM4LTNYNDU4LTciLAogICAgIjY2Ny05WDU2MC0xIiwKICAgICIxNzAtOFgyMzMtOCIsCiAgICAiNTcwLTJYMTU1LTEiCl0KCmRlZiB2YWxpZGF0ZShtc2c6IHN0cikgLT4gYm9vbDoKICAgIHJldHVybiBhbGwoWwogICAgICAgIGlzaW5zdGFuY2UobXNnLCBzdHIpLAogICAgICAgIGxlbihtc2cpID09IDExLAogICAgICAgIG1zZ1s6M10uaXNkaWdpdCgpLAogICAgICAgIG1zZ1s0XS5pc2RpZ2l0KCksCiAgICAgICAgbXNnWzY6OV0uaXNkaWdpdCgpLAogICAgICAgIG1zZ1sxMF0uaXNkaWdpdCgpLAogICAgICAgIG1zZ1szXSA9PSAiLSIsCiAgICAgICAgbXNnWzVdID09ICJYIiwKICAgICAgICBtc2dbOV0gPT0gIi0iCiAgICBdKQoKZGVmIHNlYXJjaChudW06IGludCwgbWFwcGluZzogZGljdFtpbnQsIGxpc3RbaW50XV0pIC0+IGxpc3RbaW50XToKICAgIGdyb3VwczogbGlzdFtpbnRdID0gW10KICAgIGZvciBpLCB2YWx1ZXMgaW4gZW51bWVyYXRlKG1hcHBpbmcudmFsdWVzKCkpOgogICAgICAgIGlmIG51bSBpbiB2YWx1ZXM6CiAgICAgICAgICAgIGdyb3Vwcy5hcHBlbmQoaSkKCiAgICByZXR1cm4gZ3JvdXBzCgoKZGVmIHByZXBhcmVfZGF0YShtc2c6IHN0cikgLT4gbGlzdFtpbnRdOgogICAgaWYgbm90IHZhbGlkYXRlKG1zZyk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihmIlRoZXJlIGlzIGVycm9yIGluIGZvcm1hdCBvZiBtc2c6IHttc2d9IikKICAgIHJldHVybiBbaW50KG51bSkgZm9yIG51bSBpbiBbbXNnWzozXSwgbXNnWzRdLCBtc2dbNjo5XSwgbXNnWzEwXV1dCgoKZGVmIGFuYWx5c2lzKAogICAgbXNnOiBzdHIsIG1hcHBpbmc6IGRpY3RbaW50LCBsaXN0W2ludF1dCikgLT4gZGljdFtpbnQsIGxpc3RbaW50XSB8IE5vbmVdOgogICAgbnVtczogbGlzdFtpbnRdID0gcHJlcGFyZV9kYXRhKG1zZykKCiAgICByZXR1cm4ge251bTogc2VhcmNoKG51bSwgbWFwcGluZykgZm9yIG51bSBpbiBudW1zfQoKCmRlZiBkaXNwbGF5KG1zZzogc3RyLCBtYXBwaW5nOiBkaWN0W2ludCwgbGlzdFtpbnRdXSkgLT4gc3RyOgogICAgYW5hbHlzZWQ6IHN0ciA9ICIiCgogICAgZm9yIG51bSwgZ3JvdXAgaW4gYW5hbHlzaXMobXNnLCBtYXBwaW5nKS5pdGVtcygpOgogICAgICAgIGdyb3VwID0gW3N0cihpdGVtKSBmb3IgaXRlbSBpbiBncm91cCBvciBbIk5vbmUiXV0KICAgICAgICBhbmFseXNlZCArPSBmIiAge251bX0gLT4gZ3JvdXAgeycsICcuam9pbihncm91cCl9LlxuXG4iCgogICAgcmV0dXJuICBmIk1lc3NhZ2Uge21zZ31cblxue2FuYWx5c2VkfSIKCgpkZWYgZGlzcGxheV9hbGwobXNnczogbGlzdFtzdHJdLCBtYXBwaW5nOiBkaWN0W2ludCwgbGlzdFtpbnRdXSkgLT4gc3RyOgogICAgcmV0dXJuICJcbiIuam9pbihbZGlzcGxheShtc2csIG1hcHBpbmcpIGZvciBtc2cgaW4gbXNnc10pCgoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKCXRyeToKCSAgICBwcmludChkaXNwbGF5X2FsbChtc2dzLCBtYXBwaW5nKSkKCWV4Y2VwdCBFeGNlcHRpb24gYXMgZToKCQlwcmludChlKQ==