Keluarkan llama batin dari sebuah kalimat

33

Sasaran Anda adalah menerima masukan seperti

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

dan buat larik indeks dari string tempat huruf-huruf yang membentuk kata "Llama" muncul (masing-masing berurutan). Sebagai contoh, izinkan saya menunjukkan surat-surat yang ditunjukkan dengan tanda sisipan untuk menunjukkan indeks:

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

Jadi array akan terlihat seperti:

[44, 67, 76, 105, 114]

(Jika aplikasi Anda menggunakan pengindeksan yang tidak berbasis 0, angkanya akan terlihat berbeda. Tidak masalah.)

Jika teks tidak memiliki llama, maka array harus kosong, nihil, nol, atau tidak terdefinisi.

Bahasa kode apa pun diterima. Ini adalah kontes , jadi karakter paling tidak menang!

Cilan
sumber
7
@TheWobbuffet Anda terus mengubah nama pengguna dan gambar Anda. Ada saat ketika Anda "Doorknob" dan memiliki fotonya. Sekarang, foto Anda adalah seekor domba. Anda harus mengubahnya ke llama.
Justin
1
Bagaimana dengan pengindeksan berbasis 0 vs 1? Bisakah kita menggunakan pengindeksan yang digunakan oleh bahasa kita atau apakah semua kiriman harus sesuai dengan satu konvensi (yang mana)?
Martin Ender
1
@Quincunx Domba mengatakan '42' di atasnya!
Cilan
2
@TheWobbuffet terlalu banyak yang berorientasi pada matematika: - / (Matlab, Mathematica, Julia, saya tidak tahu tentang R) ... juga Lua dan Smalltalk. Satu-satunya yang relevan dengan kode golf adalah Mathematica, tetapi mungkin tidak untuk tugas manipulasi string.
Martin Ender
3
Apakah Anda hanya ingin fungsi yang melakukannya atau keseluruhan program? Apakah Anda ingin kode input / output juga?
jzm

Jawaban:

11

CJam - 33

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

Ia mendapat indeks berbasis 1 (2 byte lebih banyak untuk berbasis 0)

Penjelasan:

lmembaca baris dari input (ganti dengan quntuk seluruh input)
eldikonversi ke huruf kecil
"llama"{...}/mengeksekusi blok untuk setiap huruf "llama"
1$menyalin string saat ini
#menemukan indeks
)_kenaikan huruf dan duplikat
T+:Tmenambahkan T (awalnya 0), memperbarui T dan membiarkannya pada tumpukan
\@bertukar item di sekitar, sekarang kita memiliki arus-T, indeks, string yang
>mengiris string mulai dari indeks
;muncul string yang tersisa
]mengumpulkan indeks dalam array
Pada titik ini kita memiliki semua indeks berbasis 1; Jika huruf apa pun tidak ditemukan, array akan memiliki duplikat.
___membuat 3 salinan array
|(dengan 2 salinan array) menghapus duplikat
=membandingkan, menghasilkan 0 jika ada duplikat atau 1 jika tidak
*mengalikan array 0 atau 1 kali sesuai

aditsu
sumber
sourceforge.net/p/cjam/wiki/Home untuk info lebih lanjut tentang bahasa ini. Baru bagi saya.
TankorSmash
12

Perl, 52 byte

Solusinya disediakan sebagai fungsi yang mengambil string sebagai argumen dan mengembalikan daftar posisi.

  • Posisi berbasis satu, pencarian case-sensitive, tanpa baris baru: 52 byte

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

    Pencarian case-sensitive mengembalikan array kosong dalam contoh pertanyaan, karena setelah mencocokkan tiga huruf pertama huruf kecil mhilang dalam teks input.

  • Dukungan baris baru: + 1 byte = 53 byte

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

    Teks sekarang dapat menjangkau beberapa baris.

  • Pencarian case-insensitive: + 1 byte = 54 byte

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

    Sekarang contoh dalam pertanyaan melaporkan daftar posisi indeks, itu adalah angka berbasis satu:

    [45 68 77 106 115]
    
  • Posisi berbasis nol: + 9 byte = 63 byte

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

    Hasil untuk contoh dalam pertanyaan:

    [44 67 76 105 114]
    

