Como eu salvei Marte ou uma pequena missão python

Olá Mundo!

Agosto 2018


É um verão quente lá fora, terminando sem problemas, e eu estou sentado em uma sala fria com um laptop e navegando na Internet em busca de coisas interessantes. Tendo perdido a esperança de encontrar algo digno de atenção, de repente tropeço em um dos grupos bastante silenciosos do VKontakte, bastante populares, com um link para outro recurso de TI. A busca me pareceu interessante, porque é quase uma busca de texto clássica em um espaço, e você precisa programar aqui!



Portanto, neste artigo, falaremos sobre como eu joguei resolvido essa missão.

O link nos espera com uma introdução à missão com o seguinte texto:

2022 . - KASP 120 .

, . , - KASP . — .


Depois de escolher o idioma - C ++, C # e Python estão disponíveis, aguardamos uma página com uma "mensagem da MCC", que é um conjunto de caracteres em uma determinada codificação. Para ir para o próximo estágio, é necessário decodificar a mensagem, classificando as partes da mensagem para aumentar o tamanho da mensagem e inserir o hash md5 da mensagem recebida.
Mas que tipo, você diz? O fato de esta mensagem ser uma certa codificação torna-se imediatamente claro, qual pode ser facilmente entendido usando um recurso semelhante, por exemplo.

Tendo entendido que é base64 , começamos a decodificá-lo. Eu fiz isso em python :

Decodifique base64:
 import base64 code = """=""" def base64ToString(b): return base64.b64decode(b).decode('utf-8') decodedJSON = base64ToString(code) print(decodedJSON) 

Após a saída, fica claro que os dados são apresentados no formato JSON:

Tal jason temos:
[{"id":31,"s":"ony: 1 man"},{"id":27,"s":"de all spe"},{"id":61,"s":"s will fac"},{"id":55,"s":"out men, a"},{"id":42,"s":"ntists.\n2."},{"id":18,"s":"n. Our soc"},{"id":70,"s":"the planet"},{"id":5,"s":". One oper"},{"id":64,"s":" condition"},{"id":44,"s":"y have to "},{"id":49,"s":"st 51% of "},{"id":58,"s":"ists must "},{"id":71,"s":". Select p"},{"id":59,"s":"be male.\n3"},{"id":85,"s":"he followi"},{"id":43,"s":" The colon"},{"id":73,"s":" resilienc"},{"id":24,"s":"selection."},{"id":62,"s":"e all kind"},{"id":47,"s":"nerations,"},{"id":105,"s":"eople who "},{"id":103,"s":"rmation, s"},{"id":22,"s":"ias to sim"},{"id":86,"s":"ng format:"},{"id":2,"s":"p's lander"},{"id":36,"s":" computer "},{"id":48,"s":" so at lea"},{"id":16,"s":"for Mars c"},{"id":75,"s":"0 and more"},{"id":11,"s":". You have"},{"id":95,"s":"emale = 0,"},{"id":68,"s":"ple should"},{"id":41,"s":"s, 14 scie"},{"id":7,"s":", but is u"},{"id":98,"s":"e rating\ne"},{"id":0,"s":"Two of the"},{"id":101,"s":".\n\nKnowing"},{"id":33,"s":"oks, 4 ele"},{"id":97,"s":";Resilienc"},{"id":51,"s":"olonists m"},{"id":108,"s":"d Planet."},{"id":100,"s":"break - \\n"},{"id":60,"s":". Colonist"},{"id":40,"s":"8 mechanic"},{"id":78,"s":"100.\n\nThe "},{"id":1,"s":" three shi"},{"id":13,"s":"0 most app"},{"id":12,"s":" to pick 4"},{"id":93,"s":"ID;Profess"},{"id":104,"s":"elect 40 p"},{"id":39,"s":"5 medics, "},{"id":8,"s":"nable to c"},{"id":52,"s":"ust be fem"},{"id":96,"s":" male = 1)"},{"id":89,"s":"female = 0"},{"id":10,"s":" colonists"},{"id":65,"s":"s. Only th"},{"id":35,"s":"gineers, 5"},{"id":21,"s":"ree criter"},{"id":17,"s":"olonisatio"},{"id":54,"s":" forget ab"},{"id":15,"s":"andidates "},{"id":87,"s":" ID;Profes"},{"id":37,"s":"system spe"},{"id":79,"s":"file attac"},{"id":90,"s":", male = 1"},{"id":29,"s":"ssential f"},{"id":107,"s":"ize the Re"},{"id":6,"s":"ates fully"},{"id":66,"s":"e most res"},{"id":32,"s":"ager, 3 co"},{"id":63,"s":"s of harsh"},{"id":4,"s":"unctioning"},{"id":82,"s":"tains a li"},{"id":38,"s":"cialists, "},{"id":74,"s":"e rating 6"},{"id":77,"s":"from 1 to "},{"id":19,"s":"iologists "},{"id":3,"s":"s are malf"},{"id":53,"s":"ale. Don't"},{"id":23,"s":"plify the "},{"id":28,"s":"cialists e"},{"id":88,"s":"sion;Sex ("},{"id":94,"s":"ion;Sex (f"},{"id":106,"s":"will colon"},{"id":25,"s":"\n\n1. Crew "},{"id":102,"s":" this info"},{"id":91,"s":");Resilien"},{"id":81,"s":"s task con"},{"id":57,"s":"% of colon"},{"id":76,"s":" on scale "},{"id":30,"s":"or the col"},{"id":80,"s":"hed to thi"},{"id":14,"s":"ropriate c"},{"id":72,"s":"eople with"},{"id":69,"s":" colonize "},{"id":9,"s":"ontain 120"},{"id":20,"s":"defined th"},{"id":67,"s":"ilient peo"},{"id":50,"s":"selected c"},{"id":99,"s":"tc. \nLine "},{"id":83,"s":"st of colo"},{"id":56,"s":"t least 30"},{"id":84,"s":"nists in t"},{"id":34,"s":"ctrical en"},{"id":45,"s":"exist for "},{"id":92,"s":"ce rating\n"},{"id":26,"s":"must inclu"},{"id":46,"s":"several ge"}]


