Saca la llama interior de una oración

33

Su objetivo es tomar aportes como

Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good.

y cree una matriz de los índices de la cadena donde aparecen las letras que forman la palabra "Llama" (una en orden). Por ejemplo, permítame mostrarle las letras señaladas con puntos para mostrar los índices:

Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good.
                                            ^                      ^        ^                            ^        ^

Entonces la matriz se vería así:

[44, 67, 76, 105, 114]

(Si su aplicación usa una indexación que no está basada en 0, los números se verán diferentes. Eso está bien).

Si el texto no tiene llama, la matriz debe estar vacía, nula, nula o indefinida.

Se acepta cualquier lenguaje de código. Este es un concurso de , por lo que ganan menos personajes.

Cilan
fuente
77
@TheWobbuffet Sigues cambiando tu nombre de usuario y foto. Hubo un tiempo en que eras "Pomo de la puerta" y tenías su foto. Ahora, tu foto es una oveja. Deberías cambiarlo por una llama.
Justin
1
¿Qué pasa con la indexación basada en 0 frente a 1? ¿Podemos usar la indexación utilizada por nuestro lenguaje o todos los envíos deben cumplir con una convención (cuál)?
Martin Ender
1
@Quincunx ¡La oveja dice '42' en ella!
Cilan
2
@TheWobbuffet demasiados orientados a las matemáticas: - / (Matlab, Mathematica, Julia, no sé sobre R) ... también Lua y Smalltalk. Sin embargo, el único de los relevantes para el golf de código sería Mathematica, pero probablemente no para las tareas de manipulación de cuerdas.
Martin Ender
3
¿Solo quieres la función que lo hace o todo el programa? ¿Quieres el código de entrada / salida también?
jzm

Respuestas:

11

CJam - 33

lel"llama"{1$#)_T+:T\@>}/;]___|=*

Obtiene los índices basados ​​en 1 (2 bytes más para 0)

Explicación:

llee una línea de la entrada (reemplaza qpor entrada completa)
elconvierte a minúscula
"llama"{...}/ejecuta el bloque para cada letra "llama"
1$copia la cadena actual
#encuentra el índice de los
)_incrementos de letras y duplicados
T+:Tagrega T (inicialmente 0), actualiza T y lo deja en la pila
\@intercambia elementos alrededor, ahora tenemos el actual-T, el índice, los
>cortes de cadena, la cadena que comienza en el índice
;emerge, la cadena restante
]reúne los índices en una matriz.
En este punto tenemos todos los índices basados ​​en 1; Si no se encuentra ninguna letra, la matriz tendrá duplicados.
___realiza 3 copias más de la matriz
|(con 2 copias de matriz) elimina duplicados
=compara, lo que resulta en 0 si hubo duplicados o 1 si no
*multiplica la matriz 0 o 1 veces en consecuencia

aditsu
fuente
sourceforge.net/p/cjam/wiki/Home para obtener más información sobre el idioma. Nuevo para mi
TankorSmash 05 de
12

Perl, 52 bytes

