Wydobyć wewnętrzną lamę zdania

33

Twoim celem jest, aby wziąć wkład jak

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

i utwórz tablicę indeksów łańcucha, w której pojawiają się litery, które składają się na słowo „Lama” (po jednym w kolejności). Na przykład pozwól mi pokazać litery wskazane za pomocą kursorów, aby pokazać indeksy:

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

Tak więc tablica wyglądałaby następująco:

[44, 67, 76, 105, 114]

(Jeśli Twoja aplikacja korzysta z indeksowania, które nie jest oparte na 0, liczby będą wyglądać inaczej. W porządku.)

Jeśli tekst nie zawiera lamy, tablica powinna być pusta, zerowa, zerowa lub niezdefiniowana.

Dowolny język kodu jest akceptowany. To jest konkurs , więc najmniej znaków wygrywa!

Cilan
źródło
7
@TheWobbuffet Zmieniasz nazwę użytkownika i zdjęcie. Był czas, kiedy byłeś „Klamką” i miałeś jego zdjęcie. Twoje zdjęcie to owca. Powinieneś zmienić go na lamę.
Justin
1
Co z indeksowaniem opartym na 0 vs opartym na 1? Czy możemy po prostu użyć indeksowania używanego przez nasz język, czy też wszystkie zgłoszenia muszą być zgodne z jedną konwencją (która)?
Martin Ender
1
@Quincunx Owca mówi na nim „42”!
Cilan
2
@ TheWobbuffet zdecydowanie za dużo zorientowanych na matematykę: - / (Matlab, Mathematica, Julia, nie wiem o R) ... także Lua i Smalltalk. Jedynym z tych istotnych dla gry w golfa kodowego byłaby Mathematica, ale prawdopodobnie nie do zadań z ciągami znaków.
Martin Ender
3
Czy chcesz tylko funkcję, która to robi, czy cały program? Czy chcesz również kod wejścia / wyjścia?
jzm

Odpowiedzi:

11

CJam - 33

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

Pobiera indeksy oparte na 1 (2 dodatkowe bajty dla 0)

Wyjaśnienie:

lodczytuje wiersz z wejścia (zamień na qna całe wejście)
elkonwertuje na małe litery
"llama"{...}/wykonuje blok dla każdej litery „lamy”
1$kopiuje bieżący ciąg
#znajduje indeks
)_przyrostów liter i duplikuje
T+:Tdodaje T (początkowo 0), aktualizuje T i opuszcza go na stosie
\@zamienia elementy wokół, teraz mamy bieżący-T, indeks, ciąg
>wycina ciąg rozpoczynający się od
;wyskakującego indeksu pozostały ciąg
]zbiera indeksy w tablicy
W tym momencie mamy wszystkie indeksy oparte na 1; Jeśli żadna litera nie została znaleziona, tablica będzie miała duplikaty.
___wykonuje 3 kolejne kopie tablicy
|(z 2 kopiami tablicy) usuwa duplikaty
=porównuje, czego wynikiem jest 0, jeśli były duplikaty, lub 1, jeśli nie, odpowiednio
*mnożą tablicę 0 lub 1 razy

aditsu
źródło
sourceforge.net/p/cjam/wiki/Home, aby uzyskać więcej informacji na temat języka. Nowy dla mnie.
TankorSmash
12

Perl, 52 bajty

Rozwiązanie jest dostarczane jako funkcja, która przyjmuje ciąg znaków jako argument i zwraca listę pozycji.

  • Pozycje w oparciu o jedną pozycję, wyszukiwanie z rozróżnianiem wielkości liter, bez znaków nowej linii: 52 bajty

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

    Wyszukiwanie z rozróżnianiem wielkości liter zwraca pustą tablicę w przykładzie pytania, ponieważ po dopasowaniu pierwszych trzech liter mw tekście wejściowym brakuje małej litery .

  • Obsługa znaków nowej linii: + 1 bajt = 53 bajty

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

    Tekst może teraz obejmować kilka wierszy.

  • Wyszukiwanie bez rozróżniania wielkości liter: + 1 bajt = 54 bajty

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

    Teraz przykład w pytaniu podaje listę pozycji indeksu, są to liczby oparte na jednym:

    [45 68 77 106 115]
    
  • Pozycje zerowe: + 9 bajtów = 63 bajty

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

    Wynik dla przykładu w pytaniu:

    [44 67 76 105 114]
    

