Bringen Sie das innere Lama eines Satzes zum Vorschein

33

Ihr Ziel ist es, Input wie zu nehmen

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

und erstellen Sie ein Array der Indizes der Zeichenfolge, in denen die Buchstaben des Wortes "Lama" erscheinen (jeweils eine in der angegebenen Reihenfolge). Lassen Sie mich zum Beispiel die Buchstaben zeigen, auf die mit Carets gezeigt wird, um die Indizes anzuzeigen:

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

Das Array würde also so aussehen:

[44, 67, 76, 105, 114]

(Wenn Ihre Anwendung eine Indexierung verwendet, die nicht auf 0 basiert, sehen die Zahlen anders aus. Das ist in Ordnung.)

Wenn der Text kein Lama enthält, sollte das Array leer, null, null oder undefiniert sein.

Jede Codesprache wird akzeptiert. Dies ist ein Wettbewerb, bei dem die wenigsten Charaktere gewinnen!

Cilan
quelle
7
@TheWobbuffet Sie ändern ständig Ihren Benutzernamen und Ihr Bild. Es gab eine Zeit, als Sie "Türklinke" waren und sein Bild hatten. Jetzt ist dein Bild ein Schaf. Sie sollten es in ein Lama ändern.
Justin
1
Was ist mit 0-basierter vs 1-basierter Indizierung? Können wir nur die von unserer Sprache verwendete Indexierung verwenden oder müssen alle Einsendungen einer Konvention entsprechen (welche)?
Martin Ender
1
@ Quincunx Das Schaf sagt '42' drauf!
Cilan
2
@TheWobbuffet viel zu viele Mathe-orientierte: - / (Matlab, Mathematica, Julia, ich weiß nicht über R) ... auch Lua und Smalltalk. Die einzige, die für das Code-Golfen relevant ist, ist Mathematica, wahrscheinlich jedoch nicht für die Bearbeitung von Saiten.
Martin Ender
3
Wollen Sie nur die Funktion, die es tut, oder das ganze Programm? Möchten Sie auch den Eingabe- / Ausgabecode?
jzm

Antworten:

11

CJam - 33

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

Es werden die 1-basierten Indizes abgerufen (2 weitere Bytes für 0-basierte)

Erläuterung:

lLiest eine Zeile aus der Eingabe (Ersetzen durch qfür die gesamte Eingabe),
elkonvertiert sie in Kleinbuchstaben.
"llama"{...}/Führt den Block für jeden "Lama"
1$-Buchstaben aus. Die aktuelle Zeichenfolge
#findet den Index der Buchstabeninkremente
)_und dupliziert
T+:Taddiert T (anfangs 0), aktualisiert T und verlässt ihn Auf dem Stapel werden die
\@Elemente vertauscht. Jetzt haben wir current-T, index. Die Zeichenfolge
>schneidet die Zeichenfolge, die am Index beginnt.
;Die verbleibende Zeichenfolge
]sammelt die Indizes in einem Array.
Zu diesem Zeitpunkt haben wir alle 1-basierten Indizes. Wenn kein Buchstabe gefunden wurde, enthält das Array Duplikate.
___macht 3 weitere Kopien des Arrays
|(mit 2 Array-Kopien) entfernt Duplikate
=vergleicht, was zu 0 führt, wenn Duplikate vorhanden sind, oder 1, wenn nicht,
*multipliziert das Array 0 oder 1 entsprechend

aditsu
quelle
sourceforge.net/p/cjam/wiki/Home für weitere Informationen zur Sprache. Neu für mich.
TankorSmash
12

Perl, 52 Bytes

Die Lösung wird als Funktion bereitgestellt, die die Zeichenfolge als Argument verwendet und eine Liste von Positionen zurückgibt.

  • Einbasierte Positionen, Suche nach Groß- und Kleinschreibung ohne Zeilenumbruch: 52 Bytes

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

    Bei der Suche nach Groß- und Kleinschreibung wird im Beispiel der Frage ein leeres Array zurückgegeben, da nach dem Abgleichen der ersten drei Buchstaben der Kleinbuchstabe mim Eingabetext fehlt.

  • Unterstützung von Zeilenumbrüchen: + 1 Byte = 53 Byte

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

    Der Text kann nun mehrere Zeilen umfassen.

  • Suche ohne Berücksichtigung der Groß- / Kleinschreibung: + 1 Byte = 54 Byte

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

    Das Beispiel in der Frage gibt eine Liste der Indexpositionen an. Es handelt sich um einbasierte Zahlen:

    [45 68 77 106 115]
    
  • Nullbasierte Positionen: + 9 Bytes = 63 Bytes

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

    Ergebnis für das Beispiel in der Frage:

    [44 67 76 105 114]
    

