12.02.2018Лось квайн
Давненько я не писал чисто программерского! Есть такая прекрасная маргинальная область: бесполезная дурня. Для меня — это совершенно точно искусство, как оно есть, только для очень узкого круга людей. Более ли менее известный пример — это Simone Giertz – Королева говёных роботов. Я сам бесконечно уважаю бесполезную дурню. О некоторых штуках я даже писал ранее. Например, про лося в терминале или про JSFuck. Сегодня хочу рассказать про моё свежее улечение — квайны. И похвастаться, конечно.
Про программы, которые выводят собственный текст, я слышал уже давно. Это казалось чем-то очень навороченным и неприступным. Если нет специальной функции для этого и нельзя читать файл, то не совсем понятно, с какого бока начинать. Но тут как раз перед выходными мне прислали статью, которая подводит под это дело теоретическую базу. В силу не совсем профильного образования, мне не довелось серьёзно заниматься теорией вычислений, а это оказалась довольно прикольная область.
И вот, наступил викенд, и меня сильно это дело вштырило. Вооружившись теоретическим доказательством того, что на любом языке программирования можно написать квайн, я приступил к составлению своего корявого решения. К концу выходных я написал двухступенчатый квайн, который при каждом запуске выводит следующий шаг моего лося из репортера.
В силу личного склада, это походило на зависимость. Чуть голова не разболелась. Главное в это деле — вовремя остановиться. Сейчас в репозитории есть усовершенствованная версия с гифки выше, версия, которая анимирует пробег лося по парамтерам, а так же версия в технике аски-графики. Примечательно, что не смотря на отсутсвие примеров, я пришёл к оптимальному варианту, который многие используют, когда хотят чтобы квайн, кроме своей непосредственной функции делал ещё что-то такое же бесполезное и прекрасное.
eval a = <<-'a'
# Мой код
puts "eval a = <<-'a'\n#{a}a"
a
После пошёл читать код такого же любителя странного — Юсуке Эндо (Yusuke Endoh). Он, среди прочего, написал квайн-реле, которое выводит на каждом шагу код на другом языке. И если его запустить на 128 языках 128 раз, то оно выведет обратно исходный код на первом языке. Чувак тоже относится к программированию как к искусству. Странному, гиковскому, маргинальному, нердическому, но при этом Великому и Бессмысленному Искусству. Например, он написал книгу, которая называется «The World of Obfuscated, Esoteric, Artistic Programming». Конечно же, на японском. И врядли её переведут ( ≧Д≦) Или у него есть «Квайн, устойчивый к радиации», из которого можно удалить одну любую букву и он при запуске выведет восстановленный исходный код. Ещё и в аски-графике.
Вот вам видео последней версии квайна, вдохновленное товарищем Эндо. Отлично провёл время, в общем. А у вас как дела?
Материалы для самостоятельного изучения
02.03.2016Лось
Сейчас меня уже почти не спрашивают: «Почему лось?» Отчасти потому, что я не очень продвигаю этого персонажа, а отчасти потому, что люди думают, что мне просто нравятся лоси, или я их коллекционирую. Второе приводит, например, к тому, что мне дарят разных игрушечных лосей. Это забавный результат, поэтому я считаю, что репутацию местного сумасшедшего нужно поддерживать. Как следствие я начал использовать лосей в повседневной работе.
Терминал
Первым делом нужно, чтобы лось приветствовал меня при каждом открытии терминала или новой его вкладки. Примерно так:
При этом хотелось бы, чтобы у него было разное случайное выражение лица. Для этого нужно в ~/.bash_profile (или какой у вас файл для создания окружения) написать следующее:
eye=(o O @ . - \* \~ °)
let left=${RANDOM}%${#eye[*]}
let right=${RANDOM}%${#eye[*]}
cat << EOF
_ _ _ _ _
| || | ____ | || || |
\ |/ \| /
\____ ${eye[$left]} ${eye[$right]} ______/
| |________
| }=
| __ ____ _ |
|| || || ||
|| || || ||
"" "" "" ""
EOF
Базовая работа с массивами. Встроенная в баш функция случайного числа. Обязательно предварять косой чертой «*» и «~», чтобы они не стали списком файлов и домашней директорией. По-моему — красота!
Spec runner
И, конечно же, для любителей разработки через тестирование нужен правильный репортер:
Здесь нужно пользоваться эскейп кодами для управления положением каретки, то есть курсора. Мало кто помнит, но курсор можно двигать во все стороны на любое количество позиций. Данный пример я собрал для раннера тестов на жасмине. Да, да, я разрабатываю в том числе на node.js и тестирую с помощью jasmine. Ключевая функция для рисования лося вот:
function printElk() {
if (specCount > 1) {
print('\x1b[5A');
}
if (specCount % 2 === 0) {
print(Array(specCount + 1).join(' ') + ' ^^' + eyes() + '^^\n');
print(Array(specCount + 1).join(' ') + ' _____ U\n');
print(specTrail + '~( _ /\n');
print(Array(specCount + 1).join(' ') + ' || ||\n');
print(Array(specCount + 1).join(' ') + ' ^^ ^^\n');
} else {
print(Array(specCount + 1).join(' ') + ' ^^' + eyes() + '^^\n');
print(Array(specCount + 1).join(' ') + ' _____ U\n');
print(specTrail + '`( _ /\n');
print(Array(specCount + 1).join(' ') + ' // \\\\\n');
print(Array(specCount + 1).join(' ') + ' ^^ ^^\n');
}
}
Здесь specTrail и eyes следят за историей вопроса, а вся функция вместо того, чтобы как раньше, ставить точку или F, поднимается на пять строчек вверх и переписывает их полностью.
Бонус
Это не про лося, но тем не менее. Вообще, я считаю, что всегда лучше потратить немного времени, чтобы сделать всё удобно и интересно. Мелочи решают!
Эту вещь придумал не я. Скорее всего, до меня её придумали неоднократно, и я не могу найти первоисточник. Тем не менее, считаю, что это очень полезная вещь, и нужно ей поделиться. Речь идёт о том, чтобы показывать статус завершения предыдущей команды в строке запроса баша.
export PS1="\[\e]0;\u@\h: \W\a\`if [ \$? = 0 ];then echo \[\e[32m\]^_^\[\e[0m\];else echo \[\e[31m\]o_O\[\e[0m\];fi\`[\u@\h: \w][\$(rvm-prompt v)][\$(nvm_version)]\$(parse_git_branch)\$ "
Это моя строка запроса. В её начале мы видим или зелёный довольный смайлик, или красный удивлённый. Благодаря вот этой части:
\`if [ \$? = 0 ];then echo \[\e[32m\]^_^\[\e[0m\];else echo \[\e[31m\]o_O\[\e[0m\];fi\`
Когда сделал себе и привык, то теперь просто не понимаю, как другие без этого обходятся.