Jalankan karakter terpanjang dalam sebuah string


19

Tantangan Anda: Tulis fungsi yang mengambil string s, karakter c, dan temukan jangka waktu terpanjang cdalam s. Panjang run akan l.

Aturan :

  • Jika spanjangnya 0 atau ckosong, lharus 0.
  • Jika tidak ada contoh cdi s, lharus 0.
  • Celah standar dan Aturan I / O Standar berlaku.
  • Tidak masalah di mana dalam smenjalankan cs terletak, lharus sama.
  • Setiap karakter ASCII yang dapat dicetak dapat muncul di sdan c.

Kasus uji :

s,c --> l
"Hello, World!",'l'  -->  2
"Foobar",'o'         -->  2
"abcdef",'e'         -->  1
"three   spaces",' ' -->  3
"xxx xxxx xx",'x'    -->  4
"xxxx xx xxx",'x'    -->  4
"",'a'               -->  0
"anything",''        -->  0

Pemenang :

Seperti halnya , jawaban terpendek dalam setiap bahasa menang.



Bisakah Anda memasukkan kasus tepi kosong sdan cyang tidak terkandung dalam non-kosong sdalam kasus pengujian Anda?
Martin Ender

Apa rentang karakter yang dapat muncul di s/ c?
Martin Ender

6
cdapat kosong? Dalam banyak bahasa, karakter hanyalah bilangan bulat dengan semantik khusus, dan Anda juga tidak bisa memiliki bilangan bulat kosong.
Martin Ender

14
Itu tidak masuk akal bagi saya. Kasing uji Anda menunjukkan bahwa kami harus mendukungnya. Jika kita tidak harus mendukungnya, maka menentukan output yang diperlukan tidak masuk akal, karena saya selalu bisa mengatakan bahwa itu tidak didukung jika solusi saya akan melakukan sesuatu yang lain dalam kasus itu.
Martin Ender

Jawaban:


12

05AB1E , 5 byte

Kode:

SQγOM

Menggunakan penyandian 05AB1E . Cobalah online!

Penjelasan:

SQ      # Check for each character if it is equal to the second input
  γ     # Split the list of zeros and ones into groups
   O    # Sum each array in the arrays
    M   # Get the maximum

2
Solusi bagus! Saya tahu ada cara untuk melakukannya seperti ini, saya hanya tidak bisa memikirkannya.
Riley

γ¢Mtidak berkinerja seperti yang saya pikir akan, pikir itu akan menjadi 3-byte.
Magic Gurita Guci

8

Mathematica, 35 byte

Max[Tr/@Split@Boole@Thread[#==#2]]&

Fungsi murni mengambil daftar karakter dan karakter lain sebagai input dan mengembalikan bilangan bulat negatif. Ditingkatkan pada upaya pertama saya menggunakan pengamatan Adnan (go upvote!) Yang harus diuji untuk menyamakan karakter khusus sebelum memisahkan array.

Thread[#==#2]memeriksa apakah setiap karakter input dalam argumen pertama sama dengan karakter yang diberikan sebagai argumen kedua. Boolemengkonversi Trues dan s yang dihasilkan Falsemenjadi 1s dan 0s. Splitmembagi daftar menjadi beberapa elemen berturut-turut; Tr/@menjumlahkan setiap sublist, dan Maxmenemukan pemenang. (Karena cara Maxkerjanya, jika argumen pertama adalah daftar kosong, maka fungsi ini kembali -∞. Jadi, Anda tahu, jangan lakukan itu.)

pengiriman pertama (51 byte)

Max[Split@#/.a:{c_String..}:>Boole[c==#2]Length@a]&

Split@#membagi input menjadi karakter berturut-turut, seperti {{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}untuk kasus uji keempat. /.a:{c_String..}:>mengganti setiap subekspresi ayang merupakan daftar karakter yang diulang cdengan Length@adikalikan dengan Boole[c==#2], yaitu 1jika csama dengan karakter input dan 0sebaliknya. Kemudian Maxekstrak jawabannya.


7

Japt , 20 18 15 byte

fV+Vî+)ª0)n o l

Cobalah online!

Disimpan 5 byte berkat obarakon dan produk ETH


1
Saya bermain-main dengan solusi saya sendiri untuk sementara waktu dan berakhir dengan solusi yang hampir milik Anda, tetapi lebih pendek. Jika Anda menggunakan fV+Vî+)... Saya akan membiarkan Anda mencari tahu sisanya :-)
ETHproduk

@ ETHproductions "If s is of length 0 or c is empty, l should be 0", saya mungkin menganggap itu terlalu harfiah
Tom