Ungolfed:

Die letztere Variante umfasst mehr oder weniger die anderen Varianten.

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
quelle
1
Dies setzt auch voraus, dass die Eingabe ASCII oder zumindest kein vollständiger Unicode ist. Es sei denn, Perls reguläre Ausdrücke respektieren heutzutage die grafischen Grenzen korrekt (sie haben sich sicherlich nicht zurückgemeldet, als ich das Pech hatte, sie zu verwenden.)
Trejkaz,
@ Trejkaz: Unicode spielt hier keine Rolle: (a) "Lama" ist ASCII und seine Buchstaben kollidieren nicht mit Nicht-ASCII-Unicode-Zeichen oder seiner Byte-Darstellung in UTF-8. (b) Unter Berücksichtigung von Mehrbyte-Codierungen wäre der Begriff "Index" in der Frage nicht genau spezifiziert. Der Index kann sich auf die Zeichenposition oder die Byte- (Speicher-) Position beziehen. (c) Das Unterstützen einer Kodierung mit Zeichenpositionen würde bedeuten, dass die Kodierung bekannt sein sollte und als zusätzliches Argument bereitgestellt werden muss.
Heiko Oberdiek
Die ersten beiden Lösungen werden gedruckt []und die dritte wird [ ]für mich gedruckt (die längeren funktionieren ordnungsgemäß). Ich verwende "Perl, v5.8.8 für msys-64int". Haben Sie einen Fehler oder funktioniert er auf einer anderen Version von Perl?
Tim S.
@TimS .: Stimmt []für die erste Lösung, Mwird bei einer Suche nicht zwischen Groß- und Kleinschreibung unterschieden. Die Frage nach der Groß- und Kleinschreibung ist recht unklar.
Heiko Oberdiek
Ok, []ist also akzeptabel für die ersten beiden. Aber die ersten drei Lösungen funktionieren immer noch nicht richtig für mich: Wenn Sie eine Eingabe geben, die Indizes zurückgeben soll, gibt sie zurück[ ]
Tim S.
10

sed, 299 + 1

Ja, sed kann ein Lama finden. Nein, sed kann nicht rechnen. Dies ist mit 299 + 1 Zeichen die längste Antwort, da ich sed das Zählen beibringen musste.

Diese Antwort erfordert ein sed mit erweiterten regulären Ausdrücken ( sed -Eoder sed -r). Ich habe OpenBSD sed (1) benutzt . Eingabe ist eine Zeichenfolge pro Zeile. (Daher enthält die Zeichenfolge möglicherweise keine neue Zeile.) Die Ausgabe ist eine Zahlenzeile oder nichts.

Verwendung (+1 Zeichen für -r):

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

Quellcode (299 Zeichen):

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

Das Programm ersetzt zunächst das Lama durch fünf %. (Alle Angaben %in diesem Programm sind wörtlich.) Der erste Befehl s/%/z/gändert sich %in zin der Eingabezeile. Die nächsten fünf Befehle finden das Lama, sodass alle Arme auf allen Schultern schmerzen können. wird A %% Arme auf% ll Schultern% ay% che. Weil jeder .*gierig ist, finde ich immer das Lama auf der rechten Seite: Lama Lama würde zu Lama %%%%% . Wenn ich keine fünf bekomme %, /(.*%){5}/!dlöscht ich die Eingabezeile und überspringe die nächsten Befehle.

s/[^%]/z/gändert jeden Charakter außer %zu z. Dann gehe ich in eine Schleife. s/(z*)%/\10 z\1/ändert die erste %in 0, kopiert null oder mehr zvon links nach rechts und fügt eine weitere znach rechts hinzu. Dies ist so, dass die Anzahl der zWillen dem Index entspricht. Zum Beispiel zz%zzz%...wird , zz0 zzzzzzzz%...da der erste %bei Index 2 war, und der nächste %ist am Index 8. s/z*$//entfernt zusätzliche zvom Ende des Strings.

