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