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