Die nächsten elf Befehle werden gezählt, zindem jeder entfernt zund von hochgezählt wird 0. Es zählt wie zzz0, zz1, z2, 3. Auch 1zzzz9wird z1zzz0(später 23) oder zzzz9wird 1zzz0(später 13). Diese Schleife setzt sich fort, bis es keine %oder mehr gibt z.

Kernigh
quelle
1
+1 für das Unterrichten von sed to count. Es ist einfacher, einem Lama das Zählen beizubringen als sed.
Andreï Kostyrka
9

Fortran - 154 148

Fortran mag Golf, aber nur um zu beweisen, dass das Parsen von Saiten in einer mathematischen Sprache möglich ist, habe ich es getan:

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

Ich habe ein paar Zeichen gespart, indem ich die fam Ende nicht benötigten weggelassen endfunctionund if(any(r==0))stattdessen verwendet habe if(.not.all(r>0)).

Dafür braucht man:

  1. s die Zeichenfolge mit Text sein
  2. aum als Kleiner Test (dh llama)
  3. bzu sein , der obere Falltest (dh LLAMA)

Das volle, nicht golfene Programm ist

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
quelle
Das moderne Fortran ist zumindest in den Pitch & Putt-Bereichen erlaubt. FORTRAN IV würde immer noch verrücktes Golf spielen.
ClickRick
4
@ClickRick: Fortran IV ist etwas, was ich nicht gelernt habe. Ich bin mir nicht sicher, ob ich will. Etwas über erzwungene Einrückung und Großschreibung stört mich.
Kyle Kanos
7

C # - 119

Nimmt String, gibt Array aus. Null, wenn kein Lama in der Zeichenfolge.

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
quelle
1
+1 fürx=>x>=0
ClickRick
Ich bin beeindruckt. Viel kleiner als jede meiner Ideen für diese. Ich habe herausgefunden, dass Sie es verkleinern können, indem Sie es iauf -1 initialisieren und .ToArray () in die .Select-Anweisung 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;}
einfügen
7

Ruby, 56 65 63

Bearbeiten : 9 Zeichen , so dass es Groß- und Kleinschreibung ist.

Definiert eine Funktion (Lambda, technisch) f.

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

Gibt zurück, nilwenn kein Lama vorhanden ist. Wenn es sein muss [](leeres Array), dann fügen Sie einfach ||[]vor dem letzten }für insgesamt 4 zusätzliche Zeichen hinzu.

Lesbare Version:

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 || []
}
Türknauf
quelle
Ich entschuldige mich dafür, dass ich meine Frage nach einiger Zeit bearbeitet habe, aber ich habe gerade hinzugefügt, dass das Array, wenn es kein Lama ist, null, leer oder undefiniert sein kann.
Cilan
21
Also hast du es mit einem Lambda gemacht?
Mason Wheeler
@Doorknob wäre um zwei Bytes kürzer, wenn Sie "upcase" anstelle von "downcase no" verwenden würden.
5.
@dstarh Ja, danke
Türklinke
Denken Sie, Sie können die Unterscheidung zwischen Groß- und Kleinschreibung um ein Byte billiger machen, wenn Sie dies tun, index(/#{c}/ianstatt upcase.
Histokrat
6

C - 53

Kompilieren mit:

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

Ich habe diesen Kompilierbefehl mit Cygwins gcc getestet. In anderen Umgebungen werden Leerzeichen und andere Sonderzeichen möglicherweise anders behandelt.

Das 0-basierte Ergebnis wird in einem Array gespeichert r. Sein Inhalt ist undefiniert, wenn der String kein Lama enthält.

  • Groß- und Kleinschreibung beachten (53)

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

  • Groß- / Kleinschreibung beachten (58)

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

Allbeert
quelle
4

JavaScript (ECMAScript 6) - 68 Zeichen

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

Angenommen, die zu testende Zeichenfolge befindet sich in der Variablen s. Wenn Sie es in eine Funktion verwandeln möchten, müssen Sie f=s=>(für weitere 5 Zeichen) voranstellen .

Ausgänge:

[]

Groß- / Kleinschreibung beachten - 69 Zeichen

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

Ausgänge:

[68, 80, 93, 105, 114]

Groß- / Kleinschreibung und erste Übereinstimmung - 74 Zeichen

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

Ausgänge:

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

Python, 100

Ich bin der schlechteste Golfer aller Zeiten. : P

Vielen Dank an @xnor für das Abschneiden von 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 enthält das Array nach.

BEARBEITEN : Behoben.

EDIT 2 : len(g)to g, o==5to o>4gemäß @ xnors Vorschlägen.

EDIT 3 : @WolframH behoben.

cjfaure
quelle
2
o*=(len(o)==5)ist ausgezeichnet . Es ist schrecklich, aber ich liebe es!
kevinsa5
Ich denke nicht, dass die äußeren Klammern in dieser Zeile notwendig sind. Sie können zwei Zeichen speichern, indem Sie sie entfernen.
user2357112 unterstützt Monica
@ user2357112 In dieser vorletzten Zeile? Ich werde sie entfernen.
cjfaure
Ich nehme an, das sist die Eingabezeichenfolge, oder? Sollte es dann nicht s.lowersein i.lower? Allerdings, dass doe
Reinstate Monica
@WolframH ah ja, wird morgen beheben.
cjfaure
3

Python 71

Übernimmt die Eingabe in s. Ausgabe in o.

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

Bearbeiten: Von Listen zu Tupeln geändert, um 2 Bytes zu sparen.

Setzen Sie Monica wieder ein
quelle
1
Das Multiplizieren von Listen mit Booleschen Werten macht Spaß, nicht wahr? ; D
cjfaure
Ich mag, wie Sie dem Problem ausweichen o, nicht leer anfangen zu müssen, um es zu nehmen o[-1]. Vielleicht ist es kürzer , obwohl nur zu beginnen , owie [-1]später tun o=o[1:]? Ärgerlicherweise stolpert die erste -1Überprüfung, ob oenthält -1.
xnor
@xnor: Ich glaube nicht, dass die -1-Idee zum Laufen gebracht werden kann. Zumindest ist mir das nicht gelungen :-( Allerdings habe ich die Listen in Tupel geändert, um 2 Bytes zu sparen. :-)
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)]

