Dizedeki bir karakterin en uzun çalışması


19

Buradaki zorluk: Bir dize alır bir işlevi yazın s, bir karakteri cve en uzun vadede uzunluğunu bulur ciçinde s. Koşunun uzunluğu olacak l.

Kurallar :

  • Eğer s0 uzunluğunda veya cboş, l0 olmalıdır.
  • Hiçbir örneklerini varsa cin s, l0 olmalıdır.
  • Standart boşluklar ve Standart I / O Kuralları geçerlidir.
  • S skoşusu nerede olursa olsun , aynı olmalıdır.cl
  • Yazdırılabilir ASCII karakterleri sve öğelerinde görünebilir c.

Test senaryoları :

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

Kazanan :

Olduğu gibi her dilde en kısa cevap kazanır.



Eğer kenar boş vakalarını içerebilir sve bir cboş olmayan yer almayan stest durumlarda?
Martin Ender

Ne karakter aralığı görünebilir s/ ' c?
Martin Ender

6
cboş olabilir mi? Birçok dilde, bir karakter yalnızca özel anlambilim ile bir tamsayıdır ve gerçekten de boş bir tam sayıya sahip olamazsınız.
Martin Ender

14
Bu benim için gerçekten mantıklı değil. Test durumlarınız bunu desteklememiz gerektiğini gösteriyor. Bunu desteklememiz gerekmiyorsa, gerekli çıktıyı belirtmek mantıklı değildir, çünkü her zaman çözümüm bu durumda başka bir şey yapacaksa desteklenmediğini söyleyebilirim.
Martin Ender

Yanıtlar:


12

05AB1E , 5 bayt

Kod:

SQγOM

05AB1E kodlamasını kullanır . Çevrimiçi deneyin!

Açıklama:

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
Güzel çözüm! Böyle yapmanın bir yolu olduğunu biliyordum, düşünemedim.
Riley

γ¢Mdüşündüğüm gibi performans göstermiyor, 3 bayt olacağını düşündüm.
Sihirli Ahtapot Urn

8

Mathematica, 35 bayt

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

Karakter olarak bir liste ve başka bir karakteri girdi olarak alan ve negatif olmayan bir tam sayı döndüren saf işlev. Diziyi bölmeden önce özel karaktere eşit olup olmadığını test etmek için Adnan'ın gözlemini (yukarı git!) Kullanarak ilk çabam geliştirildi .

Thread[#==#2]ilk bağımsız değişkendeki her girdi karakterinin ikinci bağımsız değişken olarak verilen karakterle aynı olup olmadığını kontrol eder. Booleortaya çıkan Trues ve Falses'yi 1s ve 0s'ye dönüştürür. Splitlisteyi ardışık elemanların çalışmalarına böler; Tr/@her alt listeyi toplar ve Maxkazananı bulur. (Nasıl Maxçalıştığı nedeniyle , ilk argüman boş liste ise, bu işlev geri döner -∞. Yani, biliyorsunuz, bunu yapma.)

ilk gönderim (51 bayt)

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

Split@#girişi {{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}dördüncü test senaryosu gibi ardışık karakterlerin çalışmalarına böler . /.a:{c_String..}:>Her bir alt ifade yerine atekrarlanan bir karakter bir listesi cile Length@açarpılır Boole[c==#2]olup, 1eğer cgirdi karakter eşit olur ve 0, aksi. Sonra Maxcevabı çıkarır.


7

Japt , 20 18 15 bayt

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

Çevrimiçi deneyin!

Obarakon ve ETHproductions sayesinde 5 bayt tasarruf


1
Bir süre kendi çözümümle oynadım ve neredeyse seninki ama daha kısa bir çözüm buldum. Eğer kullanırsanız fV+Vî+)... Gerisini anlamanıza izin vereceğim :-)
ETHproductions

@ETHproductions "If s is of length 0 or c is empty, l should be 0", bunu tam anlamıyla alıyor olabilirim
Tom