Em cada elemento da matriz, há um parâmetro "id" - este é um número de série, e classificaremos as mensagens por ele. Vamos complicar nosso código:

Código anterior com aprimoramentos:
 import base64 import json import hashlib code = """=""" def base64ToString(b): return base64.b64decode(b).decode('utf-8') def sortbylen(sortlist): return sortlist[ids] decodedJSON = base64ToString(code) print(decodedJSON) sortString = json.loads(decodedJSON) sortList = list() for item in sortString: sortList.append(item) elem = sortList[0] ids = list(elem.keys())[0] messages = list(elem.keys())[1] sortList.sort(key=sortbylen) finallyDecodedString = '' for item in sortList: finallyDecodedString = finallyDecodedString + '' + str(item[messages]) print(finallyDecodedString + '\n') print('Md5 hash: ' + hashlib.md5(finallyDecodedString.encode('utf-8')).hexdigest()) 


Como resultado, obtemos a mensagem e o hash md5 da mensagem:

Two of the three ship's landers are malfunctioning. One operates fully, but is unable to contain 120 colonists. You have to pick 40 most appropriate candidates for Mars colonisation. Our sociologists defined three criterias to simplify the selection.

1. Crew must include all specialists essential for the colony: 1 manager, 3 cooks, 4 electrical engineers, 5 computer system specialists, 5 medics, 8 mechanics, 14 scientists.
2. The colony have to exist for several generations, so at least 51% of selected colonists must be female. Don't forget about men, at least 30% of colonists must be male.
3. Colonists will face all kinds of harsh conditions. Only the most resilient people should colonize the planet. Select people with resilience rating 60 and more on scale from 1 to 100.

The file attached to this task contains a list of colonists in the following format: ID;Profession;Sex (female = 0, male = 1);Resilience rating
ID;Profession;Sex (female = 0, male = 1);Resilience rating
etc.
Line break - \n.

Knowing this information, select 40 people who will colonize the Red Planet.

Md5 hash: 88f57ef56978a95f044183951eabef3b


A mensagem é acompanhada por um arquivo com informações sobre os colonos no seguinte formato:

1;electrical engineer;0;90
2;mechanic;0;77
3;scientist;1;71


O formato é: ID; Profissão; Sexo (mulher = 0, homem = 1); Classificação de sustentabilidade

Propõe-se que de 120 colonos, seja atingida uma pontuação de 40 que atenda aos seguintes critérios:

  1. A colônia deve ter 1 gerente, 3 cozinheiros, 4 eletricistas, 5 cientistas da computação, 5 médicos, 8 mecânicos e 14 cientistas.
  2. As colônias terão que existir por mais de um ano; portanto, pelo menos 51% da população deve ser mulher. Mas pelo menos 30% dos colonos devem ser do sexo masculino.
  3. Viver em uma colônia não é tão fácil e divertido, então você só precisa selecionar candidatos cuja classificação de sustentabilidade seja 60 ou mais unidades em uma escala de 1 a 100.

E agora procedemos à seleção de colonos!

Nós selecionamos ...
 import random import math import sys colonists_list = list() new_colonists_list_male = list() new_colonists_list_female = list() manager_fem_list = list() manager_mal_list = list() cook_fem_list = list() cook_mal_list = list() elen_fem_list = list() elen_mal_list = list() compspec_fem_list = list() compspec_mal_list = list() doc_fem_list = list() doc_mal_list = list() mech_fem_list = list() mech_mal_list = list() sci_fem_list = list() sci_mal_list = list() lucky_colonists = list() luck_list = [random.randint(0, 100) for i in range(100)] managers = 1 cooks = 3 electrical_engineers = 4 computer_system_specialists = 5 medics = 5 mechanics = 8 scientists = 14 def pick_percentage(low, high): return random.randint(low, high)/100 perc_male = pick_percentage(30, 49) perc_female = pick_percentage(51, 69) quantity_required = 40 quantity_of_women_required = math.ceil(quantity_required * perc_female) min_percentage_fem = quantity_of_women_required/quantity_required quantity_of_men_required = quantity_required * perc_male min_percentage_mal = quantity_of_men_required/quantity_required unsorted_list = list() while 1: try: line = input() except EOFError: break unsorted_list.append(line) sorted_list = list() for i in unsorted_list: sorted_list.append(i.split(';')) #    for item in sorted_list: if int(item[3]) >= 60: colonists_list.append(item) counter = 0 conditions = "1. Crew must include all specialists essential for the colony: 1 manager, 3 cooks," \ " 4 electrical engineers, 5 computer system specialists, 5 medics, 8 mechanics, 14 " \ "scientists. 2. The colony have to exist for several generations, so at least 51% " \ "of selected colonists must be female. Don't forget about men, at least 30% of colonists must be male."\ "3. Colonists will face all kinds of harsh conditions. Only the most resilient people should colonize " \ "the planet. Select people with resilience rating 60 and more on scale from 1 to 100." #   for item in colonists_list: if int(item[2]) == 0: new_colonists_list_female.append(item) #   for item in colonists_list: if int(item[2]) == 1: new_colonists_list_male.append(item) #     for item in new_colonists_list_female: if item[1] == 'manager': manager_fem_list.append(item) if item[1] == 'cook': cook_fem_list.append(item) if item[1] == 'electrical engineer': elen_fem_list.append(item) if item[1] == 'computers specialist': compspec_fem_list.append(item) if item[1] == 'doctor': doc_fem_list.append(item) if item[1] == 'mechanic': mech_fem_list.append(item) if item[1] == 'scientist': sci_fem_list.append(item) #     for item in new_colonists_list_male: if item[1] == 'manager': manager_mal_list.append(item) if item[1] == 'cook': cook_mal_list.append(item) if item[1] == 'electrical engineer': elen_mal_list.append(item) if item[1] == 'computers specialist': compspec_mal_list.append(item) if item[1] == 'doctor': doc_mal_list.append(item) if item[1] == 'mechanic': mech_mal_list.append(item) if item[1] == 'scientist': sci_mal_list.append(item) #   def percentage_is_ok(colonists): female_quantity = 0 female_is_ok = 1 male_is_ok = 1 for i in colonists: if int(i[2]) == 0: female_quantity = female_quantity + 1 percentage_female = female_quantity/int(len(colonists)) percentage_male = 1 - percentage_female if percentage_female < min_percentage_fem: female_is_ok = 0 elif percentage_male < min_percentage_mal: male_is_ok = 0 return [female_is_ok, male_is_ok, percentage_female, percentage_male, female_quantity] def choose_colonists(female, male, quantity, resulting_list): for i in range(quantity): if int(percentage_is_ok(resulting_list)[0]) == 0 and len(female) > 0: colonist_choice = random.choice(female) resulting_list.append(colonist_choice) female.remove(colonist_choice) elif int(percentage_is_ok(resulting_list)[1]) == 0 and len(male) > 0: colonist_choice = random.choice(male) resulting_list.append(colonist_choice) male.remove(colonist_choice) else: if len(male) > 0 and len(female) > 0: sex_choice = random.choice([female, male]) colonist_choice = random.choice(sex_choice) resulting_list.append(colonist_choice) sex_choice.remove(colonist_choice) else: if len(male) == 0: colonist_choice = random.choice(female) resulting_list.append(colonist_choice) sex_choice.remove(colonist_choice) elif len(female) == 0: colonist_choice = random.choice(male) resulting_list.append(colonist_choice) sex_choice.remove(colonist_choice) #  if int(random.choice(luck_list)) >= 50: choice = random.choice(manager_fem_list) lucky_colonists.append(choice) else: choice = random.choice(manager_mal_list) lucky_colonists.append(choice) #  choose_colonists(cook_fem_list, cook_mal_list, cooks, lucky_colonists) #  choose_colonists(elen_fem_list, elen_mal_list, electrical_engineers, lucky_colonists) #   choose_colonists(compspec_fem_list, compspec_mal_list, computer_system_specialists, lucky_colonists) #  -   doctors_left = 1 for i in range(medics): if int(percentage_is_ok(lucky_colonists)[0]) == 0: choice = random.choice(doc_fem_list) lucky_colonists.append(choice) doc_fem_list.remove(choice) elif doctors_left > 0: choice = random.choice(doc_mal_list) lucky_colonists.append(choice) doc_mal_list.remove(choice) doctors_left = 0 else: choice = random.choice(doc_fem_list) lucky_colonists.append(choice) doc_fem_list.remove(choice) #  -   mechanics_male_left = 6 for i in range(mechanics): if int(percentage_is_ok(lucky_colonists)[0]) == 0: choice = random.choice(mech_fem_list) lucky_colonists.append(choice) mech_fem_list.remove(choice) elif mechanics_male_left > 0: choice = random.choice(mech_mal_list) lucky_colonists.append(choice) mech_mal_list.remove(choice) mechanics_male_left = mechanics_male_left - 1 else: choice = random.choice(mech_fem_list) lucky_colonists.append(choice) #  choose_colonists(sci_fem_list, sci_mal_list, scientists, lucky_colonists) colonists_string = '' for item in lucky_colonists: colonists_string = colonists_string + item[0] + ';' colonists_string = colonists_string[0:len(colonists_string)-1] # sys.stdout.write(colonists_string) 


O formulário no site pega o código e o testa automaticamente. Os dados são fornecidos a partir do fluxo de entrada padrão, pelo mesmo motivo, você deve lê-los a partir daí, o que complica um pouco o teste de código durante a gravação.

Janeiro 2019


Eu queria compartilhar com você essa experiência bastante interessante de participar de tais missões. Para mim, ele foi o primeiro. Parece-me que a ideia é interessante mesmo sem uma base competitiva. Pessoalmente, resolvi 5 tarefas de vários tipos. Coloquei o resto no link para o github.

E também, como recompensa, no final, há uma tabela de classificação com o seu tempo. Para mim, o melhor resultado foi este:



O resultado, um 50º lugar simbólico entre mais de 400 participantes.

O que se pode dizer sobre isso? Para mim, foi um tempo emocionante gasto em programação. A propósito, as tarefas ainda estão disponíveis para aqueles que desejam resolvê-las, apesar do fato de a competição ter sido concluída há muito tempo.

Source: https://habr.com/ru/post/pt435286/


All Articles