Nie golfowany:

Ten ostatni wariant obejmuje mniej więcej inne warianty.

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
źródło
1
Zakłada się również, że dane wejściowe to ASCII, a przynajmniej niepełny Unicode. Chyba, że
wyrażenia regularne
@ Trejkaz: Unicode nie ma tu żadnego znaczenia: (a) „lama” to ASCII, a jego litery nie kolidują z żadnym znakiem Unicode spoza ASCII ani jego reprezentacją bajtów w UTF-8. (b) Biorąc pod uwagę kodowanie wielobajtowe, termin „indeks” w pytaniu byłby nieokreślony. Indeks może odnosić się do pozycji znaku lub pozycji bajtu (pamięci). (c) Wspieranie dowolnego kodowania za pomocą pozycji znaków oznaczałoby, że kodowanie powinno być znane i należy je podać jako dodatkowy argument.
Heiko Oberdiek
Pierwsze dwa rozwiązania są drukowane, []a trzecie [ ]dla mnie (te dłuższe działają poprawnie). Korzystam z programu „perl, wersja 5.0.8 dla msys-64int”. Czy masz błąd, czy działa na innej wersji Perla?
Tim S.
@TimS .: []jest poprawny dla pierwszego rozwiązania, Mnie jest dopasowywany przy wyszukiwaniu z rozróżnianiem wielkości liter. Pytanie jest dość niejasne w odniesieniu do rozróżniania wielkości liter.
Heiko Oberdiek
Ok, więc []jest do przyjęcia przez pierwsze dwa. Ale pierwsze trzy rozwiązania nadal nie działają dla mnie dobrze: jeśli podasz dane wejściowe, które powinny zwrócić indeksy, to zwróci[ ]
Tim S.
10

sed, 299 + 1

Tak, sed może znaleźć lamę. Nie, sed nie potrafi matematyki. To najdłuższa jak dotąd odpowiedź, przy 299 + 1 znakach, ponieważ musiałem nauczyć sed liczyć.

Ta odpowiedź wymaga sed z rozszerzonymi wyrażeniami regularnymi ( sed -Elub sed -r). Użyłem OpenBSD sed (1) . Dane wejściowe to jeden ciąg w wierszu. (Dlatego ciąg nie może zawierać nowej linii.) Dane wyjściowe to linia liczb lub nic.

Zastosowanie (+1 znak za -r):

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

Kod źródłowy (299 znaków):

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

Program najpierw zamienia lamę na pięć %. (Wszystkie %w tym programie są dosłowne.) Pierwsze polecenie s/%/z/gzmienia dowolne %na zw wierszu wprowadzania. Następne pięć poleceń znajduje lamę, więc wszystkie ramiona na wszystkich ramionach mogą boleć. staje się A %% broni na% ll ramiona% ay% che. Ponieważ każdy .*jest chciwy, zawsze znajduję lamę po prawej stronie: lama lama staje się lamą %%%%% . Jeśli nie mogę dostać pięciu %, /(.*%){5}/!dusuwa wiersz wprowadzania i pomija następne polecenia.

s/[^%]/z/gzmienia każdy znak, ale %do z. Potem wchodzę w pętlę. s/(z*)%/\10 z\1/zmienia pierwszą %na 0, kopiuje zero lub więcej zz lewej do prawej i dodaje jeszcze jedną zz prawej. Jest to więc liczba zrówna indeksowi. Na przykład zz%zzz%...staje się, zz0 zzzzzzzz%...ponieważ pierwszy %był pod indeksem 2, a następny %pod indeksem 8. s/z*$//usuwa dodatkowe zz końca łańcucha.

Następne jedenaście poleceń liczy zsię, usuwając każde z nich zi odliczając w górę 0. Liczy jak zzz0, zz1, z2, 3. Również 1zzzz9staje się z1zzz0(później 23) lub zzzz9staje się 1zzz0(później 13). Ta pętla trwa, dopóki nie będzie więcej %lub z.

