Sortez le lama intérieur d'une phrase

33

Votre objectif est de prendre des entrées comme

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

et créez un tableau des index de la chaîne où apparaissent les lettres constituant le mot "Lama" (une de chaque dans l'ordre). Par exemple, laissez-moi montrer les lettres pointées avec des carets pour montrer les index:

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

Donc, le tableau ressemblerait à:

[44, 67, 76, 105, 114]

(Si votre application utilise une indexation qui n'est pas basée sur 0, les chiffres seront différents. C'est très bien.)

Si le texte n'a pas de lama, le tableau doit alors être vide, nul, nul ou non défini.

Toute langue de code est acceptée. Ceci est un concours de , donc les moins de personnages gagnent!

Cilan
la source
7
@TheWobbuffet Vous continuez à changer votre nom d'utilisateur et votre image. Il fut un temps où vous étiez "Doorknob" et que vous aviez sa photo. Maintenant, votre photo est un mouton. Vous devriez le changer en un lama.
Justin
1
Qu'en est-il de l'indexation 0 vs 1? Pouvons-nous simplement utiliser l'indexation utilisée dans notre langue ou est-ce que toutes les soumissions doivent être conformes à une convention (laquelle)?
Martin Ender
1
@Quincunx Le mouton dit '42' dessus!
Cilan
2
@ TheWobbuffet beaucoup trop orientés vers les mathématiques: - / (Matlab, Mathematica, Julia, je ne sais pas à propos de R) ... aussi Lua et Smalltalk. Mathematica est toutefois le seul élément pertinent pour le golf de code, mais probablement pas pour les tâches de manipulation de chaînes.
Martin Ender
3
Voulez-vous juste la fonction qui le fait ou tout le programme? Voulez-vous également le code d'entrée / sortie?
Jzm

Réponses:

11

CJam - 33

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

Il obtient les index basés sur 1 (2 octets supplémentaires pour les basés sur 0)

Explication:

llit une ligne depuis l'entrée (remplacer par qpour l'entrée entière)
elconvertit en minuscule
"llama"{...}/exécute le bloc pour chaque lettre "lama"
1$copie la chaîne en cours
#trouve l'index de la lettre
)_incrémente et duplique
T+:Tajoute T (initialement 0), met à jour T et la quitte sur la pile,
\@permute les éléments, nous avons maintenant current-T, index, string
>coupe la chaîne en commençant par l'index,
;la chaîne restante
]rassemble les index dans un tableau.
À ce stade, nous avons tous les index basés sur 1; Si une lettre n’a pas été trouvée, le tableau aura des doublons.
___fait 3 copies de plus du tableau
|(avec 2 copies de tableau) supprime les doublons
=compare, résultant en 0 s'il y avait des doublons ou 1 sinon
*multiplie le tableau 0 ou 1 en conséquence

Aditsu
la source
sourceforge.net/p/cjam/wiki/Home pour plus d'informations sur la langue. Nouveau pour moi.
TankorSmash
12

Perl, 52 octets

La solution est fournie en tant que fonction qui prend la chaîne en tant qu'argument et renvoie une liste de positions.

  • Positions uniques, recherche sensible à la casse, sans saut de ligne: 52 octets

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

    La recherche sensible à la casse renvoie un tableau vide dans l'exemple de la question, car après la mise en correspondance des trois premières lettres, la lettre minuscule mmanque dans le texte saisi.

  • Prise en charge des nouvelles lignes: + 1 octet = 53 octets

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

    Le texte peut maintenant s'étendre sur plusieurs lignes.

  • Recherche insensible à la casse: + 1 octet = 54 octets

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

    Maintenant, l'exemple dans la question rapporte une liste de positions d'index, ce sont des nombres à une base:

    [45 68 77 106 115]
    
  • Positions basées sur zéro: + 9 octets = 63 octets

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

    Résultat pour l'exemple dans la question:

    [44 67 76 105 114]
    

Ungolfed:

Cette dernière variante comprend plus ou moins les autres 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
la source
1
Cela suppose également que l’entrée est ASCII, ou du moins pas complète Unicode. À moins que les expressions rationnelles de Perl respectent correctement les limites des graphèmes ces temps-ci (elles ne l'ont certainement pas fait quand j'ai eu le malheur de l'utiliser).
Trejkaz
@Trejkaz: Unicode n'a pas d'importance du tout ici: (a) "llama" est un ASCII et ses lettres n'entrent en conflit avec aucun caractère Unicode non-ASCII ni sa représentation d'octet en UTF-8. (b) En gardant à l'esprit les codages sur plusieurs octets, le terme "index" dans la question serait sous-spécifié. L'index peut être associé à la position du caractère ou à la position de l'octet (stockage). (c) Soutenir tout codage avec des positions de caractères signifierait que le codage devrait être connu et doit être fourni en tant qu'argument supplémentaire.
Heiko Oberdiek
Vos deux premières solutions s'impriment []et la troisième s'imprime [ ]pour moi (les plus longues fonctionnent correctement). J'utilise "perl, v5.8.8 construit pour msys-64int". Avez-vous un bogue ou fonctionne-t-il sur une version différente de perl?
Tim S.
@TimS .: []est correct pour la première solution, Mne correspond pas à une recherche sensible à la casse. La question n'est pas claire en ce qui concerne la sensibilité à la casse.
Heiko Oberdiek
Ok, donc []est acceptable pour les deux premiers. Mais les trois premières solutions ne fonctionnent toujours pas correctement pour moi: si vous lui donnez une entrée qui devrait renvoyer des index, elle retourne[ ]
Tim S.
10

sed, 299 + 1

Oui, Sed peut trouver un lama. Non, Sed ne peut pas faire de maths. C’est la réponse la plus longue à ce jour, avec 299 + 1 caractères, car j’ai dû apprendre à sed à compter.

Cette réponse nécessite un sed avec des expressions régulières étendues ( sed -Eou sed -r). J'ai utilisé OpenBSD sed (1) . L'entrée est une chaîne par ligne. (Par conséquent, la chaîne ne peut pas contenir de nouvelle ligne.) La sortie est une ligne de chiffres ou rien.

Utilisation (+1 caractère pour -r):

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

Code source (299 caractères):

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

Le programme remplace d'abord le lama par cinq %. (Tout %dans ce programme sont littéral.) La première commande s/%/z/gchange tout %à zla ligne d'entrée. Les cinq prochains ordres trouvent le lama, de sorte que tous les bras sur les épaules peuvent faire mal. devient A %% bras sur% ll épaules% ay% che. Parce que chacun .*est gourmand, je trouve toujours le lama sur la droite: lama lama deviendrait lama %%%%% . Si je ne peux pas en obtenir cinq %, /(.*%){5}/!dsupprime la ligne de saisie et ignore les commandes suivantes.

s/[^%]/z/gchange tous les caractères , mais %à z. Puis j'entre dans une boucle. s/(z*)%/\10 z\1/change le premier %en 0, copie zéro ou plus zde gauche à droite et ajoute un de plus zà droite. C'est ainsi que le nombre de zsera égal à l'indice. Par exemple, zz%zzz%...devient zz0 zzzzzzzz%...parce que le premier %était à l'index 2 et le suivant %est à l'index 8. s/z*$//supprime extra zde la fin de la chaîne.

Les onze prochaines commandes comptent zen supprimant chacune d’elles zet en comptant à partir de 0. Il compte comme zzz0, zz1, z2, 3. En outre, 1zzzz9devient z1zzz0(plus tard 23) ou zzzz9devient 1zzz0(plus tard 13). Cette boucle continue jusqu'à ce qu'il n'y en ait plus %ou z.

Kernigh
la source
1
+1 pour apprendre à sed à compter. Il est plus facile d'apprendre à un lama à compter que sed.
Andreï Kostyrka
9

Fortran - 154 148

Fortran craint au golf, mais juste pour prouver que l’analyse de chaînes peut être faite dans un langage basé sur les mathématiques, je l’ai fait:

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

J'ai sauvé quelques caractères en éliminant les non-requis fà la fin endfunctionet utilisés à la if(any(r==0))place de if(.not.all(r>0)).

Cela nécessite:

  1. s être la chaîne avec du texte
  2. aêtre le test minuscule (c.-à-d. llama)
  3. bêtre le test majuscule (c.-à-d. LLAMA)

Le programme complet sans golf est

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
la source
Le Fortran moderne est au moins autorisé dans les zones de pitch & putt. Fortran IV serait toujours en train de jouer au golf fou.
ClickRick
4
@ClickRick: Fortran IV est quelque chose que je n'ai pas appris. Pas sûr que je veuille. Quelque chose à propos de l'indentation forcée et de la capitalisation me dérange.
Kyle Kanos
7

C # - 119

Prend chaîne, sorties tableau. Null si pas de lama dans la chaîne.

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
la source
1
+1 pourx=>x>=0
ClickRick
Je suis impressionné. Bien plus petit que n'importe lequel de mes idées pour celui-ci. J'ai trouvé que vous pouviez le réduire en initialisant ià -1 et en plaçant le .ToArray () sur l'instruction .Select, comme ceciint[]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;}
Grax32
7

Ruby, 56 65 63

Edit : +9 caractères pour qu'il ne respecte pas la casse.

Définit une fonction (lambda, techniquement) f.

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

Retourne nils'il n'y a pas de lama. Si ce doit être [](tableau vide), alors il suffit d’ajouter ||[]avant le dernier }pour un total de 4 caractères supplémentaires .