Oh, sherhangi bir örneği içermediğinde başarısız olduğunu fark etmemiştim c.
ETHproductions

7

Python , 38 bayt

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

Çevrimiçi deneyin!

Dennis c, bir sayıyı çoğaltmak için yinelemeli olarak güncellemek yerine çoğaltılan karakter dizesine güncelleyerek 3 bayt kaydetti c.


1
f=lambda s,c:c in s and-~f(s,c+c[0])6 bayt kaydeder ( False'a izin verilmiyorsa 3).
Dennis


4

Haskell, 43 39 bayt

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

Çevrimiçi deneyin!

Dizeyi çalıştırın ve geçerli karakteri eşit olduğunda artan bir sayaçla değiştirin cveya 0değilse sıfırlayın . Listenin maksimumu alın.

4 byte için @xnor'a teşekkürler.


Yapabilirsin sum[n+1|c==k].
xnor

@xnor: Güzel! *fromEnum(c==k)Hem pointfree hem de lambda ile denedim, ama her zaman 2 veya 3 bayt daha uzun oldu.
nimi

4

C # 116115 bayt

İlk kodum golf

İlk gönderim bir snippet olduğu ve normal ifade için gerekli ad alanı eksik olduğu için düzenlendi

Özel regex anlamları olan karakterleri desteklemek için # 2 tam yeniden yazmayı düzenleyin

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

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
C # bilmiyorum ama kod değişkenleri cve sönceden tanımlanmış bekliyor gibi görünüyor . Buna "kod snippet'i" diyoruz ve buna izin verilmiyor. Kodunuzu anonim bir işlev olarak yeniden yapılandırabilir veya bu değişkenleri giriş olarak ayarlayabilirsiniz. Her ikisine de izin verilir.
Buğday Büyücüsü

İşe yarıyor mu? (Yukarıdaki düzenlemeye bakın)
Süpürge

1
Bir kez daha C # bilmiyorum, ama öyle görünüyor. Burada C # daha deneyimli tavsiye için burada C # golf ipuçları bizim kontrol etmek isteyebilirsiniz .
Buğday Büyücüsü

Linkler için teşekkürler! Kesinlikle C # ipuçlarını inceleyeceğim
Süpürge

3
Merhaba sadece C # golf için bazı genel yorumlar, fonksiyonunuzu olarak tanımlayabilirsiniz (s,c)=>. System.Text.RegularExpressions.Regexİşlevinizden hemen önce bir use deyimi kullanmanız veya eklemeniz gerekir.
LiefdeWen

4

JavaScript (ES6), 54 53 51 bayt

@Neil sayesinde -2 bayt @apsillers
sayesinde -1 bayt

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

Tımar sözdiziminde girişi Alır: f("foobar")("o").

Snippet'i Test Et

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>

evalVe for(54 bayt) kullanan başka bir seçenek

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

Regex kullanarak eski cevap (85 bayt)

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

1
Bence x==c?i++:i=0sadece olabilir i=x==c&&i+1bir yana falseüzerinde sonuç x==ckarşılaştırma bir şekilde ele alınacaktır 0(dahil herhangi bir sayı beri ve dönüş değeri asla sayısal karşılaştırmalar ve artışlarla için 0de, jher zaman sıfır gibi daha öncelikli olur falseiçinde i)
apsillers

@apsillers Teşekkürler, güncellendi, ama bunun asla dönüş değeri olmaması ne demek?
Justin Mariner

Karışıklık için özür dilerim; Sadece değişikliğin asla programınızı geri getirmeyeceğini açıklıyordum false(çünkü meydan okuma her zaman bir sayı döndürmesini gerektirir)
apsillers

1
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&jbirkaç bayt kurtarıyor gibi görünüyor.
Neil

1
Üzgünüm, yanlış kod gönderdim, göndermek istedim f=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j, bu byte daha kısa.
Neil

4

JavaScript (Firefox 30-57), 75 72 bayt

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

ES6 uyumlu snippet:

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 bir sürü boş dize ve tek karakter yanı sıra çalışır döndürür, ancak bu sonucu etkilemez.


3

Mikro , 112 bayt

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

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

Dene

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

Dene

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

Dene

Expanded:

-> $_, $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

Dize girişini dizi olarak ele alan özyinelemeli çözüm (not: başlangıç ​​girdisi hala bir dizedir) ve karakterde soldan sağa tüketir C:

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

Şu anki alıştırma tve küresel en iyiyi izler T.

Açıklama:

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`

Ayar tiçin falseher çünkü olmayan maçlara çalışır tartırılır, falseolarak ele alınır 0(yani false + 1olan 1) ve falseküresel-max herhangi değerden rende karşılaştırmak asla T.


1
Güzel bir çözüm, sentaksa aşina değildim [C,...s]. slice()Kendi gönderilerimden gelen baytları bana yardımcı olmalı .
Rick Hitchcock

2

Jöle , 5 bayt

=ŒgṀS

Bu, bir dize ve bir karakter alan ikili bir bağlantı / işlevdir. Komut satırı bağımsız değişkenlerinden gelen girdi Python sözdizimini kullandığından ve Jelly'den farklı olarak Python'un tekil dizeleri karakterlerden ayırmadığından tam bir program olarak çalışamayacağını unutmayın.

Çevrimiçi deneyin!

Nasıl çalışır

=Œ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 bayt

Sürüm 16.0 ile değiştirmeyi veya sahip olmayı gerektirir ⎕ML←3(birçok sistemde varsayılan).

⌈/0,≢¨⊂⍨⎕=⎕

Çevrimiçi deneyin!

⎕=⎕ İki giriş arasında eşitlik için Boole

⊂⍨ kendi kendine bölme (sıfır olmayan bir öğenin öncekinden daha büyük olduğu bölümlere başlayın)

≢¨ her biri taksitli

0, sıfıra ekle (boş giriş durumları için)

⌈/ bunlardan en fazla


Eski çözüm

Önce s sonra da c

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

Çevrimiçi deneyin!

 s istemi

 bunun için

()⎕S 1PCRE S ,

'+' artı sembolü (bir veya daha fazla anlamına gelir)

 öğelerinin her birine

 istendi c

0, sıfıra ekle (boş giriş durumları için)

⌈/ bunlardan en fazla

c , kaçan ihtiyacı varsa, kapalı bir tel 1 eleman vektörü olarak verilmelidir.


2

PHP, 70 67 bayt

üç versiyon:

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;

komut satırı bağımsız değişkenlerinden girdi alır; çevrimiçi olarak çalıştırın -rveya test edin .


2

PHP , 70 bayt

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

Çevrimiçi deneyin!

PHP , 75 bayt

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

Çevrimiçi deneyin!

PHP , 83 bayt

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

Çevrimiçi deneyin!

Kaçınılması gereken +8 bayt @

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

67 bayt sürümü herhangi bir normal ifade özel karakter (ve #tabii ki) için başarısız olacaktır .
Titus

... ve ~başarısız olabilir chr(207).
Titus

@Titus Done and Input yalnızca Ascii karakterleri olabilir
Jörg Hülsermann

için iyi göz ++$n ! Basılabilir ascii demek istedin. ;)
Titus

1
echo$r?max($r):0; bir bayt kaydeder
Titus

2

JavaScript (ES6), 47 40 38 bayt

(@Neil sayesinde 7 bayt ve @HermanLauenstein sayesinde 2 bayt kaydedildi.)

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

Açıklama:

Hiçbiri bulunana kadar özyineli olarak daha uzun bir süre arar.

Pasaj:


1
Çok basit! Parlak!
apsillers

Yapamaz mısın f=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])?
Neil

Ya da daha iyisi, köri s=>g=c=>c&&s.includes(c)&&1+g(c+c[0]).
Neil

Bu neredeyse işe yarıyor, ancak son iki durum için "false" ve null dize döndürüyor. Bu ||0, benim çözümümden hala daha kısa olan ekleme ile düzeltildi .
Rick Hitchcock

f=Sadece iç fonksiyonu özyinelemeli olduğundan, curried versiyonunun bir parçası değildir.
Neil

2

Jöle, 10 9 bayt

f⁴L
ŒgÇ€Ṁ

Açıklama:

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.

Çevrimiçi deneyin!


İle birkaç bayt kaydedebilirsiniz Œgf€L€Ṁ.
Dennis


1

Haskell , 66 bayt

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

Çevrimiçi deneyin!

Okumak biraz daha kolay - anlamsız değil:

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

Dizeyi harfe göre gruplandırır, ardından doğru karakteri içeren gruplara göre filtreler, sonra uzunlukları bulur, görünmüyorsa uzunluk listesine 0 ekler ve son olarak maksimum değeri bulur.


1

Mathematica, 109 bayt

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


giriş

["xxx xxxx xx", "x"]



1

CJam , 20 19 18 16 bayt

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

Çevrimiçi deneyin!

açıklama

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 bayt

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

sgirilmelidir A1.
cgirilmelidir A2.
Formül bir dizi formülü olmalıdır ( Ctrl+ Shift+Enter küme parantezleri ekleyen ){ } .

Teknik olarak, bu yalnızca en uzun çalışmanın 1.048.576'dan (2 ^ 20) az olduğu durumlarda işleyebilir, çünkü mevcut Excel'in satırları bir çalışma sayfasında bulunmanıza izin verir. Her yeniden hesaplamada milyon + değeri belleğe yüklediğinden, bu hızlı bir formül değildir .


1

MATL , 15 bayt

0i0v=dfd1L)0hX>

Çevrimiçi deneyin!

Temel algoritma çok basit (bölünmüş kullanımı yok!), Ama atmak 0i0vve 0hkenar durumlarda izin vermek zorunda kaldı . Yine de, yaklaşımın güzel olduğunu düşündüm ve belki de kenar vakalarını işlemek için başka bir teknik bulabilirim: algoritma, bir dizenin ortasındaki en uzun koşuyu gayet iyi bulur, ancak tek karakterler veya boş dizeler için değil; Hala daha iyi sonuçlar için daha iyi yerlerde değişkenleri 'pad' olup olmadığını test ediyorum.

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.

Boşta çalışmaz c. Sonra tekrar, her bir dize her karakter arasında boş dizeleri sonsuz bir çalışma içeriyor varsayalım :)


1

R , 66 58 bayt

BLT ve MickyT sayesinde -8 bayt

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

anonim bir işlev döndürür. TIO'nun 1 baytlık bir farkı var çünküel burada açıklanamayan nedenlerle çalışmaz.

Çevrimiçi deneyin!


Bir bayt ile kaydedinr=rle(el(strsplit(s,'')))
BLT

1
Gördüysen önceki yorumumu görmezden gel. Senin için daha iyi bir tane varfunction(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
MickyT

@BLT elTIO (neden hiçbir fikrim) üzerinde çalışmıyor ve ben sadece kopyaladı ve orada çalışma kodundan yapıştırdı, bu yüzden @MickyT çok zekice geri koymak hatırlamak zorunda kalacağım! Teşekkürler!
Giuseppe

1

Java 8, 67 65 bayt

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

-2 bayt sayesinde @ OlivierGrégoire

Girdiyi a solarak alır char[]vec a kadarchar

Açıklama:

Burada deneyin.

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;daha kısadır {t=x==c?t+1:0;m=m>t?m:t;}.
Olivier Grégoire

Wayyyyyy daha uzun olmasına rağmen, ilk düşüncemi beğeniyorum s->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0);;)
Olivier Grégoire

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.