Tidak Disatukan:

Varian yang terakhir mencakup kurang lebih varian lainnya.

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
sumber
1
Ini juga mengasumsikan bahwa inputnya adalah ASCII, atau setidaknya bukan Unicode penuh. Kecuali regex Perl menghormati batas-batas grapheme dengan benar hari ini (mereka pasti tidak kembali ketika saya mengalami kemalangan menggunakannya.)
Trejkaz
@Trejkaz: Unicode tidak masalah sama sekali di sini: (a) "llama" adalah ASCII dan huruf-hurufnya tidak bertabrakan dengan karakter Unicode non-ASCII atau representasi byte-nya di UTF-8. (B) Dengan pengkodean multi-byte dalam pikiran, istilah "indeks" dalam pertanyaan akan kurang ditentukan. Indeks dapat berhubungan dengan posisi karakter atau posisi byte (penyimpanan). (c) Mendukung setiap pengkodean dengan posisi karakter berarti, bahwa pengkodean harus diketahui dan perlu disediakan sebagai argumen tambahan.
Heiko Oberdiek
Dua solusi pertama Anda mencetak []dan yang ketiga mencetak [ ]untuk saya (yang lebih lama berfungsi dengan benar). Saya menjalankan "perl, v5.8.8 dibangun untuk msys-64int". Apakah Anda memiliki bug, atau apakah itu bekerja pada versi perl yang berbeda?
Tim S.
@TimS .: []benar untuk solusi pertama, Mtidak cocok dengan pencarian case-sensitive. Pertanyaannya cukup tidak jelas mengenai sensitivitas kasus.
Heiko Oberdiek
Ok, jadi []diterima untuk dua yang pertama. Tetapi tiga solusi pertama masih belum berfungsi dengan baik untuk saya: jika Anda memberikan input yang seharusnya mengembalikan indeks, ia akan kembali[ ]
Tim S.
10

sed, 299 +1

Ya, sed dapat menemukan llama. Tidak, saya tidak bisa menghitung. Ini adalah jawaban terpanjang sejauh ini, pada 299 +1 karakter, karena saya harus mengajar sed untuk menghitung.

Jawaban ini membutuhkan sed dengan ekspresi reguler yang diperluas ( sed -Eatau sed -r). Saya menggunakan OpenBSD sed (1) . Input adalah satu string per baris. (Oleh karena itu, string mungkin tidak mengandung baris baru.) Output adalah garis angka, atau tidak sama sekali.

Penggunaan (karakter +1 untuk -r):

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

Kode sumber (299 karakter):

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 pertama menggantikan llama dengan lima %. (Semua %dalam program ini literal.) Perintah pertama s/%/z/gmengubah apa saja %ke zdalam baris input. Lima perintah berikutnya menemukan llama, sehingga semua lengan di atas bahu mungkin sakit. menjadi A %% lengan di atas bahu% ll% ay% che. Karena masing .*- masing serakah, saya selalu menemukan llama di sebelah kanan: llama llama akan menjadi llama %%%%% . Jika saya tidak bisa mendapatkan lima% , maka /(.*%){5}/!dhapus baris input dan lewati perintah berikutnya.

s/[^%]/z/gberubah setiap karakter tapi %untuk z. Lalu saya memasukkan satu lingkaran. s/(z*)%/\10 z\1/mengubah yang pertama %menjadi 0, menyalin nol atau lebih zdari kiri ke kanan, dan menambahkan satu lagi zke kanan. Ini agar jumlah zkehendak sama dengan indeks. Misalnya, zz%zzz%...menjadi zz0 zzzzzzzz%...karena yang pertama %berada di indeks 2, dan yang berikutnya %adalah di indeks 8. s/z*$//menghapus tambahan zdari ujung string.

