Содержание

2027

2027

Страничка в процессе разработки, заходите лучше позже

Скоро наступит 2027 год. Две тысячи двадцать седьмой год по григорианскому календарю — невисокосный год, начинающийся в пятницу. Это 2027 год нашей эры, 7‑й год 3‑го десятилетия XXI века 3‑го тысячелетия, 8‑й год 2020‑х годов. В кои-то веки число года является простым, не так уж часто это бывает. Например, предыдущий простой (с точки зрения математики) год был 2017. Следующим за 2027 простым будет 2029, а потом уже только 2039. Года с 2018 по 2026 были очень не простыми во всех смыслах, так что будем надеяться, что хотя бы в простом 2027 станет попроще.

Эта страничка посвящена не году, а номеру года – числу 2027.

Про само число можно многое сказать. Например, вот тут: https://webcalypt.com/tools/number/2027 собрано довольно большое количество всяких интересных фактов и преобразований этого числа в разные единицы измерения.

Я же хочу продолжить свои упражнения, связанные с занимательными вычислениями.

2027 из цифр 1234567890

Впервые с подобной задачей я встретился в каком-то древнем выпуске «Науки и жизни» в рубрике «Психологический практикум». Я бы нашёл этот номер и привёл бы скрин в качестве пруфа, но у меня высокие отношения с издательством этого журнала, как у Рабиновича с банком, поэтому верьте мне на слово :)

Из последовательности цифр 1234567890 и знаков 4-х математических действий нужно составить такое выражение, результат которого даст нужное нам число, в данном случае число года. Я придумал вот такие решения:

Попробуйте придумать свои варианты, очень увлекательное занятие, скажу я вам. А вот результат моей попытки привлечь к решению этой задачи ИИ. Я дал ему в качестве примера первое решение с факториалом и попросил найти решение без факториала. DeepSeek долго пытался, но в результате так и не смог, хотя был близок – нашёл решение для 2028. Так что через некоторое время оно пригодится. DeepSeek признал поражение

2027 из одинаковых цифр

Похожая задача: теперь число года надо собрать не из последовательных цифр, а из любого (желательно наименьшего) количества одинаковых цифр.

Я придумал вот такую общую формулу для цифр А из диапазона [1;9]:

то есть вот так:

Причём эту формулу можно немного упрощать для отдельных случаев:

Но можно и вообще отойти от «стандартного» решения:

Как говаривал один мой препод в институте, «Легко заметить, что…» и далее шло что-то очень сложное и непонятное. Так вот, легко заметить, что 0!=1. Это даёт нам возможность из нуля получить что-то, отличное от нуля. Но мы к четырём действиям вынуждены привлечь ещё такое мудрое действие как вычисление факториала. Далее из суммы единиц можно «собрать» любое число любых чисел, а уже потом применять действия к этим числам. Поэтому с нулём задача сводится к поиску выражения, содержащего минимум символов, которое даёт в результате 2027. Например, такое:

Разные числа из цифр 2027

Ну а теперь самое мозговыносительное.

Правила: используя любые математические действия, функции и преобразования, получить из последовательности цифр 2,0,2,7 выражение, значение которого точно равно числу слева. Не допускается явное использование каких-либо других цифр и чисел. Например, знак квадратного корня допустим, а вот кубический корень нет, так как в нём явно используется цифра 3.

Помимо вполне обычных действий сложения (+), вычитания (-), умножения (·) и деления (:), функций квадратного корня `sqrt(N)`, натурального `ln(N)` и десятичного логарифма `lg(N)` можно привлечь десятичную запятую/точку (.), инверсию знака (-), а также разные виды округления: обычное математическое `[N]`, вверх ` |~N~| ` и вниз `|__N__| ` (с отсечением дробной части). Ну и более сложные действия: возведение в степень `(x^y)`, обычный (!), двойной (!!) и другие кратные факториалы. И в этот раз постарался обойтись без привлечения палочек-выручалочек в виде констант π и e. Ибо это нечестно, потому что из них одних можно сделать выражения для любых чисел.

Перед тем как искать решения, я сделал вот такие «заготовки»:

2

0

20

202

27

7

Попытки привлечь ИИ

Честно признаюсь, в середине пути у меня возникла идея снова привлечь для этой задачи ИИ. Ну я и привлёк сначала DeepSeek, затем от безысходности ГигаЧат. И снова ни один не справился. DeepSeek честно пытался решить задачу, даже с моими подсказками смог накидать решения для первого десятка, и на этом сдох. Но при этом я подсмотрел у него великолепную идею применять кратные факториалы. Странно, но я даже не знал, что такое существует. Про одиночные и двойные факториалы я знал, а вот дальше… Те решения, которые придумал deepseek, я отмечу специальным значком (`{::}^✨`). Всё остальное я сам просчитал, можете не сомневаться :) В самом конце осталось два сложных числа, которые долго не давались – 59 и 82. И я снова попробовал привлечь ИИ для поиска этих конкретных значений. На одном из шагов удалось даже зациклить Deepseek, он стал выдавать по кругу одно и то же.

Сначала ДипСик зациклился

В конце концов я его прервал, он извинился и предложил мне программу на phyton, которая полным перебором должна была выдать решения для всех чисел от 0 до 100.

Затем сдался, но предложил программу

Код программы на питоне

Код программы на питоне

2027.py
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 успешно получены!")

Я честно попробовал её запустить, но так и не дождался, пока она отработает. То ли виснет, то ли слишком много времени ей надо. ГигаЧат просто отказался, хотя и нагнал перед этим много текста.

 ГигаЧат тоже сдался

Поэтому я поигрался ими чуток, а затем сел за бумажку и калькулятор, и минут за 10 неспешного анализа нашёл нужные мне решения. Так что пока ИИ мне видится хорошим инструментом, но задачи он всё равно решает не все. По крайней мере доступные мне бесплатные версии. Потому что есть подозрение, что Chat GPT с этой задачей бы справился лучше.

Первая сотня

и так далее...

Большие числа

А можно задаться вопросом, какое самое большое число можно получить из цифр 2,0,2,7?

Теперь привлекаем факториалы и комбинаторику:

Двойной факториал содержит … цифр результата:

Ну а в полном факториале в два раза больше цифр - :

Наверное, можно получить и ещё большие значения.

Малые числа

Некоторые интересные преобразования и соотношения