kernigh
źródło
1
+1 za naukę liczenia. Łatwiej jest nauczyć lamę liczyć niż sed.
Andreï Kostyrka
9

Fortran - 154 148

Fortran jest do bani w golfa, ale po to, aby udowodnić, że parsowanie łańcuchów można wykonać w języku opartym na matematyce, zrobiłem to:

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

Zapisałem kilka znaków, eliminując niepotrzebne fna końcu endfunctioni używane if(any(r==0))zamiast if(.not.all(r>0)).

To wymaga:

  1. s być ciągiem z tekstem
  2. abyć testem na małe litery (tj. llama)
  3. bbyć testem na wielkie litery (tj. LLAMA)

Pełny program bez gry w golfa to

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
źródło
Nowoczesne Fortran jest dozwolone przynajmniej na boiskach i boiskach do gry. FORTRAN IV nadal grałby w szalonego golfa.
ClickRick
4
@ClickRick: Fortran IV to coś, czego się nie nauczyłem. Nie jestem pewien, czy chcę. Niepokoi mnie coś w wymuszonych wcięciach i wielkich literach.
Kyle Kanos
7

C # - 119

Pobiera ciąg znaków, tablicę wyników. Brak, jeśli nie ma lamy w łańcuchu.

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
źródło
1
+1 zax=>x>=0
ClickRick
Jestem pod wrażeniem. O wiele mniejszy niż którykolwiek z moich pomysłów na ten. Odkryłem, że możesz go zmniejszyć, inicjując ina -1 i umieszczając .ToArray () w instrukcji 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

Ruby, 56 65 63

Edycja : +9 znaków, dzięki czemu wielkość liter nie jest uwzględniana.

Definiuje funkcję (technicznie lambda) f.

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

Zwraca, niljeśli nie ma Lamy. Jeśli ma to być [](pusta tablica), to po prostu dodaj ||[]przed ostatnim }w sumie 4 dodatkowe znaki.

Wersja do odczytu:

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 || []
}
Klamka
źródło
Przepraszam za edytowanie mojego pytania po pewnym czasie, ale właśnie dodałem, że tablica, jeśli nie ma lamy, może być zerowa, zerowa, pusta lub niezdefiniowana.
Cilan
21
Więc zrobiłeś to z Lambambą?
Mason Wheeler
@ Dooobnob byłby dwa bajty krótszy przy użyciu upcase zamiast downcase no?
dstarh
@dstarh Tak, dziękuję
Klamka
Pomyśl, że możesz uzyskać bajtowość bez uwzględniania wielkości liter, robiąc index(/#{c}/izamiast tego upcase.
histocrat
6

C - 53

Połącz z:

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

Przetestowałem to polecenie kompilacji z gcc cygwina. Inne środowiska mogą inaczej obsługiwać spacje i inne znaki specjalne.

Wynik oparty na 0 jest przechowywany w tablicy r. Jego zawartość jest niezdefiniowana, jeśli w sznurku nie ma lamy.

  • Z uwzględnieniem wielkości liter (53)

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

  • Bez rozróżniania wielkości liter (58)

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

Allbeert
źródło
4

JavaScript (ECMAScript 6) - 68 znaków

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

Zakłada, że ​​ciąg do przetestowania znajduje się w zmiennej s. Jeśli chcesz przekształcić go w funkcję, dodaj f=s=>(dla dodatkowych 5 znaków).

Wyjścia:

[]

Rozróżnianie wielkości liter - 69 znaków

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

Wyjścia:

[68, 80, 93, 105, 114]

Rozróżnianie wielkości liter i pierwszy mecz - 74 znaków

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

Wyjścia:

[44, 67, 76, 105, 114]
MT0
źródło
4

Python, 100

Jestem najgorszym golfistą w historii. : P

Dzięki @xnor za zgolenie 6 bajtów.

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 zawiera tablicę po.

EDYCJA : Naprawiono.

EDIT 2 : len(g)aby g, o==5aby o>4zgodnie z sugestiami użytkownika @ XNOR.

EDYCJA 3 : @WolframH naprawił to.

cjfaure
źródło
2
o*=(len(o)==5)jest doskonała . To okropne, ale uwielbiam to!
kevinsa5
Nie sądzę, aby zewnętrzne nawiasy w tej linii były konieczne. Możesz zapisać dwie postacie, usuwając je.
user2357112 obsługuje Monikę
@ user2357112 W tej drugiej ostatniej linii? Usunę je.
cjfaure
Zakładam, sże ciąg wejściowy, prawda? Nie powinno s.lowerbyć i.lower? Jednak ta królica
Przywróć Monikę
@WolframH ah, tak, naprawię jutro.
cjfaure
3

Python 71

Zakłada wejście w s. Wyjście w o.

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

Edycja: Zmieniono z list na krotki, aby zapisać 2 bajty.

Przywróć Monikę
źródło
1
Mnożenie list przez booleany jest fajne, prawda? ; D
cjfaure
Podoba mi się sposób, w jaki unikasz problemu polegającego ona tym, że musisz zacząć niepuste o[-1]. Może jednak krótsze jest rozpoczęcie otak, jak [-1]i później o=o[1:]? Irytujące, początkowe -1potknięcia sprawdzają, czy ozawiera -1.
xnor
@xnor: Nie sądzę, -1aby można było sprawić, że -Idea będzie działać. Przynajmniej mi się nie udało :-( Jednak zmieniłem listy na krotki, aby zapisać 2 bajty. :-)
Przywróć Monikę
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)]