Oh, saya tidak menyadari bahwa gagal setiap kali stidak mengandung contoh c.
ETHproduk

7

Python , 38 byte

f=lambda s,c:+(c in s)and-~f(s,c+c[0])

Cobalah online!

Dennis menyimpan 3 byte dengan memperbarui cke serangkaian karakter yang digandakan daripada memperbarui secara berulang nomor untuk dikalikan c.


1
f=lambda s,c:c in s and-~f(s,c+c[0])menghemat 6 byte (3 jika False tidak diizinkan).
Dennis


4

Haskell, 43 39 byte

f c=maximum.scanl(\n k->sum[n+1|c==k])0

Cobalah online!

Jalankan melalui string dan ganti char saat ini dengan penghitung yang meningkat setiap kali sama catau setel ulang 0jika tidak. Ambil maksimum daftar.

Terima kasih kepada @xnor untuk 4 byte.


Anda bisa melakukannya sum[n+1|c==k].
xnor

@ xnor: Bagus! Saya sudah bereksperimen dengan *fromEnum(c==k), baik pointfree dan lambda, tapi itu selalu 2 atau 3 byte lebih lama.
nimi

4

C # 116 115 byte

Golf kode pertama saya

Diedit karena pengiriman awal adalah cuplikan dan tidak ada namespace yang diperlukan untuk regex

Edit penulisan ulang lengkap # 2 untuk mendukung karakter dengan makna regex khusus

menggunakan System.Linq; s => c => System.Text.RegularExpressions.Regex.Replace (s, "[^" + c + "]", ++ c + ""). Split (c) .Max (x => x.Panjang);

using System.Linq;s=>c=>{var r=(char)(c-1);return string.Join("",s.Select(x=>x==c?c:r)).Split(r).Max(x=>x.Length)};

3
Saya tidak tahu C # tetapi sepertinya kode Anda mengharapkan variabel cdan stelah ditentukan sebelumnya. Kami menyebutnya "snipet kode" dan tidak diizinkan. Anda mungkin dapat merestrukturisasi kode Anda sebagai fungsi anonim atau untuk mengatur variabel-variabel itu untuk dimasukkan. Keduanya diizinkan.
Wheat Wizard

Apakah itu bekerja? (Lihat hasil edit di atas)
Sapu

1
Sekali lagi saya tidak tahu C #, tetapi sepertinya tidak. Anda mungkin ingin memeriksa kiat kami untuk bermain golf di C # di sini untuk saran yang lebih berpengalaman di C #.
Wheat Wizard

Terima kasih atas tautannya! Saya pasti akan membaca dengan teliti tips C #
Sapu

3
Hai, hanya beberapa komentar umum untuk bermain golf di C #, Anda dapat mendefinisikan fungsi Anda sebagai (s,c)=>. Anda harus menggunakan System.Text.RegularExpressions.Regexatau menambahkan pernyataan menggunakan tepat sebelum fungsi Anda.
LiefdeWen

4

JavaScript (ES6), 54 53 51 byte

-2 byte terima
kasih kepada @Neil -1 byte terima kasih kepada @apsillers

s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j

Mengambil input dalam sintaks currying: f("foobar")("o").

Cuplikan Tes

f=
s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j
String: <input id=I> Letter: <input id=J maxlength=1 size=1> <button onclick='O.innerHTML+=`f("${I.value}")("${J.value}") = ${f(I.value)(J.value)}\n`'>Run</button><pre id="O"></pre>

Opsi lain menggunakan evaldan for(54 byte)

s=>c=>eval("i=j=0;for(x of s)i=x==c&&i+1,i>j?j=i:0;j")

Jawaban Lama menggunakan Regex (85 byte)

s=>c=>c?Math.max(...s.match(eval(`/${/\w/.test(c)?c:"\\"+c}*/g`)).map(x=>x.length)):0

1
Saya pikir x==c?i++:i=0bisa saja i=x==c&&i+1karena falsehasil x==cperbandingan akan diperlakukan sebagai 0perbandingan numerik dan kenaikan (dan tidak akan pernah menjadi nilai pengembalian, karena angka apa pun, termasuk 0, jakan selalu mengambil prioritas di atas seperti nol falsedi i)
apsillers

@apsillers Terima kasih, diperbarui, tetapi apa maksud Anda tentang hal itu tidak pernah menjadi nilai pengembalian?
Justin Mariner

Maaf bila membingungkan; Saya baru saja menjelaskan bahwa perubahan tidak akan pernah membuat program Anda kembali false(karena tantangan selalu mengharuskannya untuk mengembalikan nomor)
apsillers

