avatar
Миша пишет код
@misha_writes_code
22.10.2023 19:29
Помните, был такой Brainfuck?

Так вот оказывается, что printf и его параметры являются тьюринг полным языком. А это значит, что подобрав аргументы верно, можно реализовать любую вычислимую функцию. Ну или простыми словами - напрограммировать что угодно.

На самом деле это не совсем честное утверждение, так как в нем нет цикла. Но

while(1) printf(.....)

уже получается тьюринг полным.

Идея принадлежит победителю контеста IOCCC 2020, на котором он сделал крестики нолики используя как раз хак с printf. Назвал он этот подход Printf Oriented Programming.

Если вы не понимаете, как это работает, то я тоже. Но базовый концепт такой.

Все дело в спецификаторе %n, из-за которого printf кладет в соответствующий указатель количество напечатанных на данный момент символов. Что как раз и удается заабъюзить.

%n позволяет сохранять результат промежуточных вычислений и используя его можно реализовать некоторые булевы операции (на самом деле все). В статье автор приводит пример OR и NOT. А эта пара операций является функционально полной - то есть с их помощью можно сделать булеву формулу, удовлетворяющую любой таблице истинности.

Ну а дальше просто (ну насколько это вообще можно назвать простым), так как промежуточный результат сохранить можно, то можно и объединять логические элементы в более сложные (как раз как и работают вычислительные машины).

Казалось бы, прикольно, но и при чем тут Brainfuck? Вместо ответа приведу просто следующую строку.

Пример printf реализующего OR:

printf("%1$s%2$s%3$hhn", A, B, C)

В результате этого printf в C будет лежать A OR B.

В общем жестко, но крайне прикольно. ioccc - кладезь запарных идей.

P.S. кстати, итоговая форматная строка printf для крестиков ноликов после раскрытия всех макросов получается больше 100к символов в длину.
🔥 5
👍 3
1 293

Обсуждение 0

Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.

Обсудить в Telegram