Próba:

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
źródło
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"

Nie golfowany:

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"

Przykład:

*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
źródło
2

Matlab, 61 96

Przeszukuje ciąg znaków i zamienia wszystko do każdego dopasowania bełkotem przed szukaniem następnego znaku. Pozostawi sniezdefiniowane, jeśli słowo nie pojawi się.

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

Pamiętaj, że liczba znaków może zostać zmniejszona, jeśli rozróżniana jest wielkość liter.

Poprzednie wersje

 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

Przeszukuje ciąg znaków i zamienia wszystko do każdego dopasowania bełkotem przed szukaniem następnego znaku. Obsługa błędów (try-catch-end) może zostać porzucona, a następnie program zawiesi się (ale nie będzie zdefiniowany zgodnie z wymaganiami), jeśli lama nie zostanie znaleziona.

Realizacja:

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

Bez obsługi błędów:

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
źródło
Podobnie jak pomysł, zmniejszyłem nieco liczbę znaków.
Dennis Jaheruddin
2

Język 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
źródło
2

Python (70)

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

Po kolei szukamy każdej postaci 'llama', zaczynając od lokalizacji poprzednio znalezionej postaci. Jeśli nie zostanie znaleziony żaden znak, cstaje się wartością domyślną -1, w którym to przypadku ostatni wiersz zamienia rsię w pustą listę.

Edycja: okazało się, że str.find(s,...)można wywołać jako s.find(...), zapisując 4 znaki.

xnor
źródło
2

OpenEuphoria, 147 128

Mam dwa przykłady. Po pierwsze, najkrótszy:

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

Mogę sprowadzić go do 126 znaków, jeśli użyję „lub” zamiast „i”, tak jak w wersji C wyżej. Jednak to również pasuje do ciągu ''!-!jako llama. Niezbyt często, ale wciąż możliwy błąd.

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

A następnie wersja wykorzystująca wyrażenia regularne:

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

Oba pobierają dane ze STDIN i wysyłają do STDOUT.

EDYCJA: Krótszy przykład wyrażenia regularnego:

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
Ołowiany żołnierzyk
źródło
Czy można zapisać kilka, budując wyrażenie regularne za pomocą split/ joinlub explode/ implode, czy też OpenEuphoria nie ma krótkich wersji?
Peter Taylor
OpenEuphoria potrafi rozdzielać / łączyć za pomocą ciągów znaków, ale nie widzę sposobu, aby to zrobić w krótszy sposób. Nie jestem zbyt dobry w wyrażeniach regularnych; regex użyty tutaj został „zainspirowany” (bezwstydnie skradziony) z jednego z innych przykładów na tej stronie.
TinSoldier
2