Sebelas perintah berikutnya dihitung zdengan menghapus masing z- masing dan menghitung dari 0. Ini penting seperti zzz0, zz1, z2, 3. Juga, 1zzzz9menjadi z1zzz0(lambat 23), atau zzzz9menjadi 1zzz0(lambat 13). Loop ini berlanjut hingga tidak ada lagi %atau z.

kernigh
sumber
1
+1 untuk mengajar sed untuk menghitung. Lebih mudah untuk mengajar llama berhitung daripada sed.
Andreï Kostyrka
9

Fortran - 154 148

Fortran mengisap golf, tetapi hanya untuk membuktikan bahwa string parsing dapat dilakukan dalam bahasa berbasis matematika, saya melakukannya:

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

Saya menyimpan beberapa karakter dengan menghilangkan yang tidak diperlukan fpada akhir endfunctiondan digunakan if(any(r==0))sebagai gantinya if(.not.all(r>0)).

Ini membutuhkan:

  1. s menjadi string dengan teks
  2. amenjadi tes huruf kecil (yaitu, llama)
  3. bmenjadi tes huruf besar (yaitu, LLAMA)

Program penuh, tidak golf adalah

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
sumber
Fortran Modern setidaknya diizinkan di area pitch & putt. FORTRAN IV masih akan bermain golf gila.
ClickRick
4
@ClickRick: Fortran IV adalah sesuatu yang belum saya pelajari. Tidak yakin saya mau. Sesuatu tentang lekukan dan huruf besar paksa mengganggu saya.
Kyle Kanos
7

C # - 119

Membawa string, output array. Tidak ada jika tidak ada string dalamama.

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
sumber
1
+1 untukx=>x>=0
ClickRick
Saya terkesan. Jauh lebih kecil dari ide saya untuk yang ini. Saya memang menemukan Anda bisa membuatnya lebih kecil dengan menginisialisasi ike -1 dan meletakkan .ToArray () pada pernyataan. Pilih, seperti begituint[]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 karakter sehingga tidak peka huruf besar-kecil.

Menentukan fungsi (lambda, secara teknis) f.

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

Kembali niljika tidak ada llama. Jika harus [](array kosong), maka tambahkan saja ||[]sebelum yang terakhir }untuk total 4 karakter tambahan .

Versi yang dapat dibaca:

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 || []
}
Gagang pintu
sumber
Saya minta maaf karena mengedit pertanyaan saya setelah beberapa waktu, tetapi saya baru saja menambahkan bahwa array, jika tidak ada llama, bisa nol, nol, kosong, atau tidak ditentukan.
Cilan
21
Jadi Anda melakukannya dengan llambda?
Mason Wheeler
@ Doorknob akan dua byte lebih pendek dengan menggunakan huruf besar dan bukan huruf kecil tidak?
dstarh
@dstarh Yap, terima kasih
Doorknob
Pikirkan Anda bisa mendapatkan case-insensitivity satu byte lebih murah dengan melakukan index(/#{c}/ialih - alih upcase.
histokrat
6

C - 53

Kompilasi dengan:

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

Saya menguji perintah kompilasi ini dengan gcc cygwin. Lingkungan lain mungkin menangani ruang, dan karakter khusus lainnya berbeda.

Hasil berbasis 0 disimpan ke dalam array r. Isinya tidak terdefinisi jika tidak ada llama di string.

  • Peka huruf besar-kecil (53)

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

  • Case-insensitive (58)

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

Allbeert
sumber
4

JavaScript (ECMAScript 6) - 68 Karakter

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

Asumsikan bahwa string yang akan diuji ada dalam variabel s. Jika Anda ingin mengubahnya menjadi fungsi, tambahkan dulu f=s=>(untuk 5 karakter tambahan).

Output:

[]

Peka huruf besar kecil - 69 Karakter

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

Output:

[68, 80, 93, 105, 114]

Tidak Peka Huruf Besar & Pertama - 74 Karakter

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

Output:

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

Python, 100

Saya adalah pegolf terburuk yang pernah ada. : P

Terima kasih kepada @xnor untuk mencukur 6 byte.

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 berisi array setelahnya.

EDIT : Diperbaiki.

EDIT 2 : len(g)untuk g, o==5untuk o>4per saran @ xnor ini.

EDIT 3 : @ Wolfram memperbaikinya.

cjfaure
sumber
2
o*=(len(o)==5)sangat bagus . Mengerikan, tapi aku menyukainya!
kevinsa5
Saya tidak berpikir tanda kurung luar pada baris itu diperlukan. Anda dapat menyimpan dua karakter dengan menghapusnya.
user2357112 mendukung Monica
@ user2357112 Pada baris terakhir kedua itu? Saya akan menghapus mereka.
cjfaure
Saya berasumsi sadalah string input, bukan? Tidak kemudian harus s.lowermenjadi i.lower? Namun, doe itu
Reinstate Monica
@ Wolfram, ah, ya, akan diperbaiki besok.
cjfaure
3

Python 71

Mengasumsikan masukan dalam s. Output dalam o.

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

Sunting: Diubah dari daftar menjadi tupel untuk menghemat 2 byte.

Pasang kembali Monica
sumber
1
Mengalikan daftar dengan booleans itu menyenangkan, bukan? ; D
cjfaure
Saya suka bagaimana Anda menghindari masalah operlu memulai nonempty untuk mengambil o[-1]. Mungkin itu lebih pendek meskipun hanya memulai osebagai [-1]dan kemudian lakukan o=o[1:]? Mengganggu, -1perjalanan awal memeriksa apakah oberisi -1.
xnor
@ xnor: Saya tidak berpikir -1-Idea dapat dibuat bekerja. Setidaknya, saya tidak berhasil :-( Namun, saya mengubah daftar menjadi tupel untuk menghemat 2 byte. :-)
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)]

