sed, 299 + 1
Sim, o sed pode encontrar uma lhama. Não, sed não pode fazer contas. Esta é a resposta mais longa até agora, com 299 + 1 caracteres, porque eu tive que ensinar sed a contar.
Esta resposta requer um sed com expressões regulares estendidas ( sed -Eou sed -r). Eu usei o OpenBSD sed (1) . A entrada é uma sequência por linha. (Portanto, a seqüência de caracteres pode não conter uma nova linha.) Saída é uma linha de números ou nada.
Uso (+1 caractere para -r):
$ echo 'All arms on all shoulders may ache.' | sed -rf llama.sed
1 2 12 26 30
Código fonte (299 caracteres):
s/%/z/g
s/(.*)[Aa]/\1%/
s/(.*)[Mm](.*%)/\1%\2/
s/(.*)[Aa]((.*%){2})/\1%\2/
s/(.*)[Ll]((.*%){3})/\1%\2/
s/(.*)[Ll]((.*%){4})/\1%\2/
/(.*%){5}/!d
s/[^%]/z/g
:w
s/(z*)%/\10 z\1/
s/z*$//
s/z0/1/
s/z1/2/
s/z2/3/
s/z3/4/
s/z4/5/
s/z5/6/
s/z6/7/
s/z7/8/
s/z8/9/
s/([0-9]z*)z9/z\10/g
s/(z*)z9/1\10/
/[%z]/bw
O programa primeiro substitui a lhama por cinco %. (Todos %neste programa são literais.) O primeiro comando s/%/z/galtera qualquer um %para zna linha de entrada. Os próximos cinco comandos encontram a lhama, então todos os braços em todos os ombros podem doer. torna-se A %% nos braços de% ll ombros% ay% che. Como cada um .*é ganancioso, sempre encontro a lhama à direita: lhama lhama se tornaria lhama %%%%% . Se eu não conseguir cinco %, /(.*%){5}/!dexclui a linha de entrada e pula os próximos comandos.
s/[^%]/z/gmuda todos os caracteres, exceto %para z. Então eu insiro um loop. s/(z*)%/\10 z\1/altera o primeiro %para 0, copia zero ou mais zda esquerda para a direita e adiciona mais um zpara a direita. É assim que o número de zserá igual ao índice. Por exemplo, zz%zzz%...torna-se zz0 zzzzzzzz%...porque o primeiro %estava no índice 2 e o próximo %no índice 8. s/z*$//remove extra zdo final da string.
Os próximos onze comandos contam z, removendo cada um deles ze contando 0. Ele conta como zzz0, zz1, z2, 3. Além disso, 1zzzz9torna-se z1zzz0(mais tarde 23) ou zzzz9torna - se 1zzz0(mais tarde 13). Esse loop continua até que não exista mais %ou z.