Привет, Мир!
На улице стоит жаркое лето, плавно подходящее к концу, а я сижу в прохладной комнате с ноутбуком и серфлю интернет в поиске интересных вещей. Потеряв надежду найти что-либо стоящее внимания, вдруг, натыкаюсь в одной из довольно популярных околоайтишных групп вконтакте пост со ссылкой на еще один айти ресурс. Квест показался мне интересным, ведь это почти классический текстовый квест в космическом сеттинге, да еще и программировать тут нужно!
Поэтому в этой статье речь пойдет о том, как яиграл решал этот квест.
По ссылке нас ждет введение в квест следующим текстом:
После выбора языка – доступны C++, C# и Python, нас ждет страница с «сообщением от ЦУПа», которое представляет собой набор символов в определенной кодировке. Чтобы пройти на следующий этап нужно декодировать сообщение, отсортировав куски сообщения в порядке увеличения длины сообщения и ввести md5-хэш полученного сообщения.
Но что сортировать, скажете вы? То, что это сообщение представляет собой некую кодировку становится понятно сразу, какую именно можно легко понять, воспользовавшись похожим ресурсом, например.
Поняв, что это base64, начинаем его декодировать. Я сделал это на python'е:
После вывода становится понятно, что данные представлены в формате JSON:
В каждом элементе массива есть параметр «id» — это порядковый номер, по нему и будем сортировать кусочки сообщения. Усложним наш код:
В итоге, получим сообщение и md5-хэш сообщения:
К сообщению прилагается файл с данными о колонистах в следующем формате:
Формат такой: ID; Профессия; Пол(женщина = 0, мужчина = 1); Рейтинг устойчивости
Предлагается из 120 колонистов набрать 40, удовлетворяющих следующим критериям:
А теперь приступим к отбору колонистов!
Форма на сайте принимает код и автоматически его тестирует. Данные подаются из потока стандартного ввода, по этой же причине, приходится их считывать оттуда, что немного усложняет тестирование кода при написании.
Хотел поделиться с вами этим, довольно интересным, опытом, участия в подобных квестах. Для меня он оказался первым. Мне кажется, идея интересная даже без конкурсной основы. Лично я нарешал штук 5 задач разных типов. Остальные прикладываю по ссылке на github.
А еще, в качестве вознаграждения, в конце выпадает рейтинговая таблица с вашим временем. Для меня лучший результат оказался таким:
Итог, символическое 50 место из более 400+ участников.
Что можно об этом сказать? Для меня это было увлекательно проведенное за программированием время. Кстати задания все еще доступны для желающих их порешать, несмотря на то, что конкурс давно завершен.
Август 2018
На улице стоит жаркое лето, плавно подходящее к концу, а я сижу в прохладной комнате с ноутбуком и серфлю интернет в поиске интересных вещей. Потеряв надежду найти что-либо стоящее внимания, вдруг, натыкаюсь в одной из довольно популярных околоайтишных групп вконтакте пост со ссылкой на еще один айти ресурс. Квест показался мне интересным, ведь это почти классический текстовый квест в космическом сеттинге, да еще и программировать тут нужно!
Поэтому в этой статье речь пойдет о том, как я
По ссылке нас ждет введение в квест следующим текстом:
2022 год. Ракета-носитель KASP со 120 колонистами на борту и электромобилем с открытым верхом приближается к Марсу.
Перед началом посадки выясняется, что одна из систем корабля неисправна. Центр управления полётами пытается передать инструкции экипажу, но из-за солнечной бури сообщение приходит на KASP беспорядочными фрагментами. От вас зависит судьба миссии — расшифруйте сообщение и следуйте инструкциям ЦУП.
После выбора языка – доступны C++, C# и Python, нас ждет страница с «сообщением от ЦУПа», которое представляет собой набор символов в определенной кодировке. Чтобы пройти на следующий этап нужно декодировать сообщение, отсортировав куски сообщения в порядке увеличения длины сообщения и ввести md5-хэш полученного сообщения.
Но что сортировать, скажете вы? То, что это сообщение представляет собой некую кодировку становится понятно сразу, какую именно можно легко понять, воспользовавшись похожим ресурсом, например.
Поняв, что это base64, начинаем его декодировать. Я сделал это на python'е:
Декодируем base64:
import base64
code = """W3siaWQiOjMxLCJzIjoib255OiAxIG1hbiJ9LHsiaWQiOjI3LCJzIjoiZGUgYWxsIHNwZSJ9LHsiaWQiOjYxLCJzIjoicyB3aWxsIGZhYyJ9LHsiaWQiOjU1LCJzIjoib3V0IG1lbiwgYSJ9LHsiaWQiOjQyLCJzIjoibnRpc3RzLlxuMi4ifSx7ImlkIjoxOCwicyI6Im4uIE91ciBzb2MifSx7ImlkIjo3MCwicyI6InRoZSBwbGFuZXQifSx7ImlkIjo1LCJzIjoiLiBPbmUgb3BlciJ9LHsiaWQiOjY0LCJzIjoiIGNvbmRpdGlvbiJ9LHsiaWQiOjQ0LCJzIjoieSBoYXZlIHRvICJ9LHsiaWQiOjQ5LCJzIjoic3QgNTElIG9mICJ9LHsiaWQiOjU4LCJzIjoiaXN0cyBtdXN0ICJ9LHsiaWQiOjcxLCJzIjoiLiBTZWxlY3QgcCJ9LHsiaWQiOjU5LCJzIjoiYmUgbWFsZS5cbjMifSx7ImlkIjo4NSwicyI6ImhlIGZvbGxvd2kifSx7ImlkIjo0MywicyI6IiBUaGUgY29sb24ifSx7ImlkIjo3MywicyI6IiByZXNpbGllbmMifSx7ImlkIjoyNCwicyI6InNlbGVjdGlvbi4ifSx7ImlkIjo2MiwicyI6ImUgYWxsIGtpbmQifSx7ImlkIjo0NywicyI6Im5lcmF0aW9ucywifSx7ImlkIjoxMDUsInMiOiJlb3BsZSB3aG8gIn0seyJpZCI6MTAzLCJzIjoicm1hdGlvbiwgcyJ9LHsiaWQiOjIyLCJzIjoiaWFzIHRvIHNpbSJ9LHsiaWQiOjg2LCJzIjoibmcgZm9ybWF0OiJ9LHsiaWQiOjIsInMiOiJwJ3MgbGFuZGVyIn0seyJpZCI6MzYsInMiOiIgY29tcHV0ZXIgIn0seyJpZCI6NDgsInMiOiIgc28gYXQgbGVhIn0seyJpZCI6MTYsInMiOiJmb3IgTWFycyBjIn0seyJpZCI6NzUsInMiOiIwIGFuZCBtb3JlIn0seyJpZCI6MTEsInMiOiIuIFlvdSBoYXZlIn0seyJpZCI6OTUsInMiOiJlbWFsZSA9IDAsIn0seyJpZCI6NjgsInMiOiJwbGUgc2hvdWxkIn0seyJpZCI6NDEsInMiOiJzLCAxNCBzY2llIn0seyJpZCI6NywicyI6IiwgYnV0IGlzIHUifSx7ImlkIjo5OCwicyI6ImUgcmF0aW5nXG5lIn0seyJpZCI6MCwicyI6IlR3byBvZiB0aGUifSx7ImlkIjoxMDEsInMiOiIuXG5cbktub3dpbmcifSx7ImlkIjozMywicyI6Im9rcywgNCBlbGUifSx7ImlkIjo5NywicyI6IjtSZXNpbGllbmMifSx7ImlkIjo1MSwicyI6Im9sb25pc3RzIG0ifSx7ImlkIjoxMDgsInMiOiJkIFBsYW5ldC4ifSx7ImlkIjoxMDAsInMiOiJicmVhayAtIFxcbiJ9LHsiaWQiOjYwLCJzIjoiLiBDb2xvbmlzdCJ9LHsiaWQiOjQwLCJzIjoiOCBtZWNoYW5pYyJ9LHsiaWQiOjc4LCJzIjoiMTAwLlxuXG5UaGUgIn0seyJpZCI6MSwicyI6IiB0aHJlZSBzaGkifSx7ImlkIjoxMywicyI6IjAgbW9zdCBhcHAifSx7ImlkIjoxMiwicyI6IiB0byBwaWNrIDQifSx7ImlkIjo5MywicyI6IklEO1Byb2Zlc3MifSx7ImlkIjoxMDQsInMiOiJlbGVjdCA0MCBwIn0seyJpZCI6MzksInMiOiI1IG1lZGljcywgIn0seyJpZCI6OCwicyI6Im5hYmxlIHRvIGMifSx7ImlkIjo1MiwicyI6InVzdCBiZSBmZW0ifSx7ImlkIjo5NiwicyI6IiBtYWxlID0gMSkifSx7ImlkIjo4OSwicyI6ImZlbWFsZSA9IDAifSx7ImlkIjoxMCwicyI6IiBjb2xvbmlzdHMifSx7ImlkIjo2NSwicyI6InMuIE9ubHkgdGgifSx7ImlkIjozNSwicyI6ImdpbmVlcnMsIDUifSx7ImlkIjoyMSwicyI6InJlZSBjcml0ZXIifSx7ImlkIjoxNywicyI6Im9sb25pc2F0aW8ifSx7ImlkIjo1NCwicyI6IiBmb3JnZXQgYWIifSx7ImlkIjoxNSwicyI6ImFuZGlkYXRlcyAifSx7ImlkIjo4NywicyI6IiBJRDtQcm9mZXMifSx7ImlkIjozNywicyI6InN5c3RlbSBzcGUifSx7ImlkIjo3OSwicyI6ImZpbGUgYXR0YWMifSx7ImlkIjo5MCwicyI6IiwgbWFsZSA9IDEifSx7ImlkIjoyOSwicyI6InNzZW50aWFsIGYifSx7ImlkIjoxMDcsInMiOiJpemUgdGhlIFJlIn0seyJpZCI6NiwicyI6ImF0ZXMgZnVsbHkifSx7ImlkIjo2NiwicyI6ImUgbW9zdCByZXMifSx7ImlkIjozMiwicyI6ImFnZXIsIDMgY28ifSx7ImlkIjo2MywicyI6InMgb2YgaGFyc2gifSx7ImlkIjo0LCJzIjoidW5jdGlvbmluZyJ9LHsiaWQiOjgyLCJzIjoidGFpbnMgYSBsaSJ9LHsiaWQiOjM4LCJzIjoiY2lhbGlzdHMsICJ9LHsiaWQiOjc0LCJzIjoiZSByYXRpbmcgNiJ9LHsiaWQiOjc3LCJzIjoiZnJvbSAxIHRvICJ9LHsiaWQiOjE5LCJzIjoiaW9sb2dpc3RzICJ9LHsiaWQiOjMsInMiOiJzIGFyZSBtYWxmIn0seyJpZCI6NTMsInMiOiJhbGUuIERvbid0In0seyJpZCI6MjMsInMiOiJwbGlmeSB0aGUgIn0seyJpZCI6MjgsInMiOiJjaWFsaXN0cyBlIn0seyJpZCI6ODgsInMiOiJzaW9uO1NleCAoIn0seyJpZCI6OTQsInMiOiJpb247U2V4IChmIn0seyJpZCI6MTA2LCJzIjoid2lsbCBjb2xvbiJ9LHsiaWQiOjI1LCJzIjoiXG5cbjEuIENyZXcgIn0seyJpZCI6MTAyLCJzIjoiIHRoaXMgaW5mbyJ9LHsiaWQiOjkxLCJzIjoiKTtSZXNpbGllbiJ9LHsiaWQiOjgxLCJzIjoicyB0YXNrIGNvbiJ9LHsiaWQiOjU3LCJzIjoiJSBvZiBjb2xvbiJ9LHsiaWQiOjc2LCJzIjoiIG9uIHNjYWxlICJ9LHsiaWQiOjMwLCJzIjoib3IgdGhlIGNvbCJ9LHsiaWQiOjgwLCJzIjoiaGVkIHRvIHRoaSJ9LHsiaWQiOjE0LCJzIjoicm9wcmlhdGUgYyJ9LHsiaWQiOjcyLCJzIjoiZW9wbGUgd2l0aCJ9LHsiaWQiOjY5LCJzIjoiIGNvbG9uaXplICJ9LHsiaWQiOjksInMiOiJvbnRhaW4gMTIwIn0seyJpZCI6MjAsInMiOiJkZWZpbmVkIHRoIn0seyJpZCI6NjcsInMiOiJpbGllbnQgcGVvIn0seyJpZCI6NTAsInMiOiJzZWxlY3RlZCBjIn0seyJpZCI6OTksInMiOiJ0Yy4gXG5MaW5lICJ9LHsiaWQiOjgzLCJzIjoic3Qgb2YgY29sbyJ9LHsiaWQiOjU2LCJzIjoidCBsZWFzdCAzMCJ9LHsiaWQiOjg0LCJzIjoibmlzdHMgaW4gdCJ9LHsiaWQiOjM0LCJzIjoiY3RyaWNhbCBlbiJ9LHsiaWQiOjQ1LCJzIjoiZXhpc3QgZm9yICJ9LHsiaWQiOjkyLCJzIjoiY2UgcmF0aW5nXG4ifSx7ImlkIjoyNiwicyI6Im11c3QgaW5jbHUifSx7ImlkIjo0NiwicyI6InNldmVyYWwgZ2UifV0="""
def base64ToString(b):
return base64.b64decode(b).decode('utf-8')
decodedJSON = base64ToString(code)
print(decodedJSON)
После вывода становится понятно, что данные представлены в формате JSON:
Такой джейсон получаем:
[{"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"}]
В каждом элементе массива есть параметр «id» — это порядковый номер, по нему и будем сортировать кусочки сообщения. Усложним наш код:
Предыдыщий код с усовершенствованиями:
import base64
import json
import hashlib
code = """W3siaWQiOjMxLCJzIjoib255OiAxIG1hbiJ9LHsiaWQiOjI3LCJzIjoiZGUgYWxsIHNwZSJ9LHsiaWQiOjYxLCJzIjoicyB3aWxsIGZhYyJ9LHsiaWQiOjU1LCJzIjoib3V0IG1lbiwgYSJ9LHsiaWQiOjQyLCJzIjoibnRpc3RzLlxuMi4ifSx7ImlkIjoxOCwicyI6Im4uIE91ciBzb2MifSx7ImlkIjo3MCwicyI6InRoZSBwbGFuZXQifSx7ImlkIjo1LCJzIjoiLiBPbmUgb3BlciJ9LHsiaWQiOjY0LCJzIjoiIGNvbmRpdGlvbiJ9LHsiaWQiOjQ0LCJzIjoieSBoYXZlIHRvICJ9LHsiaWQiOjQ5LCJzIjoic3QgNTElIG9mICJ9LHsiaWQiOjU4LCJzIjoiaXN0cyBtdXN0ICJ9LHsiaWQiOjcxLCJzIjoiLiBTZWxlY3QgcCJ9LHsiaWQiOjU5LCJzIjoiYmUgbWFsZS5cbjMifSx7ImlkIjo4NSwicyI6ImhlIGZvbGxvd2kifSx7ImlkIjo0MywicyI6IiBUaGUgY29sb24ifSx7ImlkIjo3MywicyI6IiByZXNpbGllbmMifSx7ImlkIjoyNCwicyI6InNlbGVjdGlvbi4ifSx7ImlkIjo2MiwicyI6ImUgYWxsIGtpbmQifSx7ImlkIjo0NywicyI6Im5lcmF0aW9ucywifSx7ImlkIjoxMDUsInMiOiJlb3BsZSB3aG8gIn0seyJpZCI6MTAzLCJzIjoicm1hdGlvbiwgcyJ9LHsiaWQiOjIyLCJzIjoiaWFzIHRvIHNpbSJ9LHsiaWQiOjg2LCJzIjoibmcgZm9ybWF0OiJ9LHsiaWQiOjIsInMiOiJwJ3MgbGFuZGVyIn0seyJpZCI6MzYsInMiOiIgY29tcHV0ZXIgIn0seyJpZCI6NDgsInMiOiIgc28gYXQgbGVhIn0seyJpZCI6MTYsInMiOiJmb3IgTWFycyBjIn0seyJpZCI6NzUsInMiOiIwIGFuZCBtb3JlIn0seyJpZCI6MTEsInMiOiIuIFlvdSBoYXZlIn0seyJpZCI6OTUsInMiOiJlbWFsZSA9IDAsIn0seyJpZCI6NjgsInMiOiJwbGUgc2hvdWxkIn0seyJpZCI6NDEsInMiOiJzLCAxNCBzY2llIn0seyJpZCI6NywicyI6IiwgYnV0IGlzIHUifSx7ImlkIjo5OCwicyI6ImUgcmF0aW5nXG5lIn0seyJpZCI6MCwicyI6IlR3byBvZiB0aGUifSx7ImlkIjoxMDEsInMiOiIuXG5cbktub3dpbmcifSx7ImlkIjozMywicyI6Im9rcywgNCBlbGUifSx7ImlkIjo5NywicyI6IjtSZXNpbGllbmMifSx7ImlkIjo1MSwicyI6Im9sb25pc3RzIG0ifSx7ImlkIjoxMDgsInMiOiJkIFBsYW5ldC4ifSx7ImlkIjoxMDAsInMiOiJicmVhayAtIFxcbiJ9LHsiaWQiOjYwLCJzIjoiLiBDb2xvbmlzdCJ9LHsiaWQiOjQwLCJzIjoiOCBtZWNoYW5pYyJ9LHsiaWQiOjc4LCJzIjoiMTAwLlxuXG5UaGUgIn0seyJpZCI6MSwicyI6IiB0aHJlZSBzaGkifSx7ImlkIjoxMywicyI6IjAgbW9zdCBhcHAifSx7ImlkIjoxMiwicyI6IiB0byBwaWNrIDQifSx7ImlkIjo5MywicyI6IklEO1Byb2Zlc3MifSx7ImlkIjoxMDQsInMiOiJlbGVjdCA0MCBwIn0seyJpZCI6MzksInMiOiI1IG1lZGljcywgIn0seyJpZCI6OCwicyI6Im5hYmxlIHRvIGMifSx7ImlkIjo1MiwicyI6InVzdCBiZSBmZW0ifSx7ImlkIjo5NiwicyI6IiBtYWxlID0gMSkifSx7ImlkIjo4OSwicyI6ImZlbWFsZSA9IDAifSx7ImlkIjoxMCwicyI6IiBjb2xvbmlzdHMifSx7ImlkIjo2NSwicyI6InMuIE9ubHkgdGgifSx7ImlkIjozNSwicyI6ImdpbmVlcnMsIDUifSx7ImlkIjoyMSwicyI6InJlZSBjcml0ZXIifSx7ImlkIjoxNywicyI6Im9sb25pc2F0aW8ifSx7ImlkIjo1NCwicyI6IiBmb3JnZXQgYWIifSx7ImlkIjoxNSwicyI6ImFuZGlkYXRlcyAifSx7ImlkIjo4NywicyI6IiBJRDtQcm9mZXMifSx7ImlkIjozNywicyI6InN5c3RlbSBzcGUifSx7ImlkIjo3OSwicyI6ImZpbGUgYXR0YWMifSx7ImlkIjo5MCwicyI6IiwgbWFsZSA9IDEifSx7ImlkIjoyOSwicyI6InNzZW50aWFsIGYifSx7ImlkIjoxMDcsInMiOiJpemUgdGhlIFJlIn0seyJpZCI6NiwicyI6ImF0ZXMgZnVsbHkifSx7ImlkIjo2NiwicyI6ImUgbW9zdCByZXMifSx7ImlkIjozMiwicyI6ImFnZXIsIDMgY28ifSx7ImlkIjo2MywicyI6InMgb2YgaGFyc2gifSx7ImlkIjo0LCJzIjoidW5jdGlvbmluZyJ9LHsiaWQiOjgyLCJzIjoidGFpbnMgYSBsaSJ9LHsiaWQiOjM4LCJzIjoiY2lhbGlzdHMsICJ9LHsiaWQiOjc0LCJzIjoiZSByYXRpbmcgNiJ9LHsiaWQiOjc3LCJzIjoiZnJvbSAxIHRvICJ9LHsiaWQiOjE5LCJzIjoiaW9sb2dpc3RzICJ9LHsiaWQiOjMsInMiOiJzIGFyZSBtYWxmIn0seyJpZCI6NTMsInMiOiJhbGUuIERvbid0In0seyJpZCI6MjMsInMiOiJwbGlmeSB0aGUgIn0seyJpZCI6MjgsInMiOiJjaWFsaXN0cyBlIn0seyJpZCI6ODgsInMiOiJzaW9uO1NleCAoIn0seyJpZCI6OTQsInMiOiJpb247U2V4IChmIn0seyJpZCI6MTA2LCJzIjoid2lsbCBjb2xvbiJ9LHsiaWQiOjI1LCJzIjoiXG5cbjEuIENyZXcgIn0seyJpZCI6MTAyLCJzIjoiIHRoaXMgaW5mbyJ9LHsiaWQiOjkxLCJzIjoiKTtSZXNpbGllbiJ9LHsiaWQiOjgxLCJzIjoicyB0YXNrIGNvbiJ9LHsiaWQiOjU3LCJzIjoiJSBvZiBjb2xvbiJ9LHsiaWQiOjc2LCJzIjoiIG9uIHNjYWxlICJ9LHsiaWQiOjMwLCJzIjoib3IgdGhlIGNvbCJ9LHsiaWQiOjgwLCJzIjoiaGVkIHRvIHRoaSJ9LHsiaWQiOjE0LCJzIjoicm9wcmlhdGUgYyJ9LHsiaWQiOjcyLCJzIjoiZW9wbGUgd2l0aCJ9LHsiaWQiOjY5LCJzIjoiIGNvbG9uaXplICJ9LHsiaWQiOjksInMiOiJvbnRhaW4gMTIwIn0seyJpZCI6MjAsInMiOiJkZWZpbmVkIHRoIn0seyJpZCI6NjcsInMiOiJpbGllbnQgcGVvIn0seyJpZCI6NTAsInMiOiJzZWxlY3RlZCBjIn0seyJpZCI6OTksInMiOiJ0Yy4gXG5MaW5lICJ9LHsiaWQiOjgzLCJzIjoic3Qgb2YgY29sbyJ9LHsiaWQiOjU2LCJzIjoidCBsZWFzdCAzMCJ9LHsiaWQiOjg0LCJzIjoibmlzdHMgaW4gdCJ9LHsiaWQiOjM0LCJzIjoiY3RyaWNhbCBlbiJ9LHsiaWQiOjQ1LCJzIjoiZXhpc3QgZm9yICJ9LHsiaWQiOjkyLCJzIjoiY2UgcmF0aW5nXG4ifSx7ImlkIjoyNiwicyI6Im11c3QgaW5jbHUifSx7ImlkIjo0NiwicyI6InNldmVyYWwgZ2UifV0="""
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())
В итоге, получим сообщение и md5-хэш сообщения:
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
К сообщению прилагается файл с данными о колонистах в следующем формате:
1;electrical engineer;0;90
2;mechanic;0;77
3;scientist;1;71
Формат такой: ID; Профессия; Пол(женщина = 0, мужчина = 1); Рейтинг устойчивости
Предлагается из 120 колонистов набрать 40, удовлетворяющих следующим критериям:
- В колонии должен быть 1 управляющий, 3 повара, 4 электрика, 5 компьютерщиков, 5 медиков, 8 механиков и 14 ученых.
- Колонии предстоит существовать не один год, поэтому, как минимум, 51% жителей должны быть женщинами. Но не менее 30% колонистов должны быть представителями мужского пола.
- В колонии жить не так просто и весело, поэтому необходимо выбрать только кандидатов, чей рейтинг устойчивости равен 60 и более единицам по шкале от 1 до 100.
А теперь приступим к отбору колонистов!
Отбираем...
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)
Форма на сайте принимает код и автоматически его тестирует. Данные подаются из потока стандартного ввода, по этой же причине, приходится их считывать оттуда, что немного усложняет тестирование кода при написании.
Январь 2019
Хотел поделиться с вами этим, довольно интересным, опытом, участия в подобных квестах. Для меня он оказался первым. Мне кажется, идея интересная даже без конкурсной основы. Лично я нарешал штук 5 задач разных типов. Остальные прикладываю по ссылке на github.
А еще, в качестве вознаграждения, в конце выпадает рейтинговая таблица с вашим временем. Для меня лучший результат оказался таким:
Итог, символическое 50 место из более 400+ участников.
Что можно об этом сказать? Для меня это было увлекательно проведенное за программированием время. Кстати задания все еще доступны для желающих их порешать, несмотря на то, что конкурс давно завершен.
Комментарии (7)
BoroL
07.01.2019 14:56sortList.sort(key=sortbylen)
sortbylen не определена, что я делаю не так?petukhovlive Автор
07.01.2019 14:57Вот определение функции из моего кода:
def sortbylen(sortlist): return sortlist[ids]
walkman7
07.01.2019 16:42Ничего сексисткого, но почему:
1;electrical engineer;0;90
2;mechanic;0;77
3;scientist;1;71
Формат такой: ID; Профессия; Пол(женщина = 0, мужчина = 1); Рейтинг устойчивости
Електро-монтер и механик — женщины, а ученый — мужчина?petukhovlive Автор
07.01.2019 22:24+1Скрытый сексизм! А то, что женщина — 0, а мужчина — 1 вас не смутило?
OZR
Даже для прохождения текстового квеста настало время (нет) ввести e-mail, телефон и согласие на обработку персональных данных для третьих лиц… Теперь я не могу даже поиграть в текстовый квест. Грустно :(
petukhovlive Автор
К сожалению, такое время :(