Mencicipi:

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

Tidak Disatukan:

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"

Contoh:

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

Matlab, 61 96

Mencari string dan mengganti semuanya hingga setiap kecocokan dengan omong kosong sebelum mencari karakter berikutnya. Akan sdibiarkan tidak terdefinisi jika sebuah kata tidak muncul.

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

Perhatikan bahwa charcount dapat dikurangi jika sensitivitas case dibolehkan.

Versi sebelumnya

 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

Mencari string dan mengganti semuanya hingga setiap kecocokan dengan omong kosong sebelum mencari karakter berikutnya. Penanganan kesalahan (coba-tangkap-akhir) mungkin dapat dibatalkan, maka program akan macet (tetapi s tidak dapat ditentukan seperti yang diperlukan) jika llama tidak ditemukan.

Pelaksanaan:

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

Tanpa penanganan kesalahan:

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
sumber
Seperti idenya, sedikit mengurangi charcount.
Dennis Jaheruddin
2

Bahasa Jawa

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

Python (70)

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

Kami mencari setiap karakter secara 'llama'bergantian, dimulai setelah lokasi karakter yang ditemukan sebelumnya. Jika tidak ada karakter yang ditemukan, cmenjadi nilai default -1, dalam hal ini baris terakhir berubahr menjadi daftar kosong.

Sunting: Ditemukan yang str.find(s,...)dapat dipanggil sebagai s.find(...), menyimpan 4 karakter.

Tidak
sumber
2

OpenEuphoria, 147 128

Saya punya dua contoh. Pertama, yang terpendek:

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

Saya bisa menurunkannya menjadi 126 karakter jika saya menggunakan "atau" bukannya "dan" seperti versi C di atas. Namun, ini juga cocok dengan string ''!-!sebagaillama . Jarang, tetapi masih ada kemungkinan kesalahan.

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

Dan kemudian versi menggunakan ekspresi reguler:

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

Keduanya mengambil input dari STDIN dan memposting ke STDOUT.

