Математика полна удивительных закономерностей. В одном из номеров журнала «Наука и жизнь» была небольшая заметка в разделе «Математические досуги». С двумя примерами на умножение из разряда математических неожиданностей.

20646 × 35211 = 11253 × 64602

203313 × 657624 = 426756 × 313302

Примечательны эти примеры тем, что цифры в них расположены зеркально-симметрично относительно знака равенства. Зеркальные равенства напоминают палиндромы, но с ключевым отличием. Палиндром — это свойство одного числа, а зеркальное равенство — это свойство операции над числами.

Как математический объект исследования зеркальные математические равенства не имеют определённого автора или даты первого упоминания. Это скорее концепция, которая возникает в процессе изучения чисел и их свойств, как естественное развитие темы палиндромов и симметрии в математике.

Как много существует подобных комбинаций?

На первый взгляд, зеркальные равенства — это какие-то эксклюзивные выражения с определённым расположением цифр. Но на самом деле вариантов множество. Количество возможных комбинаций при выполнении подобного алгоритма растёт с увеличением разрядности чисел: для 2-значных чисел — 56, для 3-значных — 240, для 4-значных — 2456, а для 5-значных — 9612 вариантов.

Примечание. При подсчёте вариантов не рассматривались следующие случаи:

– множители с одинаковыми цифрами (например, 111 × 222 = 222 × 111);

– множители – палиндромы (например, 232 × 454 = 454 × 232);

– множители между собой зеркальны (например, 1357 × 7531 = 1357 × 7531);

– в разряде единиц есть нули (чтобы при перевороте исключить ведущие нули).

Кому интересно посмотреть варианты, код на Python (от 2-значных до 6-значных чисел):

Код на Python для умножения
from itertools import product

def has_all_identical_digits(n):
    s = str(n)
    return all(c == s[0] for c in s)

def is_palindrome(n):
    s = str(n)
    return s == s[::-1]

def are_mirrors(a, b):
    return str(a) == str(b)[::-1]

def is_trivial_pair(a, b, c, d):
    return (
        (a == d and b == c) or 
        (a == c and b == d) or 
        are_mirrors(a, b) or  
        are_mirrors(c, d) 
    )

def find_all_pairs(digits):
    print("\n" + "="*50)
    found = 0
    total_operations = 0
    
    # генерация без чисел с одинаковыми цирами и палиндромов
    numbers = []
    for num_digits in product(*([range(1, 10)] + [range(0, 10)]*(digits-1))):
        num = int(''.join(map(str, num_digits)))
        reversed_num = int(''.join(map(str, num_digits[::-1])))
        
        if not has_all_identical_digits(num) and not is_palindrome(num):
            numbers.append((num, reversed_num))
    
    total_numbers = len(numbers)
    
    # проверка всех пар
    for i, (num1, num2) in enumerate(numbers):
        for j, (num3, num4) in enumerate(numbers):
            total_operations += 1
            if num1 * num3 == num2 * num4:
                if not is_trivial_pair(num1, num3, num4, num2):
                    print(f"{num1:0{digits}d} × {num3:0{digits}d} = {num4:0{digits}d} × {num2:0{digits}d}")
                    found += 1
    
    print(f"\nВсего проверено комбинаций: {total_operations}")
    print(f"Всего найдено уникальных вариантов: {found}")

def main():
    while True:
        print("\n" + "="*50)
        print("2. 2-значные числа")
        print("3. 3-значные числа")
        print("4. 4-значные числа")
        print("5. 5-значные числа")
        print("6. 6-значные числа")
        print("0. Выход из программы")
        
        choice = input("Выберите вариант (2–6) или нажмите 0 > ")
        
        if choice == '0':
            print("Выход из программы.")
            break
        elif choice in {'2', '3', '4', '5', '6'}:
            digits = int(choice)
            find_all_pairs(digits)
        else:
            print("Ошибка. Неверный выбор варианта.")

if __name__ == "__main__":
    main()

Зеркальные равенства для других арифметических операций

А как обстоят дела с делением, сложением и вычитанием? Можно ли найти аналогичные закономерности для других арифметических действий?

Зеркальные равенства для деления

Такие равенства могут получаться, если результатом деления является дробное число.

Примеры:

276 / 384 = 483 / 672 → 0,71875 = 0,71875

4716 / 8253 = 3528 / 6174 → 0,5714285714285714 = 0,5714285714285714

Код на Python (от 2-значных до 6-значных чисел) с дробными результатами:

Код на Python для деления
from itertools import product
from fractions import Fraction

def has_all_identical_digits(n):
    s = str(n)
    return all(c == s[0] for c in s)

def reverse_number(n, digits):
    reversed_str = str(n)[::-1]
    if len(reversed_str) < digits or reversed_str[0] == '0':
        return None
    return int(reversed_str)