Probe:

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

Beispiel:

*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
quelle
2

Matlab, 61-96

Durchsucht die Zeichenfolge und ersetzt bis zu jeder Übereinstimmung alles durch Kauderwelsch, bevor nach dem nächsten Zeichen gesucht wird. Lässt sundefiniert, wenn das Wort nicht vorkommt.

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

Beachten Sie, dass die Anzahl der Zeichen verringert werden kann, wenn die Berücksichtigung der Groß- und Kleinschreibung zulässig ist.

Vorherige Versionen

 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

Durchsucht die Zeichenfolge und ersetzt bis zu jeder Übereinstimmung alles durch Kauderwelsch, bevor nach dem nächsten Zeichen gesucht wird. Die Fehlerbehandlung (try-catch-end) könnte möglicherweise fallengelassen werden, dann würde das Programm abstürzen (aber s wäre nach Bedarf undefiniert), wenn Lama nicht gefunden würde.

Implementierung:

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

Ohne Fehlerbehandlung:

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
quelle
Wie die Idee, habe Charcount ein bisschen reduziert.
Dennis Jaheruddin
2

Sprache 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
quelle
2

Python (70)

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

Wir suchen nacheinander nach jedem Zeichen 'llama', beginnend nach der Position des zuvor gefundenen Zeichens. Wird kein Zeichen gefunden, cwird der Standardwert von verwendet -1. In diesem Fall wird die letzte Zeile rin die leere Liste umgewandelt.

Bearbeiten: Es wurde herausgefunden, str.find(s,...)dass aufgerufen werden kann s.find(...), indem 4 Zeichen gespeichert werden.

xnor
quelle
2

OpenEuphoria, 147 128

Ich habe zwei Beispiele. Erstens die kürzeste:

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

Ich kann es auf 126 Zeichen reduzieren, wenn ich "oder" anstelle von "und" verwende, wie es die C-Version oben tut. Dies entspricht jedoch auch der Zeichenfolge ''!-!als llama. Gelegentlich, aber immer noch ein möglicher Fehler.

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

Und dann die Version mit regulären Ausdrücken:

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

Beide nehmen Eingaben von STDIN entgegen und senden diese an STDOUT.

EDIT: Kürzere Regex Beispiel:

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
Zinn Soldat
quelle
Ist es möglich, ein paar zu sparen, indem man den regulären Ausdruck mit split/ joinoder explode/ erstellt implode, oder hat OpenEuphoria keine kurzen Versionen davon?
Peter Taylor
OpenEuphoria kann Zeichenfolgen teilen / verbinden, aber ich sehe keine Möglichkeit, dies in kürzerer Form zu tun. Ich bin nicht sehr gut mit regulären Ausdrücken; Die hier verwendete Regex wurde von einem der anderen Beispiele auf dieser Seite "inspiriert" (schamlos gestohlen).
TinSoldier
2