Version lisible:

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 || []
}
Poignée de porte
la source
Je m'excuse d'avoir modifié ma question après un certain temps, mais je viens d'ajouter que le tableau, s'il n'y a pas de lama, peut être nil, null, vide ou indéfini.
Cilan
21
Alors vous l'avez fait avec un llambda?
Mason Wheeler
@Doorknob serait deux octets plus court en utilisant upcase au lieu de downcase no?
dstarh
@dstarh Oui, merci
Bouton de porte
Pensez que vous pouvez obtenir un octet moins cher en insensible à la casse index(/#{c}/iau lieu de upcase.
histocrat
6

C - 53

Compiler avec:

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.\"

J'ai testé cette commande de compilation avec le gcc de cygwin. D'autres environnements peuvent gérer des espaces et d'autres caractères spéciaux différemment.

Le résultat basé sur 0 est stocké dans un tableau r. Son contenu n'est pas défini s'il n'y a pas de lama dans la chaîne.

  • Sensible à la casse (53)

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

  • Insensible à la casse (58)

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

Allbeert
la source
4

JavaScript (ECMAScript 6) - 68 caractères

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

Suppose que la chaîne à tester est dans la variable s. Si vous voulez en faire une fonction, ajoutez des préfixes f=s=>(pour 5 caractères supplémentaires).

Les sorties:

[]

Insensible à la casse - 69 Caractères

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

Les sorties:

[68, 80, 93, 105, 114]

Insensible à la casse et premier match - 74 caractères

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

Les sorties:

[44, 67, 76, 105, 114]
MT0
la source
4

Python, 100

Je suis le pire golfeur de tous les temps. : P

Merci à @xnor d'avoir supprimé 6 octets.

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 contient le tableau après.

EDIT : corrigé.

EDIT 2 : len(g)to g, o==5to o>4selon les suggestions de @ xnor.

EDIT 3 : @WolframH l'a corrigé.

cjfaure
la source
2
o*=(len(o)==5)est excellent . C'est horrible, mais j'adore ça!
kevinsa5
Je ne pense pas que les parenthèses extérieures sur cette ligne soient nécessaires. Vous pouvez enregistrer deux personnages en les supprimant.
user2357112 prend en charge Monica
@ user2357112 Sur cette dernière dernière ligne? Je vais les enlever.
cjfaure
Je suppose que sc'est la chaîne d'entrée, non? Ne devrait pas alors s.lowerêtre i.lower? Cependant, cette biche
Réintègre Monica
@ WolframH ah, oui, ça ira demain.
cjfaure
3

Python 71

Suppose une entrée dans s. Sortie en o.

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

Éditer: changé de liste en tuples pour économiser 2 octets.

Rétablir Monica
la source
1
Multiplier des listes par des booléens est amusant, n'est-ce pas? ; D
cjfaure
J'aime la façon dont vous esquivez le problème de la onécessité de commencer sans être vide o[-1]. Peut-être est-ce plus court de commencer ocomme [-1]ça et plus tard o=o[1:]? De manière ennuyeuse, les premiers -1tris vérifient si ocontient -1.
xnor
@xnor: Je ne pense pas que l' -1Idée puisse fonctionner. Au moins, je n'ai pas réussi :-( Cependant, j'ai changé les listes en tuples pour économiser 2 octets. :-)
Rétablir 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)]

Échantillon:

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
la source
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"

Exemple:

*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
la source
2

Matlab, 61 96

Recherche la chaîne et remplace tout le contenu de chaque correspondance par un charabia avant de rechercher le caractère suivant. Laissera sindéfini si le mot ne se produit pas.

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

Notez que le nombre de caractères peut être réduit si la sensibilité à la casse est autorisée.

Versions précédentes

 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

Recherche la chaîne et remplace tout le contenu de chaque correspondance par un charabia avant de rechercher le caractère suivant. La gestion des erreurs (try-catch-end) pourrait peut-être être supprimée, puis le programme se bloquerait (mais s serait indéfini selon les besoins) si llama n'est pas trouvé.

La mise en oeuvre:

>> 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

Sans traitement d'erreur:

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
la source
A l'instar de l'idée, avons un peu réduit le nombre de personnages.
Dennis Jaheruddin
2

Langage 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
la source
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
la source
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
la source
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
la source
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
la source
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
la source
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
la source
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
la source
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
la source