Perl 5.10, 392 384 372 235 369 (ASCII) / 234 (Unicode)
Самая короткая версия ASCII длиной 369 символов:
@_=(fly,spider,bird,cat,dog);$_="There was an old lady who!ed a";for$P("",",
That wrJand Jand jJinside her",",
How absurd&",",
Imagine that&",",
What a hog&"){$p=$c;$c=$".shift@_;$t=$p?"She!ed the$c to catch the$p,
$t":"I don't know why she!ed that$c,
Perhaps she'll die.
$_";$_.="$c$P.
$t";s/&/ to! a$c/}s/!/ swallow/g;s/J/iggled /g;say"$_ horse,
She died of course."
Это началось с этой базовой программы:
my @animals = qw(fly spider bird cat dog);
my $buf = "There was an old lady who swallowed a ";
for my $phrase ( "",
",\nThat wriggled and iggled and jiggled inside her",
",\nHow absurd&",
",\nImagine that&",
",\nWhat a hog&" ) {
$previous = $current;
$current = shift @animals;
$trail = $previous ? "She swallowed the $current to catch the $previous,\n$trail"
: "I don't know why she swallowed that $current,\n"
. "Perhaps she'll die.\n\n$buf";
$buf .= "$current$phrase.\n$trail";
$buf =~ s/&/ to swallow a $current/;
}
say "$buf horse,\nShe died of course.";
Основная идея состоит в том, чтобы сохранить конец рифмы и начало следующего $trail
, увеличивая его по мере продвижения вперед. Это стало нетривиальным из-за необходимости особого случая для первого использования и попытки повторно использовать переменную имени животного даже в фразе, специфичной для животного. Дальнейшие оптимизации включают в себя:
- односимвольные идентификаторы для всего
- использование голых слов вместо строк в кавычках для списка животных
- использование аккумулятора
$_
для $buf
сокращения большинства операций замещения еще больше (использование @_
по привычке и не выигрывает ничего больше, чем любой другой символ)
- включая предшествующий пробел непосредственно внутри переменной имени животного (символ пробела, взятый из
$"
переменной)
- регулярное_выражение замены сократить наиболее распространенные фразы:
' swallow'
и'iggled '
- никакой пробел в коде и все
\n
в строковых литералах заменены реальными символами новой строки
Все, кроме последней оптимизации, дают следующее:
@_ = (fly, spider, bird, cat, dog);
$_ = "There was an old lady who!ed a";
for $P ( "",
",\nThat wrJand Jand jJinside her",
",\nHow absurd&",
",\nImagine that&",
",\nWhat a hog&" ) {
$p = $c;
$c = $" . shift @_;
$t = $p ? "She!ed the$c to catch the$p,\n$t"
: "I don't know why she!ed that$c,\nPerhaps she'll die.\n\n$_";
$_ .= "$c$P.\n$t";
s/&/ to! a$c/;
}
s/!/ swallow/g;
s/J/iggled /g;
say "$_ horse,\nShe died of course.";
Кроме того, этот гольф является жертвой недостаточно определенной кодировки. Поскольку на данный момент он подсчитывает отдельные символы вместо байтов в указанной кодировке, можно добиться большого выигрыша за счет декодирования исходного кода программы из UCS2 перед запуском. Окончательный результат уже не очень читабелен, но он короткий. (234 символа, считаются отличием от perl -E''
обычного) (мне пришлось включить завершающий перевод строки, чтобы сделать его действительным UCS2)
$ perl -MEncode=from_to -e'$_="䁟㴨晬礬獰楤敲Ɫ楲搬捡琬摯朩㬤弽≔桥牥⁷慳渠潬搠污摹⁷桯Ⅵ搠愢㭦潲⠢∬∬桡琠睲䩡湤⁊慮搠橊楮獩摥敲∬∬ੈ潷扳畲搦∬∬浡杩湥⁴桡琦∬∬桡琠愠桯朦∩笤瀽④㬤挽␢桩晴䁟㬤琽⑰㼢卨攡敤⁴桥④⁴漠捡瑣栠瑨攤瀬ਤ琢㨢䤠摯渧琠歮潷⁷桹桥Ⅵ搠瑨慴④Ⰺ健牨慰猠獨攧汬楥⸊ਤ弢㬤弮㴢④⸊⑴∻猯☯⁴漡④⽽猯ℯ睡汬潷⽧㭳⽊⽩杧汥搠⽧㭳慹∤张桯牳攬桥楥搠潦潵牳攮∊";from_to($_,utf8,ucs2);eval'
Хорошо, что до того, как прибегнуть к Unicode, нужно было много играть в гольф, иначе было бы не очень весело.
Редактировать: не могу найти способ скопировать / вставить 234-символьную версию в этот браузер, поэтому я оставляю 235-символьную версию. Это будет исправлено сегодня вечером, когда я возьму в руки настоящий буфер обмена с поддержкой UTF8. нашел способ. Квазиустойчиво на идеоне.