1
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&jtampaknya menghemat beberapa byte.
Neil

1
Maaf, saya memposting kode yang salah, maksud saya memposting f=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j, yang merupakan byte lebih pendek.
Neil

4

JavaScript (Firefox 30-57), 75 72 byte

(s,c)=>Math.max(0,...(for(s of s.split(/((.)\2*)/))if(s[0]==c)s.length))

Cuplikan yang kompatibel dengan ES6:

f=
(s,c)=>Math.max(0,...s.split(/((.)\2*)/).filter(s=>s[0]==c).map(s=>s.length))
<div oninput=o.textContent=f(s.value,c.value)><input id=s><input id=c maxlength=1 size=1><pre id=o>0

split mengembalikan sekelompok string kosong dan karakter tunggal serta menjalankan tetapi ini tidak mempengaruhi hasilnya.


3

Mikro , 112 byte

{T l m 1+:Q # T Q T l~:r}:Z{T[0]+}:X
{i s m:n
n p = if(Z,X)
i L=if(,a)}:a
0\\:C:s:i"":p"":n[0]:T
s l:L
a
T l m:\


2

Perl 6 ,  45 43  42 byte

->$_,$c {$c&&$_??.comb(/$c+/)».chars.max!!0}

Menguji

->$_,$c {$c&&$_??.comb(/$c+/).max.chars!!0}

Menguji

->$_,$c {$c&$_??.comb(/$c+/).max.chars!!0}

Menguji

Diperluas:

-> $_, $c {       # pointy block lambda

    $c & $_       # AND junction of $c and $_
                  #   empty $c would run forever
                  #   empty $_ would return 4 ( "-Inf".chars )

  ??              # if True (neither are empty)

    .comb(/$c+/)  # find all the substrings
    .max          # find the max
    .chars        # get the length

  !!              # if False (either is empty)

    0             # return 0
}

2

JavaScript, ES6, 52

Solusi rekursif yang memperlakukan input string sebagai array (catatan: input awal masih berupa string) dan menggunakan karakter karakter kiri-ke-kanan C:

f=([C,...s],c,t=0,T=0)=>C?f(s,c,C==c&&++t,t>T?t:T):T

Lacak run saat ini tdan global terbaik diT .

Penjelasan:

f=            // function is stored in `f` (for recursion)
  ([C,...s],  // turn input string in first-char `C` and the rest in `s`
   c,         // argument `c` to search for
   t=0,T=0)   // current total `t`, best total `T`
     =>
        C?             // if there is still any char left in the string
          f(s,c,       // recursively call `f`
            C==c&&++t, // increment `t` if char is match, or set `t` to `false`
            t>T?t:T)   // set global `T` to max of `t` and `T`
          :T           // when string is depleted, return `T`

Pengaturan tuntuk falsenon-pertandingan bekerja karena setiap kali tbertambah, falsediperlakukan sebagai 0(yaitu, false + 1adalah 1), dan falsetidak akan pernah membandingkan parutan daripada nilai dalam dunia-max T.


1
Solusi yang bagus, saya tidak terbiasa dengan [C,...s]sintaks. Haruskah saya membantu slice()byte dari posting saya sendiri.
Rick Hitchcock

2

Jelly , 5 byte

=ŒgṀS

Ini adalah tautan / fungsi diad yang mengambil string dan karakter. Perhatikan bahwa ini tidak dapat berfungsi sebagai program penuh, karena input dari argumen baris perintah menggunakan sintaksis Python, dan Python - tidak seperti Jelly - tidak membedakan string tunggal dari karakter.

Cobalah online!

Bagaimana itu bekerja

=ŒgṀS  Main link. Left argument: s (string). Right argument: c (character)

=      Compare all characters in s with c, yielding 1 for c and 0 otherwise.
 Œg    Group adjacent, equal Booleans in the resulting array.
   Ṁ   Take the maximum. Note that any array of 1's will be greater than any array
       of 0's, while two arrays of the same Booleans are compared by length.
    S  Take the sum, yielding the length for an array of 1's and 0 otherwise.


2

APL (Dyalog) , 18 11 byte

Membutuhkan swapping dengan dalam Versi 16.0 atau memiliki ⎕ML←3(default pada banyak sistem).

⌈/0,≢¨⊂⍨⎕=⎕

Cobalah online!

⎕=⎕ Boolean untuk kesetaraan antara dua input

⊂⍨ partisi mandiri (mulai partisi di mana elemen non-nol lebih besar dari pendahulunya)

≢¨ tally masing-masing

0, tambahkan nol (untuk kasus input kosong)

⌈/ maks mereka


Solusi lama

Anjuran pertama untuk s , lalu untuk c

⌈/0,(⎕,¨'+')⎕S 1⊢⎕

Cobalah online!

 meminta s

 untuk itu

(... )⎕S 1PCRE S earch untuk panjang kejadian

'+' simbol plus (artinya satu atau lebih)

 ditambahkan ke masing-masing elemen

 diminta untuk c

0, tambahkan nol (untuk kasus input kosong)

⌈/ maks mereka

c harus diberikan sebagai vektor 1-elemen dari string yang terlampir jika perlu melarikan diri.


2

PHP, 70 67 byte

tiga versi:

while(~$c=$argv[1][$i++])$x=max($x,$n=($c==$argv[2])*++$n);echo+$x;
while(~$c=$argv[1][$i++])$x=max($x,$n=$c==$argv[2]?++$n:0);echo+$x;
for(;++$n&&~$c=$argv[1][$i++];)$x=max($x,$n*=$c==$argv[2]);echo+$x;

mengambil input dari argumen baris perintah; jalankan dengan -ratau uji secara online .


2

PHP , 70 byte

for(;~$c=$argv[1][$i++];)$r[]=$argv[2]==$c?++$n:$n=0;echo$r?max($r):0;

Cobalah online!

PHP , 75 byte

for(;~$s=substr($argv[1],$i++);)$r[]=strspn($s,$argv[2]);echo max($r?:[0]);

Cobalah online!

PHP , 83 byte

<?=@preg_match_all("<".preg_quote($argv[2])."+>",$argv[1],$t)?strlen(max($t[0])):0;

Cobalah online!

+8 Bytes yang harus dihindari @

<?=($a=$argv[2])&&preg_match_all("<".preg_quote($a)."+>",$argv[1],$t)?strlen(max($t[0])):0;

Versi 67 byte akan gagal untuk setiap char khusus regex (dan #tentu saja).
Titus

... dan ~mungkin gagal untuk chr(207).
Titus

@Titus Done dan Input hanya boleh karakter Ascii
Jörg Hülsermann

mata yang bagus untuk ++$n! Anda berarti ascii yang dapat dicetak. ;)
Titus

1
echo$r?max($r):0;menghemat satu byte
Titus

2

JavaScript (ES6), 47 40 38 byte

(Disimpan 7 byte berkat @Neil, dan 2 byte berkat @HermanLauenstein.)

s=>g=c=>c&&s.includes(c)?1+g(c+c[0]):0

Penjelasan:

Secara rekursif mencari jangka yang lebih panjang sampai tidak ada yang ditemukan

Potongan:


1
Sangat sederhana! Cemerlang!
apsillers

Tidak bisakah kamu melakukannya f=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])?
Neil

