#!/usr/bin/env python3 from datetime import datetime from itertools import product import requests from bs4 import BeautifulSoup from geopy.geocoders import Nominatim # Konstanty je zapotřebí vyplnit pro konkrétní vstup. PERIODIC_SUM = 778 COORDS = "47.94093275N, 106.91795035225584E" BANNED_LETTER = "J" HIPPO_IMG = "" def safe_letter(): return "a" if BANNED_LETTER != "A" else "b" def balance(password): lower = sum(char.islower() for char in password) upper = sum(char.isupper() for char in password) add = safe_letter()*abs(upper-lower) if upper < lower: add = add.upper() return password + add def add_roman_minute(password): minute = datetime.now().minute # Pokud by zakázané písmeno bylo X nebo I, # tak v některých případech nemusí být možné úlohu vyřešit return password + "X"*(minute//10) + "I"*(minute%10) ELEMENTS = {"H": 1, "He": 2, "Li": 3, "Be": 4, "B": 5, "C": 6, "N": 7, "O": 8, "F": 9, "Ne": 10, "Na": 11, "Mg": 12, "Al": 13, "Si": 14, "P": 15, "S": 16, "Cl": 17, "Ar": 18, "K": 19, "Ca": 20, "Sc": 21, "Ti": 22, "V": 23, "Cr": 24, "Mn": 25, "Fe": 26, "Co": 27, "Ni": 28, "Cu": 29, "Zn": 30, "Ga": 31, "Ge": 32, "As": 33, "Se": 34, "Br": 35, "Kr": 36, "Rb": 37, "Sr": 38, "Y": 39, "Zr": 40, "Nb": 41, "Mo": 42, "Tc": 43, "Ru": 44, "Rh": 45, "Pd": 46, "Ag": 47, "Cd": 48, "In": 49, "Sn": 50, "Sb": 51, "Te": 52, "I": 53, "Xe": 54, "Cs": 55, "Ba": 56, "La": 57, "Ce": 58, "Pr": 59, "Nd": 60, "Pm": 61, "Sm": 62, "Eu": 63, "Gd": 64, "Tb": 65, "Dy": 66, "Ho": 67, "Er": 68, "Tm": 69, "Yb": 70, "Lu": 71, "Hf": 72, "Ta": 73, "W": 74, "Re": 75, "Os": 76, "Ir": 77, "Pt": 78, "Au": 79, "Hg": 80, "Tl": 81, "Pb": 82, "Bi": 83, "Po": 84, "At": 85, "Rn": 86, "Fr": 87, "Ra": 88, "Ac": 89, "Th": 90, "Pa": 91, "U": 92, "Np": 93, "Pu": 94, "Am": 95, "Cm": 96, "Bk": 97, "Cf": 98, "Es": 99, "Fm": 100, "Md": 101, "No": 102, "Lr": 103, "Rf": 104, "Db": 105, "Sg": 106, "Bh": 107, "Hs": 108, "Mt": 109, "Ds": 110, "Rg": 111, "Cn": 112, "Nh": 113, "Fl": 114, "Mc": 115, "Lv": 116, "Ts": 117, "Og": 118} def add_periodic_sum(password): remaining = PERIODIC_SUM for i in range(len(password)): if password[i:i+2] in ELEMENTS: remaining -= ELEMENTS[password[i:i+2]] elif password[i] in ELEMENTS: remaining -= ELEMENTS[password[i]] if BANNED_LETTER != "H": return password + "H"*remaining else: # Předpokládejme, že rozdíl není <= 2 match remaining % 3: case 0: el = "Li" case 1: el = "Be" case 2: el = "B" remaining -= ELEMENTS[el] return password + el + "Li"*(remaining//3) def add_city_on_coords(password): geolocator = Nominatim(user_agent="ksp") location = geolocator.reverse(COORDS, language='en') return password + location.raw['address']['city'].lower() def add_sponsor(password): return password + ("cuni" if BANNED_LETTER in "MFF" else "mff") def get_page(code): response = requests.get(f"http://ksp.mff.cuni.cz/viz/{code}") if 400 <= response.status_code: return None return response.content def add_hippo_task(password): if not HIPPO_IMG: return password # Časová optimalizace, pokud hrošíka neznáme for year, cat, series in product(range(0, 37), ("", "Z"), range(0, 6)): label = f"{year}-{cat}{series}" if not (content := get_page(label)): continue content = content.decode("utf-8") soup = BeautifulSoup(content, "html.parser") last_task = None for tag in soup.find_all(["h3", "img"]): if tag.name == "h3" and tag.attrs.get("id", "").startswith("task-"): last_task = tag.attrs["id"][5:] if tag.name == "img" and HIPPO_IMG in tag.attrs["src"]: return password + last_task def make_prime_lenght(password): target_length = len(password) while True: is_prime = True for i in range(2, target_length-1): if target_length % i == 0: is_prime = False break if is_prime: break target_length += 1 return password + "1" * (target_length - len(password)) password = "1" password = add_sponsor(password) password = add_city_on_coords(password) password = add_hippo_task(password) password = add_roman_minute(password) password = add_periodic_sum(password) password = balance(password) password = make_prime_lenght(password) print(password) print(password)