def find_division_pairs(digits):
    found = 0
    total_pairs = 0
    
    numbers = []
    for num_digits in product(*([range(1, 10)] + [range(0, 10)]*(digits-1))):
        num = int(''.join(map(str, num_digits)))
        if not has_all_identical_digits(num):
            numbers.append(num)
    
    total_numbers = len(numbers)
    
    # проверка уникальных пар
    for i, ab in enumerate(numbers):
        ba = reverse_number(ab, digits)
        if ba is None:
            continue
            
        for j, cd in enumerate(numbers):
            if j <= i:
                continue
                
            dc = reverse_number(cd, digits)
            if dc is None:
                continue
                
            total_pairs += 1
            
            if Fraction(ab, cd) == Fraction(dc, ba):
                if ab != dc or cd != ba:
                    print(f"{ab:0{digits}d}/{cd:0{digits}d} = {dc:0{digits}d}/{ba:0{digits}d}")
                    found += 1
    
    print(f"\nВсего проверено комбинций: {total_pairs}")
    print(f"Всего найдено уникальных вариантов: {found}")

def main():
    while True:
        print("\n" + "="*50)
        print("2. 2-значные числа")
        print("3. 3-значные числа")
        print("4. 4-значные числа")
        print("5. 5-значные числа")
        print("6. 6-значные числа")
        print("0. Выход из программы")
        
        choice = input("Выберите вариант (2–6) или нажмите 0 > ")
        
        if choice == '0':
            print("Выход из программы.")
            break
        elif choice in {'2', '3', '4', '5', '6'}:
            digits = int(choice)
            find_division_pairs(digits)
        else:
            print("Ошибка. Неверный выбор варианта.")

if __name__ == "__main__":
    main()

Зеркальные равенства для сложения

Для зеркального сложения 2-значных и 3-значных чисел можно легко подбирать варианты вручную по простому алгоритму.

Алгоритм для двухзначных чисел:

Условие: AB + CD = DC + BA.

Представим числа в виде суммы разрядов:

(100A + B) + (100C + D) = (100D + C) + (100B + A)

Упростим:

 99A + 99C = 99D + 99B

A + C = D + B

Проверим. Пусть A = 5, B = 3, C = 4, D = 6.

5 + 4 = 6 + 3

Подставим цифры в равенство AB + CD = DC + BA.

53 + 46 = 64 + 35

99 = 99

Как видим, для подбора вариантов зеркального равенства AB + CD = DC + BA для 2-значных чисел необходимо выполнения условия: A + C = D + B.

Алгоритм для трёхзначных чисел:

Условие: ABC + DEF = FED + CBA.

Представим числа в виде суммы разрядов:

(100A + 10B + C) + (100D + 10E + F) = (100F + 10E + D) + (100C + 10B + A)

После преобразований:

99A + 99D = 99C + 99F

A + D = C + F

Проверим. Пусть A = 5, D = 3, C = 6, F = 2.

5 + 3 = 6 + 2

Подставим цифры в выражение ABC + DEF = FED + CBA.

5_6 + 3_2 = 2_3 + 6_5

Дополним произвольными цифрами: B = 1, E = 7.

516 + 372 = 273 + 615

888 = 888

Этот же пример проверим для случая, когда В = Е (например, В = Е = 9).

596 + 392 = 293 + 695

988 = 988

Получается, что для зеркального равенства сложения 3-значных чисел ABC + DEF = FED + CBA должно выполняться условие равенства сумм для крайних цифр: A + D = C + F. Средние цифры могут принимать любые значения.

Для нахождения всех вариантов зеркального равенства сложения оставили ниже пример кода на Python (от 2-значных до 6-значных чисел):

Код на Python для сложения
from itertools import product

def has_all_identical_digits(n):
    s = str(n)
    return all(c == s[0] for c in s)

def is_palindrome(n):
    s = str(n)
    return s == s[::-1]

def reverse_number(n, digits):
    reversed_str = str(n)[::-1]
    if len(reversed_str) < digits or reversed_str[0] == '0':
        return None
    return int(reversed_str)

def find_addition_pairs(digits):
    print("\n" + "="*50)
    found = 0
    total_pairs = 0
    
    numbers = []
    for num_digits in product(*([range(1, 10)] + [range(0, 10)]*(digits-1))):
        num = int(''.join(map(str, num_digits)))
        if not has_all_identical_digits(num) and not is_palindrome(num):
            numbers.append(num)
    
    total_numbers = len(numbers)
    
    for i, a in enumerate(numbers):
        rev_a = reverse_number(a, digits)
        if rev_a is None:
            continue
            
        for j, b in enumerate(numbers):
            if j <= i:
                continue
                
            rev_b = reverse_number(b, digits)
            if rev_b is None:
                continue
                
            total_pairs += 1
            
            if a + b == rev_b + rev_a:
                if a != rev_b or b != rev_a:
                    print(f"{a:0{digits}d} + {b:0{digits}d} = {rev_b:0{digits}d} + {rev_a:0{digits}d}")
                    found += 1
    
    print(f"\nВсего проверено комбинаций: {total_pairs}")
    print(f"Всего найдено уникальных вариантов: {found}")