La solución se proporciona como una función que toma la cadena como argumento y devuelve una lista de posiciones.

  • Posiciones basadas en uno, búsqueda entre mayúsculas y minúsculas, sin nuevas líneas: 52 bytes

    sub l{pop=~/(l).*?(l).*?(a).*?(m).*?(a)/;@+[1..$#+]}

    La búsqueda entre mayúsculas y minúsculas devuelve una matriz vacía en el ejemplo de la pregunta, porque después de hacer coincidir las tres primeras letras, mfalta la letra minúscula en el texto de entrada.

  • Soporte de nuevas líneas: + 1 byte = 53 bytes

    sub l{pop=~/(l).*?(l).*?(a).*?(m).*?(a)/s;@+[1..$#+]}

    El texto ahora puede abarcar varias líneas.

  • Búsqueda sin distinción entre mayúsculas y minúsculas: + 1 byte = 54 bytes

    sub l{pop=~/(l).*?(l).*?(a).*?(m).*?(a)/si;@+[1..$#+]}

    Ahora el ejemplo en la pregunta informa una lista de posiciones de índice, son números basados ​​en uno:

    [45 68 77 106 115]
    
  • Posiciones basadas en cero: + 9 bytes = 63 bytes

    sub l{pop=~/(l).*?(l).*?(a).*?(m).*?(a)/si;map{$_-1}@+[1..$#+]}

    Resultado para el ejemplo en la pregunta:

    [44 67 76 105 114]
    

Sin golf:

La última variante incluye más o menos las otras variantes.

sub l {
    # pop() gets the last argument 
    pop() =~ /(l).*?(l).*?(a).*?(m).*?(a)/si;
    # the letters inbetween are matched against ".*?",
    # the non-greedy variant of ".*". Thus ".*?"
    # matches only as few as possible characters.
    # The modifier /i controls the case-sensitivity
    # and means ignore case. Without the case matters.
    # Modifier /s treats the string as single line,
    # even if it contains newlines.
    map { $_-1 }   # subtract 1 for zero-based positions
        @+[1..$#+]
    # Array @+ contains the end-positions of the last
    # submatches, and of the whole match in the first position.
    # Therefore the first value is sliced away.
    # @+ is available since Perl 5.6.
}

# test
my @result = l(<<"END_STR");
Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good.
END_STR
print "[@result]\n";
Heiko Oberdiek
fuente
1
Esto también supone que la entrada es ASCII, o al menos no Unicode completo. A menos expresiones regulares de Perl respetan correctamente los límites de grafema estos días (que ciertamente no lo hizo hacia atrás cuando tuve la desgracia de usarlo.)
Trejkaz
@Trejkaz: Unicode no importa en absoluto aquí: (a) "llama" es ASCII y sus letras no chocan con ningún carácter Unicode que no sea ASCII o su representación de bytes en UTF-8. (b) Con las codificaciones de múltiples bytes en mente, el término "índice" en la pregunta estaría subespecificado. El índice puede relacionarse con la posición del carácter o la posición del byte (almacenamiento). (c) Apoyar cualquier codificación con posiciones de caracteres significaría que la codificación debe ser conocida y debe proporcionarse como argumento adicional.
Heiko Oberdiek
Sus primeras dos soluciones se imprimen []y la tercera se imprime [ ]para mí (las más largas funcionan correctamente). Estoy ejecutando "perl, v5.8.8 creado para msys-64int". ¿Tiene un error o funciona en una versión diferente de perl?
Tim S.
@TimS .: []es correcto para la primera solución, Mno coincide en una búsqueda sensible a mayúsculas y minúsculas. La pregunta no está clara con respecto a la sensibilidad a mayúsculas y minúsculas.
Heiko Oberdiek
Ok, entonces []es aceptable para los dos primeros. Pero las tres primeras soluciones todavía no funcionan bien para mí: si le das una entrada que debería devolver índices, vuelve[ ]
Tim S.
10

sed, 299 + 1

Sí, sed puede encontrar una llama. No, sed no puede hacer matemáticas. Esta es la respuesta más larga hasta ahora, con 299 + 1 caracteres, porque tuve que enseñarle a contar.

Esta respuesta requiere un sed con expresiones regulares extendidas ( sed -Eo sed -r). Usé OpenBSD sed (1) . La entrada es una cadena por línea. (Por lo tanto, la cadena puede no contener una nueva línea). La salida es una línea de números, o nada.

Uso (+1 carácter para -r):

$ echo 'All arms on all shoulders may ache.' | sed -rf llama.sed
1 2 12 26 30 

Código fuente (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

El programa primero reemplaza la llama por cinco %. (Todos %en este programa son literales). El primer comando s/%/z/gcambia cualquiera %a zen la línea de entrada. Los siguientes cinco comandos encuentran la llama, por lo que todos los brazos en todos los hombros pueden doler. se convierte en A %% brazos en% ll hombros% ay% che. Como cada uno .*es codicioso, siempre encuentro la llama a la derecha: llama llama se convertiría en llama %%%%% . Si no puedo obtener cinco %, /(.*%){5}/!dborra la línea de entrada y omite los siguientes comandos.

s/[^%]/z/gcambia cada personaje excepto %a z. Entonces entro en un bucle. s/(z*)%/\10 z\1/cambia el primero %a 0, copia cero o más zde izquierda a derecha y agrega uno más za la derecha. Esto es para que el número de zsea ​​igual al índice. Por ejemplo, se zz%zzz%...convierte en zz0 zzzzzzzz%...porque el primero %estaba en el índice 2, y el siguiente %en el índice 8. s/z*$//elimina más zdel final de la cadena.

Los siguientes once comandos cuentan zeliminando cada uno zy contando desde 0. Se cuenta como zzz0, zz1, z2, 3. Además, se 1zzzz9convierte z1zzz0(más tarde 23) o se zzzz9convierte 1zzz0(más tarde 13). Este ciclo continúa hasta que no haya más %o z.

kernigh
fuente
1
+1 por enseñar a contar. Es más fácil enseñarle a una llama a contar que a la sed.
Andreï Kostyrka
9

Fortran - 154 148

Fortran apesta al golf, pero solo para demostrar que las cadenas de análisis se pueden hacer en un lenguaje matemático, lo hice:

function f result(r);integer::r(5),j=1;do i=1,len(s);if(s(i:i)==a(j:j).or.s(i:i)==b(j:j)) then;r(j)=i;j=j+1;endif;enddo;if(any(r==0))r=0;endfunction

Ahorré algunos caracteres al eliminar lo no requerido fal final endfunctiony lo usé en if(any(r==0))lugar de if(.not.all(r>0)).

Esto requiere:

  1. s ser la cadena con texto
  2. aser la prueba en minúscula (es decir, llama)
  3. bser la prueba de mayúsculas (es decir, LLAMA)

El programa completo sin golf es

program find_llama
   character(len=123) :: s = "Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good."
   character(len=5) :: a="llama",b="LLAMA"

   print *,f()
 contains
   function f result(r)
     integer::r(5),j=1
     do i=1,len(s)
        if(s(i:i)==a(j:j).or.s(i:i)==b(j:j)) then
           r(j)=i
           j=j+1
        endif
     enddo
     if(any(r==0)) r=0
   end function
end program find_llama
Kyle Kanos
fuente
Fortran moderno al menos está permitido en las áreas de pitch & putt. FORTRAN IV todavía estaría jugando al golf loco.
ClickRick
44
@ClickRick: Fortran IV es algo que no he aprendido. No estoy seguro de quererlo. Algo sobre sangría forzada y capitalización me perturba.
Kyle Kanos 05 de
7

C # - 119

Toma cadena, emite matriz. Nulo si no hay llama en cadena.

int[]a(string s){var i=0;var o="llama".Select((x,y)=>i=s.IndexOf(x,y>0?i+1:0));return o.All(x=>x>=0)?o.ToArray():null;}
jzm
fuente
1
+1 parax=>x>=0
ClickRick
Estoy impresionado. Mucho más pequeño que cualquiera de mis ideas para este. Descubrí que podría hacerlo más pequeño inicializando ia -1 y colocando .ToArray () en la instrucción int[]a(string s){var i=-1;var o="llama".Select(x=>i=s.IndexOf(x,i+1)).ToArray();return o.All(x=>x>=0)?o:null;}
.Select
7

Rubí, 56 65 63

Editar : +9 caracteres para que no distinga entre mayúsculas y minúsculas.

Define una función (lambda, técnicamente) f.

f=->s{i=0;'LLAMA'.chars.map{|c|i=s.upcase.index(c,i+1)||break}}

Devuelve nilsi no hay llama. Si tiene que ser [](matriz vacía), simplemente agregue ||[]antes del último }para un total de 4 caracteres adicionales .

Versión legible:

innerLlama = -> str{
    index = 0;
    str.downcase!
    arr = 'llama'.each_char.map{|char|
        index = str.index(char, index + 1)
        break unless index
    }
    # uncomment this line for empty array on failure
    #arr || []
}
Pomo de la puerta
fuente
Pido disculpas por editar mi pregunta después de un tiempo, pero acabo de agregar que la matriz, si no hay llama, puede ser nula, nula, vacía o indefinida.
Cilan
21
¿Entonces lo hiciste con una llambda?
Mason Wheeler
@Doorknob sería dos bytes más corto usando upcase en lugar de downcase no?
dstarh
@dstarh Sí, gracias
Pomo
Piensa que puedes obtener insensibilidad de mayúsculas y minúsculas un byte más barato haciendo en index(/#{c}/ilugar de upcase.
histocrat
6

C - 53

Compilar con:

gcc -D L=\"llama\" -D W=\"Lie\ is\ good.\ \ I\ just\ ate\ a\ bunch\ of\ pies\ early\ this\ morning.\ \ Actually,\ it\ was\ closer\ to\ the\ afternoon.\ \ Mornings\ are\ good.\"

Probé este comando de compilación con el gcc de cygwin. Otros entornos pueden manejar espacios y otros caracteres especiales de manera diferente.

El resultado basado en 0 se almacena en la matriz r. Su contenido no está definido si no hay llama en la cadena.

  • Mayúsculas y minúsculas (53)

    i,m,r[5];main(){for(;W[i];i++)W[i]==L[m]?r[m++]=i:i;}

  • No distingue entre mayúsculas y minúsculas (58)

    i,m,r[5];main(){for(;W[i];i++)(W[i]|96)==L[m]?r[m++]=i:i;}

Allbeert
fuente
4

JavaScript (ECMAScript 6) - 68 caracteres

(/((((.*l).*l).*a).*m).*a/.exec(s)||[]).map(x=>x.length-1).reverse()

Asume que la cadena a probar está en la variable s. Si quieres convertirlo en una función, entonces anteponef=s=> (para 5 caracteres adicionales).

Salidas:

[]

Caso insensible - 69 caracteres

(/((((.*l).*l).*a).*m).*a/i.exec(s)||[]).map(x=>x.length-1).reverse()

Salidas:

[68, 80, 93, 105, 114]

Case Insensitive & First Match - 74 caracteres

(/((((.*?l).*?l).*?a).*?m).*?a/i.exec(s)||[]).map(x=>x.length-1).reverse()

Salidas:

[44, 67, 76, 105, 114]
MT0
fuente
4

Python, 100

Soy el peor golfista de todos los tiempos. :PAGS

Gracias a @xnor por reducir 6 bytes.

g,n,o='llama',0,[]
for i in s:
 if g:exec("o+=[n];g=g[1:];"*(i.lower()==g[0])+"n+=1")
o*=len(o)>4

o contiene la matriz después.

EDITAR : fijo.

EDIT 2 : len(g)to g, o==5to o>4según las sugerencias de @ xnor.

EDITAR 3 : @WolframH lo arregló.

cjfaure
fuente
2
o*=(len(o)==5) is excellent. It's horrible, but I love it!
kevinsa5
I don't think the outer parentheses on that line are necessary. You could save two characters by removing them.
user2357112 supports Monica
@user2357112 On that second last line? I'll remove 'em.
cjfaure
I assume s is the input string, right? Shouldn't then s.lower be i.lower? However, that doe
Reinstate Monica
@WolframH ah, yes, will fix tomorrow.
cjfaure
3

Python 71

Assumes input in s. Output in o.

F=s.lower().find
o=F('l'),
for c in'lama':o+=F(c,o[-1]+1),
o*=min(o)>=0

Edit: Changed from lists to tuples to save 2 bytes.

Reinstate Monica
fuente
1
Multiplying lists by booleans is fun, isn't it? ;D
cjfaure
I like how you dodge the problem of o needing to start nonempty to take o[-1]. Maybe it's shorter though to just start o as [-1] and later do o=o[1:]? Annoyingly, the initial -1 trips up checking if o contains -1.
xnor
@xnor: I don't think the -1-Idea can be made to work. At least, I didn't succeed :-( However, I changed lists to tuples to save 2 bytes. :-)
Reinstate Monica
2

Python 100

import re
x=input()
print[re.search(r"l.*?(l).*?(a).*?(m).*?(a)",x,re.I).start(i) for i in range(5)]

Sample:

in  = Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good.
out = [44, 67, 76, 105, 114]
in[out] = ['l', 'l', 'a', 'M', 'a']
Kaya
fuente
2

Haskell, 111

import Data.Char
l i(a:as)t@(b:bs)|a==b=i:l(i+1)as bs|True=l(i+1)as t
l _ _ _=[]
r s=l 0(map toUpper s)"LLAMA"

Ungolfed:

import Data.Char

llama :: Int -> String -> String -> [Int]
llama i (a:as) t@(b:bs)
  | a==b      = i : llama (i+1) as bs
  | otherwise = llama (i+1) as t
llama _ _ _ = []

runme :: String -> [Int]
runme s = llama 0 (map toUpper s) "LLAMA"

Example:

*Main> r "Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good."
[44,67,76,105,114]
danmcardle
fuente
2

Matlab, 61 96

Searches the string and replaces everything up to each match with gibberish before searching for next character. Will leave s undefined if an the word does not occur.

t='llama';for q=1:5;s(q)=min(regexpi(z,t(q))),z(1:s(q))=0;end

Note that the charcount could be reduced if case sensitivity is allowed.

Previous versions

 try;t='llama';for q=1:length(t);s(q)=find(lower(z)==t(q),1);z(1:s(q))=ones(1,s(q));end;catch;end

Searches the string and replaces everything up to each match with gibberish before searching for next character. Error handling (try-catch-end) could maybe be dropped, then the program would crash (but s would be undefined as required) if llama not found.

Implementation:

>> z='Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good.';
>> try;t='llama';for q=1:length(t);s(q)=find(lower(z)==t(q),1);z(1:s(q))=ones(1,s(q));end;catch;end
>> s
s =

    45    68    77   106   115

Without error handling:

t='llama';for q=1:length(t);s(q)=find(lower(z)==t(q),1);z(1:s(q))=ones(1,s(q));end
Jørgen
fuente
Like the idea, have reduced charcount a bit.
Dennis Jaheruddin
2

Language Java

 final int[] wordIndexInSentence(String sentence, String word)
  {
    final int[] returnArr = new int[word.length()];
    int fromIndex = 0;
    word = word.toUpperCase();
    sentence = sentence.toUpperCase();
    for (int i = 0; i < word.length(); i++)
    {
      final char c = word.charAt(i);
      returnArr[i] = sentence.indexOf(c, fromIndex);
      fromIndex = returnArr[i] > 0 ? returnArr[i] + 1 : fromIndex;
    }
    return returnArr;
  }
Sudarshana
fuente
2

Python (70)

r=[];c=-1
for x in'llama':c=s.lower().find(x,c+1);r+=[c]
r*=1-(-1in r)

We search of each character in 'llama' in turn, starting after the location of the previously-found character. If no character is found, c becomes the default value of -1, in which case the last line turns r into the empty list.

Edit: Found out that str.find(s,...) can be invoked as s.find(...), saving 4 characters.

xnor
fuente
2

OpenEuphoria, 147128

I have two examples. First, the shortest:

object t=and_bits(gets(0),#DF),L="LLAMA",i=0,X={}for j=1 to 5 do 
i=find(L[j],t,i+1)X&=i 
end for 
if find(0,X) then X={} end if?X

I can get it down to 126 characters if I use "or" instead of "and" like the C version does up above. However, this also matches the string ''!-! as llama. Uncommon, but still a possible error.

object t=or_bits(gets(0),96),L="llama",i=0,X={}for j=1 to 5 do 
i=find(L[j],t,i+1)X&=i 
end for 
if find(0,X) then X={} end if?X

And then the version using regular expressions:

include std/regex.e
include std/sequence.e
include std/utils.e
object X=regex:find(new("(?i)(l).*?(l).*?(a).*?(m).*?(a)"),gets(0))
? iff(atom(X),{},vslice(X[2..6],2))

Both take input from STDIN and post to STDOUT.

EDIT: Shorter regex example:

include std/regex.e
include std/sequence.e
object X=regex:find(new("(?i)(l).*?(l).*?(a).*?(m).*?(a)"),gets(0))
if atom(X)then?{}else?vslice(X[2..6],2)end if
TinSoldier
fuente
Is it possible to save a few by building the regex with split/join or explode/implode, or does OpenEuphoria not have short versions of those?
Peter Taylor
OpenEuphoria can do split/join with strings of characters, but I don't see a way to do it in a shorter manner. I'm not very good with regular expressions; the regex used here was "inspired" (shamelessly stolen) from one of the other examples on this page.
TinSoldier
2

Powershell - 121 85

I'm still practicing with Powershell, expect this could be improved

$s contains the string, result is in array $a

Original version

$a=@();$w="llama";$n=$c=0;foreach ($i in $s.tochararray()) {if ($i -eq $w[$n]) {$a+=$c;$n+=1} $c+=1};$a*=$a.length -gt 4

Ungolfed

$a=@()
$w="llama"
$n=$c=0
foreach ($i in $s.tochararray()) {
 if ($i -eq $w[$n]) {
  $a+=$c
  $n+=1
 } $c+=1
}
$a*=$a.length -gt 4

New version, with massive thanks to @goric

$a=@();$n=$c=0;[char[]]$s|%{if($_-eq"llama"[$n]){$a+=$c;$n++}$c++};$a*=$a.length-gt4
Brian
fuente
You can remove a lot of spaces in there to shorten things up to 112: $a=@();$w="llama";$n=$c=0;foreach($i in $s.tochararray()){if($i-eq$w[$n]){$a+=$c;$n+=1}$c+=1};$a*=$a.length-gt4
goric
Also, you can replace foreach($i in $s.tochararray()) with [char[]]$s|%, as long as you change the subsequent $i to a $_. That shaves it down to 93: $a=@();$w="llama";$n=$c=0;[char[]]$s|%{if($_-eq$w[$n]){$a+=$c;$n+=1}$c+=1};$a*=$a.length-gt4
goric
Save 5 more chars by removing the $w variable altogether, since its only used once. Just inline it into the if: if($i-eq"llama"[$n])
goric
..and, of course, replace your +=1s with ++s
goric
1

PHP

no PHP answer yet? I think a language heavily string-oriented can beat at least a math-based one

function x($s){$i=$j=0;$r=str_split('llama');$s=strtolower($s);while($i<strlen($s)){if($s[$i]==$r[$j]){$r[$j]=$i;$j++;if($j>4)return$r;}$i++;}return[];}

152 against fortran 154, job done :P

ungolfed

function x($s){
    $i=$j=0;$r=str_split('llama');
    $s=strtolower($s);
    while($i<strlen($s)){
        if ($s[$i]==$r[$j]){
            $r[$j]=$i;
            $j++;
            if($j>4)
                return $r;
        }
        $i++;
    }
    return[];
}

if the caller always passes a lowercase string, it lowers to 137

Einacio
fuente
You need to add <? at the beginning of your code to make it valid. Sorry...
avall
1

JavaScript, 122 115

function(s,b){z=[];for(i=0;i<5;i++){z.push(b=s.toLowerCase().indexOf("llama"[i],++b))};return z.indexOf(-1)<0?z:[]}

Defines a function that takes a string as its only argument (second arg is a cheap var) and returns either an empty array or a 5-element array.

Drops to 108 if I take the input on a single char variable (s) and leave the output in another (b):

var b=((z="llama".split('').map(function(a){return (b=s.toLowerCase().indexOf(a,++b))})).indexOf(-1)<0?z:[])

Edit: Swapped out map for for loop.

Aaron Dufour
fuente
ECMAScript 6 version (81 characters) - b=(z=[].map.call("llama",a=>b=s.toLowerCase().indexOf(a,++b))).indexOf(-1)<0?z:[]
MT0
1

Rebol, 97

f: func[s][a: copy[]foreach n"llama"[if none? s: find s n[return[]]append a index? s s: next s]a]

Usage example in Rebol console:

>> f "Pie is good.  I just ate a bunch of pies early this morning.  Actually, it was closer to the afternoon.  Mornings are good." 
== [45 68 77 106 115]

>> f "nearly llami"       
== []

>> f "Llama"
== [1 2 3 4 5]

>> f reverse "llama"
== []

Rebol uses 1-based indexing. Returns empty list [] if no llama sequence found (case insensitive).

Ungolfed:

f: func [s] [
    a: copy []
    foreach n "llama" [
        if none? s: find s n [return []]
        append a index? s
        s: next s
    ]
    a
]
draegtun
fuente
1

APL, 47

+\↑⊃{a s←⍵⋄~⍺∊s:⍬⍬⋄a,←n←s⍳⍺⋄a(n↓s)}/'amall',⊂⍬⍞

Not the shortest code, but quite warped, in an APL way.

Explanation

'amall',⊂⍬⍞ Make an array of 6 elements: the letters 'amall' and a subarray of 2 elements, themselves subarrays: the empty array and a line of characters read from input.

{...}/... Reduce (right-fold) the 6-element array using the provided function.

a s←⍵ Decompose the right argument into the array of indices and the remaining substring (initially the empty array and the full string.)

~⍺∊s:⍬⍬ If the substring does not contain the next letter stop the computation and return the empty array.

a,←n←s⍳⍺ Otherwise, find its position, call it n, and append it to the array of indices.

a(n↓s) Make and return an array of 2 elements: the extended array of indices and the remaining substring.

+\↑⊃... Unpack the output of the folding, take the first element (the array of indices) and scan it with addition, to turn relative offsets into absolute ones.

Examples

      +\↑⊃{a s←⍵⋄~⍺∊s:⍬⍬⋄a,←n←s⍳⍺⋄a(n↓s)}/'amall',⊂⍬⍞
All cats meow aloud.
2 3 6 10 15

 

      +\↑⊃{a s←⍵⋄~⍺∊s:⍬⍬⋄a,←n←s⍳⍺⋄a(n↓s)}/'amall',⊂⍬⍞
Some cats purr instead.
 
Tobia
fuente
1

Julia, 76

Another regex example using Julia language.

f(s)=(m=match(r"(?i)(l).*?(l).*?(a).*?(m).*?(a)",s);m==nothing?m:m.offsets)
TinSoldier
fuente