Najdłuższy ciąg znaku w ciągu


19

Twoje zadanie: napisać funkcję, która pobiera ciąg s, znak c, i stwierdza, długość najdłuższego biegu cw s. Długość biegu będzie l.

Zasady :

  • Jeśli sma długość 0 lub cjest pusty, lpowinien wynosić 0.
  • Jeśli nie ma żadnych wystąpień cin s, lpowinno wynosić 0.
  • Obowiązują standardowe luki i standardowe zasady we / wy .
  • Bez względu na to, gdzie w sbieg od cs znajduje, lpowinny być takie same.
  • Dowolne drukowalne znaki ASCII mogą pojawiać się w si c.

Przypadki testowe :

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

Zwycięzca :

Podobnie jak w przypadku w wygrywa najkrótsza odpowiedź w każdym języku.



Czy możesz dołączyć skrajne przypadki pustych si cnieujętych sw niepustych przypadkach testowych?
Martin Ender

Jaki zakres znaków może pojawić się w s/ c?
Martin Ender

6
cmoże być pusty? W wielu językach znak jest tylko liczbą całkowitą ze specjalną semantyką i nie można tak naprawdę mieć pustej liczby całkowitej.
Martin Ender

14
To nie ma dla mnie sensu. Twoje przypadki testowe sugerują, że musimy to wspierać. Jeśli nie musimy go obsługiwać, określenie wymaganego wyniku nie ma sensu, ponieważ zawsze mogę po prostu powiedzieć, że nie jest obsługiwane, jeśli moje rozwiązanie zrobiłoby coś innego w tym przypadku.
Martin Ender

Odpowiedzi:


12

05AB1E , 5 bajtów

Kod:

SQγOM

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Wyjaśnienie:

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
Fajne rozwiązanie! Wiedziałem, że jest na to sposób, po prostu nie mogłem o tym myśleć.
Riley

γ¢Mnie działa tak, jak myślałem, że to będzie 3-bajtowy.
Magic Octopus Urn

8

Mathematica, 35 bajtów

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

Czysta funkcja przyjmuje listę znaków i inny znak jako dane wejściowe i zwraca nieujemną liczbę całkowitą. Ulepszono mój pierwszy wysiłek, wykorzystując obserwację Adnana (idź na górę!), Że przed podzieleniem tablicy należy sprawdzić, czy ma się równać znak specjalny.

Thread[#==#2]sprawdza, czy każdy znak wejściowy w pierwszym argumencie jest równy znakowi podanemu jako drugi argument. Boolekonwertuje powstałe Trues i Falses na 1s i 0s. Splitdzieli listę na serie kolejnych elementów; Tr/@podsumowuje każdą podlistę i Maxznajduje zwycięzcę. (Z powodu tego, jak Maxdziała, jeśli pierwszym argumentem jest pusta lista, wówczas funkcja ta się zwraca -∞. Wiesz, nie rób tego.)

pierwsze przesłanie (51 bajtów)

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

Split@#dzieli dane wejściowe na serie kolejnych znaków, na przykład {{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}w czwartym przypadku testowym. /.a:{c_String..}:>zastępuje każde podwyrażenie, aktóre jest listą powtarzanego znaku c, Length@apomnożone przez Boole[c==#2], czyli 1jeśli jest crówne znakowi wejściowemu, a w 0przeciwnym razie. Następnie Maxwyodrębnia odpowiedź.


7

Japt , 20 18 15 bajtów

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

Wypróbuj online!

Zaoszczędzono 5 bajtów dzięki obarakon i produktom ETH


1
Przez jakiś czas bawiłem się własnym rozwiązaniem i skończyłem z takim, który był prawie twój, ale krótszy. Jeśli użyjesz fV+Vî+)... Dam ci resztę :-)
ETHproductions

@ETHproductions "If s is of length 0 or c is empty, l should be 0", być może biorę to zbyt dosłownie
Tom