Atau lebih baik lagi, cari saja s=>g=c=>c&&s.includes(c)&&1+g(c+c[0]).
Neil

Itu hampir berhasil, tetapi mengembalikan "false" dan string nol untuk dua kasus terakhir. Itu diperbaiki dengan menambahkan ||0, yang masih lebih pendek dari solusi saya.
Rick Hitchcock

Ini f=bukan bagian dari versi kari, karena hanya fungsi bagian dalam yang bersifat rekursif.
Neil

2

Jelly, 10 9 byte

f⁴L
ŒgÇ€Ṁ

Penjelasan:

f⁴L
f⁴      -Filter by the character argument.
  L     -Return Length of filtered String.

ŒgÇ€»/
Œg      -Group string by runs of characters.
  ǀ    -Run above function on each group.
    Ṁ   -Return the largest in the list.

Cobalah online!


Anda dapat menyimpan beberapa byte dengan Œgf€L€Ṁ.
Dennis


1

Haskell , 66 byte

import Data.List
((maximum.(0:).map length).).(.group).filter.elem

Cobalah online!

Versi yang sedikit lebih mudah dibaca - bukan pointfree:

f c s = maximum (0:(map length (filter (elem c) (group s))))

Mengelompokkan string dengan huruf, lalu memfilter menurut grup yang berisi karakter yang tepat, lalu menemukan panjang, menambahkan 0 ke daftar panjang jika tidak muncul, dan akhirnya menemukan nilai maksimum.


1

Mathematica, 109 byte

