import math from fractions import Fraction # -------- Настройки -------- DIGITS = "2027" # цифры в заданном порядке TARGET_MIN = 0 TARGET_MAX = 100 MAX_FACTORIAL = 20 # не брать факториалы слишком больших чисел ALLOW_UNARY = True # разрешить унарные операции: факториалы, корень, логарифм, модуль, отрицание # -------- Вспомогательные функции для унарных операций -------- def apply_unary(x, expr): """Возвращает список (значение, строка_выражения) после применения всех унарных операций.""" res = [] # само число res.append((x, expr)) # отрицание res.append((-x, f"(-{expr})")) # модуль res.append((abs(x), f"|{expr}|")) # квадратный корень (если x >= 0) if x >= 0: res.append((math.sqrt(x), f"√({expr})")) # факториал (если x целое неотрицательное и не слишком большое) if isinstance(x, int) and x >= 0 and x <= MAX_FACTORIAL: try: res.append((math.factorial(x), f"({expr})!")) except: pass # кратные факториалы (до 10 восклицательных знаков) if isinstance(x, int) and x >= 0: for k in range(2, 11): val = 1 for i in range(x, 0, -k): val *= i if abs(val) < 1e9: res.append((val, f"({expr}){'!'*k}")) # натуральный и десятичный логарифмы (если x > 0) if x > 0: res.append((math.log(x), f"ln({expr})")) res.append((math.log10(x), f"lg({expr})")) return res # -------- Основной рекурсивный перебор -------- memo = {} # кеш: подстрока -> список (значение, выражение) def get_values(s): """Возвращает список кортежей (число, строка_выражения) для подстроки s.""" if s in memo: return memo[s] if len(s) == 0: return [] if len(s) == 1: d = int(s) # число как цифра, а также .d (десятичная дробь) res = [(d, s)] if d != 0: res.append((Fraction(d, 10), f".{s}")) # например, .2 = 0.2 else: res.append((Fraction(0, 1), "0")) # .0 = 0 memo[s] = res return res # ---------- 1. Конкатенация всей подстроки ---------- num = int(s) res = [(num, s)] # ---------- 2. Десятичные дроби (вставить точку внутри) ---------- for i in range(1, len(s)): left = s[:i] right = s[i:] if left and right: try: val = float(left + '.' + right) # избегаем дубликатов (например, 2.0 = 2) if val != int(val) or int(val) != num: res.append((val, left + '.' + right)) except: pass # ---------- 3. Разбиение на две части и применение бинарных операций ---------- for i in range(1, len(s)): left = s[:i] right = s[i:] left_vals = get_values(left) right_vals = get_values(right) for a, a_expr in left_vals: for b, b_expr in right_vals: # сложение res.append((a + b, f"({a_expr})+({b_expr})")) # вычитание res.append((a - b, f"({a_expr})-({b_expr})")) # умножение res.append((a * b, f"({a_expr})*({b_expr})")) # деление (если b != 0) if b != 0: res.append((a / b, f"({a_expr})/({b_expr})")) # возведение в степень (если допустимо) if a != 0 or b != 0: # избегаем 0^0 try: res.append((a ** b, f"({a_expr})^({b_expr})")) except: pass # ---------- 4. Применение унарных операций ко всем полученным значениям ---------- final = [] seen = set() for val, expr in res: # пропускаем слишком большие числа (для скорости) if abs(val) > 1e9: continue # применяем унарные операции for new_val, new_expr in apply_unary(val, expr): # приводим к float для сравнения, но храним как есть if isinstance(new_val, Fraction): new_val = float(new_val) if abs(new_val) < 1e9: key = (new_val, new_expr) if key not in seen: seen.add(key) final.append((new_val, new_expr)) memo[s] = final return final # ---------- Генерация всех выражений для всей строки ---------- all_results = get_values(DIGITS) # ---------- Фильтрация целых чисел в заданном диапазоне ---------- found = {} for val, expr in all_results: # проверяем, является ли число целым и в диапазоне if isinstance(val, float) and val.is_integer(): n = int(val) if TARGET_MIN <= n <= TARGET_MAX: # если ещё не нашли или выражение короче, сохраняем более короткое if n not in found or len(expr) < len(found[n]): found[n] = expr elif isinstance(val, int): n = val if TARGET_MIN <= n <= TARGET_MAX: if n not in found or len(expr) < len(found[n]): found[n] = expr # также проверяем Fraction elif isinstance(val, Fraction) and val.denominator == 1: n = val.numerator if TARGET_MIN <= n <= TARGET_MAX: if n not in found or len(expr) < len(found[n]): found[n] = expr # ---------- Вывод результата ---------- print(f"Покрытие чисел от {TARGET_MIN} до {TARGET_MAX}:") missing = [] for n in range(TARGET_MIN, TARGET_MAX + 1): if n in found: print(f"{n:3d} = {found[n]}") else: missing.append(n) print(f"{n:3d} = НЕ НАЙДЕНО") if missing: print(f"\nНе найдены: {missing}") else: print("\n✅ Все числа от 0 до 100 успешно получены!")