Och, nie zdawałem sobie sprawy, że zawodzi, gdy snie zawiera żadnych przykładów c.
ETHproductions

7

Python , 38 bajtów

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

Wypróbuj online!

Dennis zapisał 3 bajty, aktualizując cciąg zduplikowanych znaków zamiast rekurencyjnie aktualizując liczbę do pomnożenia c.


1
f=lambda s,c:c in s and-~f(s,c+c[0])zapisuje 6 bajtów (3, jeśli fałsz nie jest dozwolony).
Dennis


4

Haskell, 43 39 bajtów

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

Wypróbuj online!

Przeprowadź ciąg znaków i zamień bieżący znak na licznik, który jest zwiększany, ilekroć jest on równy, club zerowany, 0jeśli nie. Weź maksimum z listy.

Dzięki @xnor za 4 bajty.


Można to zrobić sum[n+1|c==k].
xnor

@xnor: Fajnie! Eksperymentowałem *fromEnum(c==k)zarówno z bezzałogową, jak i lambda, ale zawsze było o 2 lub 3 bajty dłużej.
nimi

4

C # 116 115 bajtów

Mój pierwszy golf golfowy

Edytowane, ponieważ wstępne przesłanie było fragmentem kodu i brakowało wymaganej przestrzeni nazw dla wyrażenia regularnego

Edytuj # 2 pełne przepisywanie, aby obsługiwać znaki o specjalnych znaczeniach regularnych

using System.Linq; s => c => System.Text.RegularExpressions.Regex.Replace (s, "[^" + c + "]", ++ c + ""). Podział (c) .Max (x => x. długość);

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
Nie znam C #, ale wygląda na to, że Twój kod oczekuje zmiennych ci sjest predefiniowany. Nazywamy to „fragmentem kodu” i jest to niedozwolone. Prawdopodobnie możesz zrestrukturyzować swój kod jako funkcję anonimową lub ustawić zmienne wejściowe. Oba są dozwolone.
Wheat Wizard

Czy to działa? (Patrz wyżej edycja)
Miotła

1
Jeszcze raz nie znam C #, ale wygląda na to, że tak. Możesz sprawdzić nasze porady dotyczące gry w golfa w C # tutaj, aby uzyskać bardziej doświadczone porady w C #.
Wheat Wizard

Dzięki za linki! Na pewno przejrzę wskazówki C #
Broom

3
Witam tylko kilka ogólnych komentarzy do gry w golfa w C #, możesz zdefiniować swoją funkcję jako (s,c)=>. Musisz użyć System.Text.RegularExpressions.Regexlub dodać instrukcję using tuż przed funkcją.
LiefdeWen

4

JavaScript (ES6), 54 53 51 bajtów

-2 bajty dzięki @Neil
-1 bajtów dzięki @apsillers

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

Trwa wejście w składni currying: f("foobar")("o").

Test Snippet

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>

Inna opcja przy użyciu evali for(54 bajtów)

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

Stara odpowiedź przy użyciu Regex (85 bajtów)

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