(s=Differences[First/@StringPosition[#,#2]];k=t=0;Table[If[s[[i]]==1,t++;If[k<t,k=t],t=0],{i,Length@s}];k+1)&


memasukkan

["xxx xxxx xx", "x"]



1

CJam , 20 19 18 16 byte

0q~e`f{~@=*}$+W=

Cobalah online!

Penjelasan

0                 e# Push 0. We'll need it later.
 q~               e# Read and eval input. Pushes c and s to the stack.
   e`             e# Run-length encode s: turns it into an array of [length, char] pairs.
     f{           e# Map over these pairs using c an extra parameter:
       ~          e#  Dump the pair to the stack.
        @=        e#  Bring c to the top, check equality with the char, pushing 0 or 1.
          *       e#  Multiply the length by the result.
           }      e# (end map)
            $     e# Sort the resulting list in ascending order.
             +    e# Prepend the 0 from before, in case it's empty.
              W=  e# Get the last element.

1

Excel, 56 byte

{=MAX(IFERROR(FIND(REPT(A2,ROW(A:A)),A1)^0*ROW(A:A),0))}

sharus menjadi input A1.
charus menjadi input A2.
Formula harus berupa rumus array ( Ctrl+ Shift+ Enter) yang menambahkan tanda kurung keriting { }.

Secara teknis, ini hanya dapat menangani di mana jangka waktu terpanjang kurang dari 1.048.576 (yaitu 2 ^ 20) karena itulah bagaimana baris Excel saat ini akan membiarkan Anda miliki di lembar kerja. Karena memuat jutaan nilai ke dalam memori setiap kali dihitung ulang, ini bukan formula cepat .


1

MATL , 15 byte

0i0v=dfd1L)0hX>

Cobalah online!

Algoritma dasar sangat sederhana (tidak menggunakan split!), Tapi saya harus melempar masuk 0i0vdan0h mengizinkan kasus tepi. Namun, saya pikir pendekatannya bagus, dan mungkin saya masih bisa menemukan teknik lain untuk menangani kasus tepi: algoritme menemukan jangka terpanjang di tengah-tengah string baik-baik saja, tetapi tidak untuk karakter tunggal atau string kosong; Saya masih menguji apakah saya bisa 'pad' variabel di tempat yang lebih baik untuk hasil yang lebih baik.

0i0v % Prepends and appends a zero to the (implicit) input.
   = % Element-wise equality with the desired char (implicit input)
   d % Pairwise difference. Results in a 1 at the start of a run, and -1 at the end.
   f % Get indices of 1's and -1's.
   d % Difference to get length of the runs (as well as length of non-runs)
 1L) % Only select runs, throw out non-runs. We now have an array of all run lengths.
  0h % 'Find' (`f`) returns empty if no run is found, so append a zero to the previous array.
  X> % Maximum value.

Tidak berfungsi saat kosong c. Kemudian lagi, saya kira setiap string berisi deretan kosong kosong di antara setiap karakter :)


1

R , 66 58 byte

-8 byte berkat BLT dan MickyT

function(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)

mengembalikan fungsi anonim. TIO memiliki perbedaan 1 byte karenael tidak berfungsi di sana karena alasan yang tidak dapat dijelaskan.

Cobalah online!


Simpan satu byte denganr=rle(el(strsplit(s,'')))
BLT

1
Abaikan komentar saya sebelumnya jika Anda melihatnya. Ada yang lebih baik untuk Andafunction(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
MickyT

@BLT eltidak bekerja pada TIO (tidak tahu mengapa) dan saya hanya menyalin dan menempelkannya dari kode kerja di sana jadi saya harus ingat untuk memasukkannya kembali ke @MickyT sangat pintar! Terima kasih!
Giuseppe

1

Java 8, 67 65 byte

s->c->{int t=0,m=0;for(char x:s)m=m>(t=x==c?t+1:0)?m:t;return m;}

-2 byte terima kasih kepada @ OlivierGrégoire

Mengambil input ssebagai char[], dan csebagaichar

Penjelasan:

Coba di sini.

s->c->{          // Method with char[] and char parameters and int return-type
  int t=0,       //  Temp counter-integer
      m=0;       //  Max integer
  for(char a:s)  //  Loop over the characters of the input
    m=m>(
     t=x==c?     //   If the current character equals the input-character:
      t+1        //    Raise `t` by 1
      :          //   Else:
       0)        //    Reset `t` to 0
    ?m:t;        //   If `t` is now larger than `m`, put `t` as new max into `m`
                 //  End of loop (implicit / single-line body)
  return m;      //  Return the resulting max
}                // End of method

1
m=m>(t=x==c?t+1:0)?m:t;lebih pendek dari {t=x==c?t+1:0;m=m>t?m:t;}.
Olivier Grégoire

Meskipun lebih lama wayyyyyy, saya suka pemikiran pertama saya s->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0)
:;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.