📜 ⬆️ ⬇️

How I saved Mars or a small quest on python

Hello World!

August 2018


On the street there is a hot summer, smoothly coming to an end, and I sit in a cool room with a laptop and surf the Internet in search of interesting things. Having lost hope of finding anything worthwhile, I suddenly stumble into one of the quite popular around-the-VKontakte groups with a link to another IT resource. The quest seemed interesting to me, because it is almost a classic text quest in the space setting, and you also need to program here!


')
Therefore, this article will discuss how I played decided this quest.

Under the link we are waiting for an introduction to the quest with the following text:

2022 . - KASP 120 .

, . , - KASP . — .


After selecting the language - C ++, C # and Python are available, we are waiting for a page with a “message from the MCC”, which is a set of characters in a specific encoding. To go to the next stage, you need to decode the message by sorting the message pieces in order of increasing the length of the message and enter the md5-hash of the received message.
But what sort, you say? The fact that this message is a kind of encoding becomes clear immediately, which one can be easily understood using a similar resource , for example.

Realizing that this is base64 , we begin to decode it. I did this in python :

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

After the output, it becomes clear that the data is in JSON format:

Such a Jason get:
[{"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"}]


In each element of the array there is a parameter “id” - this is a sequence number, according to which we will sort the message pieces. Let's complicate our code:

Previous code with enhancements:
 import base64 import json import hashlib code = """W=""" 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()) 


As a result, we get the message and md5-hash of the message:

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


Attached is a file with data on colonists in the following format:

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


The format is: ID; Profession; Gender (female = 0, male = 1); Sustainability Rating

It is proposed to recruit 40 of 120 colonists who meet the following criteria:

  1. In the colony there should be 1 manager, 3 cooks, 4 electricians, 5 programmers, 5 doctors, 8 mechanics and 14 scientists.
  2. Colonies will exist for more than one year, therefore, at least 51% of the inhabitants must be women. But at least 30% of the colonists must be males.
  3. Living in a colony is not so easy and fun, so you need to select only candidates whose sustainability rating is 60 or more units on a scale from 1 to 100.

And now we proceed to the selection of colonists!

Selecting ...
 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) 


The form on the site accepts the code and automatically tests it. The data is fed from the standard input stream, for the same reason, it is necessary to read them from there, which makes it a bit difficult to test the code when writing.

January 2019


I wanted to share with you this, rather interesting, experience, participation in similar quests. For me, he was the first. It seems to me that the idea is interesting even without a competitive basis. Personally, I have solved 5 tasks of different types. The rest I attach by reference to github.

And also, as a reward, at the end a rating table with your time falls out. For me, the best result was this:



The result is a symbolic 50 place out of more than 400+ participants.

What can you say about this? For me it was a fascinating time spent programming. By the way, tasks are still available for those who want to solve them, despite the fact that the competition has long been completed.

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


All Articles