Программистам хорошо известно понятие квайна. Если вы все еще не знаете, что это такое, то вот определение.
Квайн можно считать условно примером рекурсии - код сам себя выводит. Но, классическая рекурсия запускает код который вызывает себя несколько раз до остановки по критерию, а квайн - только один раз. Аналогичным примером квайна в математике можно считать формулу Таппера (2001 год). Формула замечательна тем, что график функции, построенной по этой формуле представляет собой графическое изображение этой же формулы. Формула рисует сама себя - так можно сказать. Вот эта формула.
\[{1 \over 2}<\left\lfloor {\mathrm {mod}}\left(\left\lfloor {y \over 17}\right\rfloor 2^{{-17\lfloor x\rfloor -{\mathrm {mod}}(\lfloor y\rfloor ,17)}},2\right)\right\rfloor ,\] Здесь оператор в таких скобках \(\lfloor * \rfloor\) обозначает целую часть от числа в скобках, а оператор \(mod(a,b)\) - остаток от деления числа \(a\) на \(b\).Пусть дано следующее число \(k\) - (состоит из 544 цифр)
Фактически на графике представлено поле размером \(106 \cdot 17\), разбитое сеткой на клеточки (пиксели). Результатом подстановки значений \(x,y\) в неравенство есть \(0\) - если неравенство не выполняется и \(1\) - если выполняется. Затем, если для некоторой пары координат \(x,y\) получилось значение \(1\) , то указанная клетка на поле закрашивается (черным), если \(0\) то цвет поля не меняется (белый) . Перебрав все клетки и закрашивая те клетки, для которых получается из неравенства значение \(1\) - выполнение, получим приведенное изображение.
Теперь покажем как нарисовать такое изображение, используя javascript. Пример отрисовки показан ниже: Рисунок здесь выполнен на канве:
<canvas class="tupper" width="570" height="85"></canvas>Далее следует на страницу подключить скрипт:
<script src="https://cdn.rawgit.com/filipemeneses/tupper/b17885ae/dist/tupper.web.min.js" charset="utf-8"></script>И последний шаг - выполнить следующий скрипт:
<script>
var CUBE_SIZE = 5
var paintArray = (canvas, number) => {
var ctx = canvas.getContext('2d')
tupper.toGraph(number).forEach((row, y) => {
row.forEach((pixel, x) => {
ctx.fillStyle = pixel ? 'black' : 'white';
ctx.fillRect(x * CUBE_SIZE, y * CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
})
})
}
paintArray(document.querySelector('.tupper'), '48584506361897134235820959624942020445814005879
83244549483093085061934704708809928450644769865524364
84999724702491511911041160573917740785691975432657185
54420572104457358836818298237541396343382251994521916
51284348332905131193199953502413758765239264874613394
90687013056229581321948111368533953556529085002387509
28568926945559742815463865107300491067230589335860525
44096664351265349363643957125565695936815184334857605
26694016125126695142155053955451915378545752575659074
05401579290017659679654800644278291314885482599147212
48506352686630476300')
paintArray(document.querySelector('.invader'), '356190145855031919348890157738898011538149755602338030')
</script>
P.S. Обратите внимание. В скрипте число должно быть без переносов на веб-странице для корректной работы скрипта.