EDIT: Contoh regex yang lebih pendek:

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
Prajurit timah
sumber
Apakah mungkin untuk menyelamatkan beberapa dengan membangun regex dengan split/ joinatau explode/ implode, atau apakah OpenEuphoria tidak memiliki versi pendek dari itu?
Peter Taylor
OpenEuphoria dapat melakukan split / join dengan serangkaian karakter, tetapi saya tidak melihat cara untuk melakukannya dengan cara yang lebih pendek. Saya tidak terlalu bagus dengan ekspresi reguler; regex yang digunakan di sini "terinspirasi" (tanpa malu-malu dicuri) dari salah satu contoh lain di halaman ini.
TinSoldier
2

Powershell - 121 85

Saya masih berlatih dengan Powershell, berharap ini bisa diperbaiki

$ s berisi string, hasilnya dalam array $ a

Versi asli

$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

Tidak disatukan

$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

Versi baru, dengan terima kasih banyak kepada @goric

$a=@();$n=$c=0;[char[]]$s|%{if($_-eq"llama"[$n]){$a+=$c;$n++}$c++};$a*=$a.length-gt4
Brian
sumber
Anda dapat menghapus banyak ruang di sana untuk mempersingkat segalanya hingga 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
Juga, Anda dapat mengganti foreach($i in $s.tochararray())dengan [char[]]$s|%, selama Anda mengubah berikutnya $ike a $_. Yang mencukurnya menjadi 93:$a=@();$w="llama";$n=$c=0;[char[]]$s|%{if($_-eq$w[$n]){$a+=$c;$n+=1}$c+=1};$a*=$a.length-gt4
goric
Simpan 5 karakter lagi dengan menghapus $wvariabel sama sekali, karena hanya digunakan satu kali. Cukup if($i-eq"llama"[$n])
sebariskan
..dan, tentu saja, ganti +=1s Anda dengan ++s
goric
1

PHP

belum ada jawaban PHP? Saya pikir bahasa yang sangat berorientasi string dapat mengalahkan setidaknya yang berbasis matematika

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 melawan fortran 154, pekerjaan dilakukan: 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[];
}

jika penelepon selalu melewati string huruf kecil, maka penurunnya menjadi 137

Einacio
sumber
Anda harus menambahkan <?di awal kode Anda untuk membuatnya valid. Maaf ...
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:[]}

Menentukan fungsi yang menggunakan string sebagai satu-satunya argumen (argumen kedua adalah yang murah var) dan mengembalikan array kosong atau array 5-elemen.

Turun menjadi 108 jika saya mengambil input pada variabel char tunggal ( s) dan meninggalkan output di yang lain ( b):

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

Sunting: Mengganti peta untuk for loop.

Aaron Dufour
sumber
Versi ECMAScript 6 (81 karakter) -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]

Contoh penggunaan di konsol 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 menggunakan pengindeksan berbasis 1. Mengembalikan daftar kosong []jika tidak ada urutan llama yang ditemukan (case-sensitive).

Tidak Disatukan:

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

APL, 47

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

Bukan kode terpendek, tetapi cukup bengkok, dengan cara APL.

Penjelasan

'amall',⊂⍬⍞ Buatlah array dengan 6 elemen: huruf 'amall' dan subarray dari 2 elemen, dengan sendirinya subarrays: array kosong dan sederet karakter yang dibaca dari input.

{...}/... Kurangi (kanan-lipat) array 6-elemen menggunakan fungsi yang disediakan.

a s←⍵ Menguraikan argumen yang tepat ke dalam array indeks dan substring yang tersisa (awalnya array kosong dan string penuh.)

~⍺∊s:⍬⍬ Jika substring tidak mengandung huruf berikutnya hentikan perhitungan dan kembalikan array kosong.

a,←n←s⍳⍺ Kalau tidak, temukan posisinya, panggil saja n, dan tambahkan ke array indeks.

a(n↓s) Buat dan kembalikan array yang terdiri dari 2 elemen: array indeks yang diperluas dan substring yang tersisa.

+\↑⊃... Buka kemasan keluaran lipat, ambil elemen pertama (array indeks) dan pindai dengan tambahan, untuk mengubah offset relatif menjadi yang absolut.

Contohnya

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

Julia, 76

Contoh regex lain menggunakan bahasa Julia.

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