На сайте Карла Мэсака есть интересное руководство про то, как создавать программы для Perl Golf.
В качестве основы взята задача о расстановке восьми ферзей на шахматной доске.
На этом примере показано, как, написав вначале «многословный» код, методично сократить его. На каждом шаге показаны версии до и после преобразований.
На первом шаге убираются все комментарии. На втором — имена переменных и названия подпрограмм сокращаются до одной буквы. На третьем — циклы while заменяются вызовами функции grep. На четвертом код подпрограмм переносится в основную программу, что дает экономию на вызовах и определении фукнций. На пятом объединяются в цепочки условия в вызовах grep и вывод в аргументах print. На шестом шаге части кода, в которых использовался условный оператор if, объединяются в одну цепочку с помощью or.
Седьмой шаг, довольно хитрый, меняет направление счетчика в рекурсивном вывове функций. Вместо последовательного декремента счетчика он наоборот инкрементируется. Это позволяет не передавать начальное значение при первом вызове. То есть вместо
sub g {
my $l = shift;
. . .
($l > 1) and !g($l - 1)
. . .
}
g(8);
получается следующее:
sub g {
my $l = shift;
. . .
($l < 7) and !g($l + 1)
. . .
}
g;
На восьмом шаге происходят тонкие замены логических операторов. На девятом находится применение «секретному» оператору «детской коляски» (babycart) @{[]}. На десятом происходит еще одна смена направления — однако, на этот раз в списке из одного элемента: операция shift заменена вызовом pop. На одиннадцатом исчезает инструкция use strict. И, наконец, после двенадцатого шага пропадают необязательные пробелы:
sub g{my$l=pop;for$c(1..8){my$d;grep++$d==abs$c-$_|$c==$_,@_
or$l<7&!g($c,@_,$l+1)||print "@{[$c,@_]}\\n"}}g
P. S. О том, как решалась задача на YAPC::Russia::Golf 2009, рассказано в ЖЖ Андрея Завьялова.