Тема эзотерических языков программирования на Хабре, конечно, представлена, но, как мне кажется, не пользуется сильной популярностью. В то время, как гипотеза Коллатца, хоть и является более узкой темой, обсуждается гораздо активнее. Одним из интересных (на мой субъективный взгляд) эзолэнгов является FRACTRAN, концепция которого была предложена Джоном Конвеем (известным в первую очередь конечно же благодаря игре «Жизнь»).  В этой статье я расскажу про клёвую математику, лежащую в основе этого эзотерического языка программирования, разберу несколько простых программ на нём, и, наконец, покажу связь FRACTRAN'а с гипотезой Коллатца. Статья во многом является вольным пересказом соответствующей главы книги Strange Code: Esoteric Languages That Make Programming Fun Again (которую я бы рекомендовал всем, кто хочет взглянуть на программирование под другим углом). Начать конечно стоит с логики, лежащей в основе этого языка.  Программа представляет из себя последовательность обыкновенных дробей (рациональных чисел), на вход она принимает единственное натуральное число. Алгоритм выполнение программы следующий: пробуем умножить входное число на первую дробь если результат — натуральное число, оно становится новым входным числом, и алгоритм начинается с первого шага если результат — дробь, переходим к следующей дроби и пробуем аналогично когда дробей не осталось, программа останавливается Результатом выполнения программы является последнее целое число (или, при желании, все промежуточные целые числа). Простыми словами: ищется первая по порядку дробь, умножение на которую даёт целое число. Если такая дробь найдена — результат умножения становится новым входным числом и алгоритм начинается с начала (с первой дроби), если такой дроби не найдено — программа останавливается. Здесь я и не буду рассматривать реализацию языка, скажу лишь, что ожидается, что в ней будет использоваться длинная арифметика. Примеры реализации на python'е можно легко найти в интернете, нас интересует не это. На примере простой программы по сложению двух чисел попробуем понять, чем же FRACTRAN так интересен. Вот как она выглядит:  Если мы "запустим" эту программу и дадим на вход 144, результат будет 729 (входное число умножается на полтора, пока оно является целым). Разберёмся, какие же два числа мы тут складываем, и что за результат получаем.  FRACTRAN можно рассматривать как машину Минского, у которой регистры хранятся в степенях простых множителей входного числа.  Отмотаем немного назад. Как нам говорит основная теорема арифметики, каждое число можно единственным образом разложить на простые множители. Например, наше 144 выше — это , соответственно, в регистре №2 хранится 4, в регистре №3 (номер регистра соответствует простому числу, "отвечающему" за него) — 2. Результат выполнения программы — 729— не что иное, как . Что это значит? Что наша программа принимает на вход число в формате , а в результате выдаёт , то есть установив значения регистров №2 и №3 как a и b соответственно, результатом выполнения программы будет их сумма в 3м регистре. Очевидно, что вместо регистров 2 и 3 можно использовать два любых других простых m и n, соответственно, входное число должно быть в формате , а программа примет вид , результат будет записан в регистр m. Не хочется сильно раздувать статью вдаваясь в специфику языка, поэтому вот еще несколько примеров с кратким объяснением их работы: Входные данные:  Результат:  Программа:  Тут всё аналогично со сложением, мы уменьшаем одновременно 2й и 3й регистры, пока в 3м не окажется 0, в результате во 2м получаем искомую разницу. Входные данные:  Результат:  Программа:  Наконец, программа, в которой больше одной дроби! Что же здесь происходит? Сначала, мы увеличиваем 5й регистр, пока наше входное число делится на 6. В результате, после первого шага, минимальное число перемещается в 5й регистр, а в регистре с максимальным числом оказывается их (чисел) разница. Вторая и третья дроби по очередь тестируют 2й и 3й регистры на то, осталось ли там что-то еще, и переносят этот остаток в 5й регистр. В результате изначальные регистры остаются пустыми, а в 5м оказывается искомый максимум. Входные данные:  Результат:  Программа:  В этом примере дроби 7/11 и 13/17 являются аналогами цикла в привычных языках программирования. Рассмотрим блок из первых двух дробей подробнее: , каждое умножение входного числа на первую дробь уменьшает значение во 2м регистре на 1, одновременно увеличивая 3й и 5й (и 11й, но это не так важно1) регистры так же на 1. Поскольку 7 входит во входное число в 1й степени, умножение на 1ю дробь происходит только один раз. После чего единица перемещается из 7го регистра в 11й. Вторая дробь (7/11) перемещает эту единицу обратно. Происходит это до тех пор, пока входное число делится на 2 (значение во 2м регистре больше нуля). После этого 3я дробь (13/7) перемещает единицу из 7го регистра в 13й, и начинается второй цикл по перемещению значения из 5го регистра обратно во 2й, очищенный в первом цикле. Последняя дробь (1/13) очищает 13й регистр. Входные данные:  Результат:  Программа:  В предыдущем примере мы узнали, как во FRACTRAN'е выглядит цикл. Принцип умножения основан на нём же. В 5й регистр мы добавляем раз , используя вложенный цикл и копирование регистра. Входные данные:  Программа:  Тут я уже не берусь объяснять происходящее. Скажу только, что эта программа выводит все степени 2ки с простым показателем. Объяснение можно найти в лекции самого Конвея, ссылка на которую есть в конце статьи. Первым делом, перепишем уравнение, задающее гипотезу, в чуть другой форме. Оригинальное выглядит следующим образом: Если результат деления на 2 даёт нам целое число, оно становится новым входным числом, иначе, применяем второе преобразование. Запишем это в таком виде:  В общем виде это выглядит следующим образом: Функция возвращает самое первое целое число, полученное при вычислении функций и . Но совершенно необязательно ограничивать двумя частями, представим самый общий вид такой функции: Конвей назвал такие функции Коллатцевыми играми (в оригинале Collatzian games). Заметим, что если для всех функций взять , получится не что иное, как программа на FRACTRAN'е!  Поскольку FRACTRAN представляет из себя машину Минского, он является полным по Тьюрингу, а значит, на него распространяется проблема остановки. Поскольку программа на FRACTRAN'е — это частный случай Коллатцевой игры, значит, существуют такие игры, для которых невозможно доказать, закончатся ли они для всевозможных входных данных. Это и есть главный вывод этой статьи. Еще раз, гипотеза Коллатца и FRACTRAN — два частных случая Коллатцевой игры. При этом игра, описываемая через FRACTRAN, неразрешима. Конечно, FRACTRAN и оригинальная гипотеза Коллатца принадлежат к совершенно разным видам Коллатцевых игр, но сам факт, что существуют неразрешимые игры, наводит на мысль, что и сама гипотеза не обязана быть разрешимой. Во-первых, как же тяжело писать статью. Даже о том, что казалось бы интересно мне, как автору статьи. Прямо ощущаю, как интерес улетучивается с каждой написанной строчкой. Во-вторых, надеюсь, кому-нибудь этот путь тоже показался интересным, поэтому.. конечно, упомянутая выше Strange Code: Esoteric Languages That Make Programming Fun Again (честное слово, не имею к ней никакого отношения) лекция Джона Конвея, где он рассказывает и про FRACTRAN, и про гипотезу Коллатца статья в блоге какого-то чувака, которая, к сожалению, с момента создания потеряла всё форматирование