99 бутылок: cURL
На сайте «Оупеннет», который я давно читаю, стараясь зажмуриваться на комментариях (там чистые Содом и Гоморра), увидел сегодня статью «В конфигурационных файлах curl случайно реализована полнота по Тьюрингу». Естественно, мимо такого названия я пройти не мог. Не беда, что «Песня о пиве» уже реализована, в первый раз что ли? Реализую свою!
88. cURL — это очень известная утилита, о которой вспоминают, в основном, когда нужно
#!/usr/bin/env curl -qsK 99.conf
# Written by Evgeny Stepanischev, Nov 2026
# 99.conf
url = 0
variable = b=xxxxxxxxx
variable = B=xxxxxxxxx
variable = "bottles=no bottles"
variable = output@final.txt
variable = r1=x0
variable = run=step.conf
expand-variable = dc[0-0]={{b}}{{B}}
expand-variable = run{{dc}}=/dev/null
expand-config = {{run}}
expand-write-out = {{output}}
# inc.conf
expand-variable = digit[1-1]={{c}}
expand-variable = c[2-]={{c}}
expand-variable = i={{carry}}{{digit}}
expand-variable = digit[{{i}}-{{i}}]=01234567891234567890
expand-variable = carry[{{i}}-{{i}}]=00000000000000000001
expand-variable = n1={{digit}}{{n1}}
expand-variable = r1={{r1}}x{{digit}}
expand-variable = dc[0-0]={{c}}
expand-variable = inc{{dc}}=/dev/null
expand-config = {{inc}}
# step.conf
expand-variable = dc[0-0]={{b}}
expand-variable = b{{dc}}=xxxxxxxxxx
expand-variable = B{{dc}}[1-]={{B}}
expand-variable = b[1-]={{b}}
expand-variable = dc[0-0]={{b}}{{B}}
expand-variable = run{{dc}}=/dev/null
expand-config = {{run}}
expand-variable = next={{bottles}}
variable = carry=1
expand-variable = c={{r1}}
variable = r1=
variable = n1=
variable = inc=inc.conf
config = inc.conf
expand-variable = n{{carry}}=1{{n1}}
expand-variable = r{{carry}}={{r1}}x1
expand-variable = "bottles={{n1}} bottle{{plural}}"
expand-variable = "output={{next}} of beer on the wall.\n\n{{output}}"
expand-variable = "output=Take one down and pass it around, {{output}}"
expand-variable = "output={{bottles}} of beer.\n{{output}}"
expand-variable = "output={{bottles}} of beer on the wall, {{output}}"
variable = plural=s
# final.txt
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
Для запуска нужен cURL версий 8.12…8.16, в более поздних рекурсию ограничили до пяти уровней, так что пример работать не будет.
У меня тут используется несколько трюков.
При помощи строковой конструкции var[1-] урезается контрольная строка, содержащая буквы «x». Таких строк две — одна содержит количество равное десяткам, другое — единицам.
Эта строки нужны для ветвления. Если взять первый символ конструкцией var[0-0], то добавив его к имени конфигурационного файла, можно получить условный переход — мы перейдём на config, если буквы закончились и на configx, если нет.
Таким образом, узнаём, что мы прошли всю длину контрольной строки. Параллельно мы точно так же отрезаем строку, содержащую цифры. Как только цикл остановился, срезаем первый символ и получаем нужную цифру, отдельно десятки и единицы, которые надо вывести.
На этих трюках основан весь код программы.
Комментарии 4
плюс учитывая что у квача своя виртуалка, это звучит еще менее реальным((