Power Shell - 121 85

Ich übe immer noch mit Powershell und erwarte, dass dies verbessert werden kann

$ s enthält den String, Ergebnis ist in Array $ a

Originalfassung

$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

Neue Version, mit großem Dank an @goric

$a=@();$n=$c=0;[char[]]$s|%{if($_-eq"llama"[$n]){$a+=$c;$n++}$c++};$a*=$a.length-gt4
Brian
quelle
Sie können dort viele Leerzeichen entfernen, um die $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
Zahl
Außerdem können Sie ersetzen foreach($i in $s.tochararray())mit [char[]]$s|%, solange Sie die nachfolgende ändern $izu ein $_. Dass Rasuren es bis auf 93:$a=@();$w="llama";$n=$c=0;[char[]]$s|%{if($_-eq$w[$n]){$a+=$c;$n+=1}$c+=1};$a*=$a.length-gt4
Gorić
Sparen Sie 5 weitere Zeichen, indem Sie die $wVariable vollständig entfernen , da sie nur einmal verwendet wird. Fügen Sie es einfach in das if ein:if($i-eq"llama"[$n])
goric
..und natürlich ersetzen Sie Ihr +=1s durch ++s
goric
1

PHP

Noch keine PHP-Antwort? Ich denke, eine Sprache, die stark auf Saiten ausgerichtet ist, kann zumindest eine mathematische schlagen

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 gegen fortran 154, Aufgabe erledigt: 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[];
}

Übergibt der Anrufer immer eine Zeichenfolge in Kleinbuchstaben, wird die Zeichenfolge auf 137 verringert

Einacio
quelle
Sie müssen <?am Anfang Ihres Codes hinzufügen , um ihn gültig zu machen. Entschuldigung ...
wird
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:[]}

Definiert eine Funktion, die einen String als einziges Argument verwendet (zweites Argument ist billig var) und entweder ein leeres Array oder ein Array mit 5 Elementen zurückgibt.

Fällt auf 108, wenn ich die Eingabe für eine einzelne Zeichenvariable ( s) nehme und die Ausgabe in einer anderen ( b) belasse:

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

Bearbeiten: Karte für for-Schleife ausgetauscht.

Aaron Dufour
quelle
ECMAScript 6-Version (81 Zeichen) -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]

Anwendungsbeispiel in der Rebol-Konsole:

>> 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 verwendet eine 1-basierte Indizierung. Gibt eine leere Liste zurück, []wenn keine Lama-Sequenz gefunden wurde (Groß- / Kleinschreibung wird nicht berücksichtigt).

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

APL, 47

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

Nicht der kürzeste Code, aber auf APL-Weise ziemlich verzerrt.

Erläuterung

'amall',⊂⍬⍞ Bilden Sie ein Array aus 6 Elementen: die Buchstaben 'amall' und ein Subarray aus 2 Elementen, selbst Subarrays: das leere Array und eine Zeichenzeile, die aus der Eingabe gelesen werden.

{...}/... Reduzieren Sie das 6-Elemente-Array mit der bereitgestellten Funktion (nach rechts).

a s←⍵ Zerlegen Sie das richtige Argument in das Array mit den Indizes und die verbleibende Teilzeichenfolge (anfangs das leere Array und die vollständige Zeichenfolge).

~⍺∊s:⍬⍬ Wenn die Teilzeichenfolge nicht den nächsten Buchstaben enthält, stoppen Sie die Berechnung und geben Sie das leere Array zurück.

a,←n←s⍳⍺ Suchen Sie andernfalls seine Position, rufen Sie es n auf und hängen Sie es an das Array von Indizes an.

a(n↓s) Erstellen Sie ein Array mit zwei Elementen und geben Sie sie zurück: das erweiterte Array mit den Indizes und die verbleibende Teilzeichenfolge.

+\↑⊃... Packen Sie die Ausgabe der Faltung aus, nehmen Sie das erste Element (das Array von Indizes) und scannen Sie es mit Addition, um relative Offsets in absolute zu verwandeln.

Beispiele

      +\↑⊃{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
quelle
1

Julia, 76

Ein weiteres Beispiel für Regex mit der Sprache Julia.

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