PowerShell - 121 85

Nadal ćwiczę z Powershellem, spodziewaj się, że można to poprawić

$ s zawiera ciąg, wynik jest w tablicy $ a

Orginalna wersja

$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

Bez golfa

$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

Nowa wersja z ogromnym podziękowaniem za @goric

$a=@();$n=$c=0;[char[]]$s|%{if($_-eq"llama"[$n]){$a+=$c;$n++}$c++};$a*=$a.length-gt4
Brian
źródło
Możesz usunąć wiele miejsc, aby skrócić rzeczy do 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
Ponadto, można wymienić foreach($i in $s.tochararray())z [char[]]$s|%tak długo, jak zmienić późniejsze $iDo $_. To goli go do 93:$a=@();$w="llama";$n=$c=0;[char[]]$s|%{if($_-eq$w[$n]){$a+=$c;$n+=1}$c+=1};$a*=$a.length-gt4
goric
Zaoszczędź 5 dodatkowych znaków, usuwając $wzmienną, ponieważ jest ona używana tylko raz. Wystarczy wstawić to do if:if($i-eq"llama"[$n])
goric
..i oczywiście zastąpić +=1S z ++S
goric
1

PHP

brak odpowiedzi PHP? Myślę, że język silnie zorientowany na sznurki może pokonać przynajmniej matematykę

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 przeciwko fortranowi 154, praca wykonana: P

bez golfa

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[];
}

jeśli dzwoniący zawsze przekazuje ciąg małych liter, obniża się do 137

Einacio
źródło
Musisz dodać <?na początku kodu, aby był poprawny. Przepraszam ...
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:[]}

Definiuje funkcję, która przyjmuje ciąg jako jedyny argument (drugi argument jest tani var) i zwraca pustą tablicę lub tablicę 5-elementową.

Zmniejsza się do 108, jeśli wezmę dane wejściowe na jedną zmienną char ( s) i zostawię wynik w innej ( b):

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

Edycja: Zamieniono mapę dla pętli.

Aaron Dufour
źródło
Wersja ECMAScript 6 (81 znaków) -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]

Przykład użycia w konsoli Rebol:

>> 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 używa indeksowania 1. Zwraca pustą listę, []jeśli nie znaleziono sekwencji lamy (wielkość liter nie ma znaczenia).

Nie golfowany:

f: func [s] [
    a: copy []
    foreach n "llama" [
        if none? s: find s n [return []]
        append a index? s
        s: next s
    ]
    a
]
draegtun
źródło
1

APL, 47

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

Nie najkrótszy kod, ale dość zniekształcony w sposób APL.

Wyjaśnienie

'amall',⊂⍬⍞ Zrób tablicę 6 elementów: litery „amall” i podtablicę z 2 elementów, same podtablice: pusta tablica i wiersz znaków odczytywanych z wejścia.

{...}/... Zmniejsz (składając prawy) 6-elementową tablicę za pomocą dostarczonej funkcji.

a s←⍵ Rozpakuj odpowiedni argument do tablicy indeksów i pozostałych podciągów (początkowo pusta tablica i pełny ciąg).

~⍺∊s:⍬⍬ Jeśli podciąg nie zawiera następnej litery przerwij obliczenia i zwróć pustą tablicę.

a,←n←s⍳⍺ W przeciwnym razie znajdź jego pozycję, nazwij ją n i dołącz do tablicy wskaźników.

a(n↓s) Utwórz i zwróć tablicę 2 elementów: rozszerzoną tablicę indeksów i pozostałe podłańcuchy.

+\↑⊃... Rozpakuj wynik składania, weź pierwszy element (tablicę indeksów) i zeskanuj go z dodatkiem, aby przekształcić przesunięcia względne w absolutne.

Przykłady

      +\↑⊃{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
źródło
1

Julia, 76

Kolejny przykład wyrażenia regularnego z użyciem języka Julia.

f(s)=(m=match(r"(?i)(l).*?(l).*?(a).*?(m).*?(a)",s);m==nothing?m:m.offsets)
Ołowiany żołnierzyk
źródło