1
Myślę, że x==c?i++:i=0może tak być, i=x==c&&i+1ponieważ falsewynik x==cporównania będzie traktowany jako 0porównanie liczbowe i przyrosty (i nigdy nie będzie wartością zwracaną, ponieważ dowolna liczba, w tym 0, in j, zawsze będzie miała falsei
wyższy

@apsillers Dzięki, zaktualizowano, ale co masz na myśli mówiąc, że nigdy nie jest wartością zwracaną?
Justin Mariner

Przepraszam za zamieszanie; Właśnie wyjaśniłem, że zmiana nigdy nie sprawi, że Twój program powróci false(ponieważ wyzwanie zawsze wymaga zwrócenia liczby)
apsillers

1
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&jwydaje się zaoszczędzić kilka bajtów.
Neil

1
Przepraszam, wysłałem zły kod, chciałem opublikować f=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j, który jest krótszy bajt.
Neil

4

JavaScript (Firefox 30-57), 75 72 bajtów

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

Fragment kodu zgodny z 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 zwraca wiązkę pustych ciągów znaków i pojedynczych znaków, a także przebiegów, ale nie wpływa to na wynik.


3

Mikro , 112 bajtów

{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 bajtów

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

Sprawdź to

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

Sprawdź to

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

Sprawdź to

Rozszerzony:

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

Rozwiązanie rekurencyjne, które traktuje dane wejściowe ciągu jako tablicę (uwaga: dane wejściowe są nadal ciągiem znaków) i zużywa znaki od lewej do prawej C:

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

Śledzi bieżący bieg ti najlepszy na świecie w T.

Wyjaśnienie:

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`

Ustawianie tsię falsena niebędących meczów działa, ponieważ gdy tjest zwiększany, falsetraktowany jest jako 0(czyli false + 1jest 1), i falsenigdy nie będzie porównać Tarka niż jakakolwiek wartość w global-max T.


1
Dobre rozwiązanie, nie znałem [C,...s]składni. Powinno mi pomóc w slice()usuwaniu bajtów z moich własnych postów.
Rick Hitchcock,

2

Galaretka , 5 bajtów

=ŒgṀS

Jest to dynamiczne łącze / funkcja, która pobiera ciąg znaków i znak. Zauważ, że nie może działać jako pełny program, ponieważ dane wejściowe z argumentów wiersza poleceń używają składni Pythona, a Python - w przeciwieństwie do Jelly - nie rozróżnia ciągów singletonów od znaków.

Wypróbuj online!

Jak to działa

=Œ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 bajtów

Wymaga wymiany ze w wersji 16.0 lub konieczności ⎕ML←3(domyślnie w wielu systemach).

⌈/0,≢¨⊂⍨⎕=⎕

Wypróbuj online!

⎕=⎕ Boolean dla równości między dwoma wejściami

⊂⍨ auto-partycja (rozpocznij partycje, w których element niezerowy jest większy niż jego poprzednik)

≢¨ suma każdego

0, wstaw zero (dla przypadków z pustym wejściem)

⌈/ maksimum z nich


Stare rozwiązanie

Monituje najpierw dla s , a następnie dla c

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

Wypróbuj online!

 monit o s

 za to

()⎕S 1PCRE S earch dla długości wystąpień

'+' symbol plus (oznaczający jeden lub więcej)

 dołączone do każdego z elementów

 monit o c

0, wstaw zero (dla przypadków z pustym wejściem)

⌈/ maksimum z nich

c należy podać jako 1-elementowy wektor zamkniętego łańcucha, jeśli wymaga on ucieczki.


2

PHP, 70 67 bajtów

trzy wersje:

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;

pobiera dane wejściowe z argumentów wiersza poleceń; uruchom je -rlub przetestuj online .


2

PHP , 70 bajtów

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

Wypróbuj online!

PHP , 75 bajtów

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

Wypróbuj online!

PHP , 83 bajty

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

Wypróbuj online!

+8 bajtów do uniknięcia @

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

Wersja 67 bajtów nie powiedzie się dla żadnego specjalnego znaku regularnego (i #oczywiście).
Titus

... i ~może się nie powieść chr(207).
Titus

@Titus Gotowe i dane wejściowe mogą być tylko znakami Ascii
Jörg Hülsermann

dobre oko ++$n! Miałeś na myśli ascii do wydruku. ;)
Titus

1
echo$r?max($r):0;oszczędza jeden bajt
Tytus

2

JavaScript (ES6), 47 40 38 bajtów

(Zapisano 7 bajtów dzięki @Neil i 2 bajty dzięki @HermanLauenstein.)

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

Wyjaśnienie:

Rekurencyjnie szuka dłuższego przebiegu, dopóki nie zostanie znaleziony.

Skrawek:


1
Tak prosty! Znakomity!
apsillers

Nie można zrobić f=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])?
Neil

Lub jeszcze lepiej, curry to s=>g=c=>c&&s.includes(c)&&1+g(c+c[0]).
Neil

To prawie działa, ale zwraca „fałsz” i ciąg zerowy dla dwóch ostatnich przypadków. Zostało to naprawione przez dołączanie ||0, które wciąż jest krótsze niż moje rozwiązanie.
Rick Hitchcock

Nie f=jest częścią wersji curry, ponieważ rekursywna jest tylko funkcja wewnętrzna.
Neil

2

Galaretka, 10 9 bajtów

f⁴L
ŒgÇ€Ṁ

Wyjaśnienie:

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.

Wypróbuj online!


Możesz zapisać kilka bajtów za pomocą Œgf€L€Ṁ.
Dennis


1

Haskell , 66 bajtów

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

Wypróbuj online!

Nieco łatwiejsza do odczytania wersja - nie ma sensu:

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

Grupuje ciąg według liter, a następnie filtruje według tych grup, które zawierają odpowiedni znak, a następnie wyszukuje długości, dołącza 0 do listy długości w przypadku, gdy się nie pojawi, i na końcu znajduje maksymalną wartość.


1

Mathematica, 109 bajtów

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


Wejście

[„xxx xxxx xx”, „x”]



1

CJam , 20 19 18 16 bajtów

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

Wypróbuj online!

Wyjaśnienie

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 bajtów

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

snależy wprowadzić do A1.
cnależy wprowadzić do A2.
Formuła musi być formułą tablicową (Ctrl + Shift+ Enter), która dodaje nawiasy klamrowe { }.

Technicznie może to poradzić sobie tylko wtedy, gdy najdłuższy bieg jest mniejszy niż 1 048 576 (co oznacza 2 ^ 20), ponieważ w ten sposób wiersze bieżący Excel pozwoli ci mieć w arkuszu. Ponieważ ładuje ponad milion wartości do pamięci przy każdym ponownym obliczeniu, nie jest to szybka formuła.


1

MATL , 15 bajtów

0i0v=dfd1L)0hX>

Wypróbuj online!

Podstawowy algorytm jest bardzo prosty (bez użycia podziału!), Ale musiałem wrzucić 0i0vi0h pozwolić na przypadki brzegowe. Mimo to uważałem, że to podejście jest dobre i być może uda mi się znaleźć inną technikę obsługi przypadków skrajnych: algorytm znajduje najdłuższy ciąg w środku łańcucha w porządku, ale nie dla pojedynczych znaków lub pustych ciągów; Wciąż testuję, czy mogę „wstawić” zmienne w lepszych miejscach, aby uzyskać lepsze wyniki.

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.

Nie działa na pustych c. Z drugiej strony, przypuszczam, że każdy ciąg zawiera nieskończony ciąg pustych ciągów między każdym znakiem :)


1

R , 66 58 bajtów

-8 bajtów dzięki BLT i MickyT

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

zwraca anonimową funkcję. TIO ma różnicę 1 bajta, ponieważ elnie działa tam z niewytłumaczalnych powodów.

Wypróbuj online!


Zapisz bajt za pomocąr=rle(el(strsplit(s,'')))
BLT

1
Zignoruj ​​mój poprzedni komentarz, jeśli go widziałeś. Mam dla ciebie function(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
lepszy

@BLT elnie działa na TIO (nie mam pojęcia dlaczego), a ja po prostu skopiowałem i wkleiłem go z działającego kodu, więc będę musiał pamiętać, aby umieścić to z powrotem w @MickyT bardzo sprytnie! Dzięki!
Giuseppe,

1

Java 8, 67 65 bajtów

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

-2 bajty dzięki @ OlivierGrégoire

Zajmuje wejście sjak char[]i cjako Achar

Wyjaśnienie:

Wypróbuj tutaj.

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; jest krótszy niż {t=x==c?t+1:0;m=m>t?m:t;} .
Olivier Grégoire,

Mimo, że jest już dłuższa, podobała mi się moja pierwsza myśl:; s->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0))
Olivier Grégoire

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.