def main():
    while True:
        print("\n" + "="*50)
        print("2. 2-значные числа")
        print("3. 3-значные числа")
        print("4. 4-значные числа")
        print("5. 5-значные числа")
        print("6. 6-значные числа")
        print("0. Выход из программы")
        
        choice = input("Выберите вариант (2-6) или нажмите 0 > ")
        
        if choice == '0':
            print("Выход из программы.")
            break
        elif choice in {'2', '3', '4', '5', '6'}:
            digits = int(choice)
            find_addition_pairs(digits)
        else:
            print("Ошибка. Неверный выбор варианта.")

if __name__ == "__main__":
    main()

Зеркальные равенства для вычитания

Примеры:

724 – 625 = 526 – 427

1225 – 1135 = 5311 – 5221

Код на Python (от 2-значных до 6-значных чисел). Варианты, когда получаются отрицательные результаты, не учитываются.

Код на Python для вычитания
from itertools import product

def has_all_identical_digits(n):
    s = str(n)
    return all(c == s[0] for c in s)

def reverse_number(n, digits):
    reversed_str = str(n)[::-1]
    if len(reversed_str) < digits or reversed_str[0] == '0':
        return None
    return int(reversed_str)

def find_subtraction_pairs(digits):
    found = 0
    total_pairs = 0
    
    numbers = []
    for num_digits in product(*([range(1, 10)] + [range(0, 10)]*(digits-1))):
        num = int(''.join(map(str, num_digits)))
        if not has_all_identical_digits(num):
            numbers.append(num)
    
    total_numbers = len(numbers)
    
    for i, a in enumerate(numbers):
        rev_a = reverse_number(a, digits)
        if rev_a is None:
            continue
            
        for j, b in enumerate(numbers):
            if j == i:
                continue
                
            rev_b = reverse_number(b, digits)
            if rev_b is None:
                continue
                
            total_pairs += 1
            
            if (a - b == rev_b - rev_a) and (a - b > 0) and (rev_b - rev_a > 0):
                if a != rev_b or b != rev_a:
                    print(f"{a:0{digits}d} - {b:0{digits}d} = {rev_b:0{digits}d} - {rev_a:0{digits}d}")
                    found += 1
    
    print(f"\nВсего проверено комбинаций: {total_pairs}")
    print(f"Всего найдено уникальных вариантов: {found}")

def main():
    while True:
        print("\n" + "="*50)
        print("2. 2-значные числа")
        print("3. 3-значные числа")
        print("4. 4-значные числа")
        print("5. 5-значные числа")
        print("6. 6-значные числа")
        print("0. Выход из программы")
        
        choice = input("Выберите вариант (2–6) или нажмите 0 > ")
        
        if choice == '0':
            print("Выход из программы.")
            break
        elif choice in {'2', '3', '4', '5', '6'}:
            digits = int(choice)
            find_subtraction_pairs(digits)
        else:
            print("Ошибка. Неверный выбор варианта.")

if __name__ == "__main__":
    main()

Так сколько же можно составить зеркальных равенств с арифметическими действиями? В зависимости от количества цифр в числах — от нескольких сотен до нескольких миллионов. И это только для чисел в диапазоне от 2-значных до 5-значных. Шестизначные числа не проверялись по причине долгой обработки. Но по аналогии с результатами, записанными в таблице ниже, понятно, что это миллионы вариантов. Естественно, чем выше разрядность, тем больше будет уникальных комбинаций зеркальных равенств.

2-значные

3-значные

4-значные

5-значные

умножение

всего комбинаций

6561

656100

79388100

7938810000

уникальные варианты

56

240

2456

9612

деление (с дробными результатами)

всего комбинаций

2556

320400

32728095

3279730545

уникальные варианты

0

14

134

936

сложение

всего комбинаций

2556

258840

32076045

3207964950

уникальные варианты

168

20040

155760

15936450

вычитание (с положительными результатами)

всего комбинаций

5112

640800

65456190

6559461090

уникальные варианты

136

1648

155488

3114656

Где можно использовать свойство зеркальных равенств

  • Такие примеры отлично подходят для популяризации математики, для головоломок и развлечений. Также их можно использовать для олимпиад или конкурсов на нестандартные математические закономерности.

  • В качестве учебной модели в криптографии.

  • Для тестирования алгоритмов, выполняющих арифметические действия с большими числами, в тех случаях, когда результат должен сохранять симметрию.

  • Математические исследования условий, при которых такие равенства возможны, и можно ли найти общую формулу для их генерации.

При написании статьи возникло несколько предположений о закономерностях, которые в дальнейшем интересно будет проверить. У кого какие мысли по зеркальным равенствам — поделитесь.


НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

Комментарии (0)