Esecuzione più lunga di un personaggio in una stringa


19

La tua sfida: scrivi una funzione che accetta una stringa s, un carattere ce trova la lunghezza della corsa più lunga di cin s. La lunghezza della corsa sarà l.

Regole :

  • Se sè di lunghezza 0 o cè vuoto, ldovrebbe essere 0.
  • Se non ci sono istanze di cin s, ldovrebbe essere 0.
  • Si applicano scappatoie standard e regole I / O standard .
  • Indipendentemente da dove si trovi nella ssequenza di cs, ldovrebbe essere lo stesso.
  • Qualsiasi carattere ASCII stampabile può apparire in se c.

Casi di prova :

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

Vincitore :

Come nel , vince la risposta più breve in ogni lingua.



Potresti includere i casi limite di vuoto se uno cche non è contenuto in un non vuoto snei casi di test?
Martin Ender,

Quale intervallo di caratteri può apparire in s/ c?
Martin Ender,

6
cpuò essere vuoto? In molte lingue, un personaggio è solo un numero intero con una semantica speciale e non puoi nemmeno avere un numero intero vuoto.
Martin Ender,

14
Questo non ha davvero senso per me. I tuoi casi di test suggeriscono che dobbiamo supportarlo. Se non è necessario supportarlo, specificare il risultato richiesto non ha senso, perché posso sempre solo dire che non è supportato se la mia soluzione farebbe qualcos'altro in quel caso.
Martin Ender,

Risposte:


12

05AB1E , 5 byte

Codice:

SQγOM

Utilizza la codifica 05AB1E . Provalo online!

Spiegazione:

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
Bella soluzione! Sapevo che c'era un modo per farlo in questo modo, non riuscivo proprio a pensarci.
Riley,

γ¢Mnon funziona come pensavo, pensavo che sarebbe un 3 byte.
Magic Octopus Urn

8

Mathematica, 35 byte

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

Funzione pura che accetta un elenco di caratteri e un altro carattere come input e restituisce un numero intero non negativo. Migliorato al mio primo sforzo usando l'osservazione di Adnan (vai avanti!) Che si dovrebbe testare per eguagliare il carattere speciale prima di dividere l'array.

Thread[#==#2]controlla se ciascun carattere di input nel primo argomento è uguale al carattere indicato come secondo argomento. Booleconverte le Trues e Falses risultanti in 1s e 0s. Splitdivide l'elenco in serie di elementi consecutivi; Tr/@somma tutti gli elenchi secondari e Maxtrova il vincitore. (A causa di come Maxfunziona, se il primo argomento è l'elenco vuoto, questa funzione ritorna -∞. Quindi, sai, non farlo.)

primo invio (51 byte)

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

Split@#divide l'input in sequenze di caratteri consecutivi, come nel {{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}caso del quarto test. /.a:{c_String..}:>sostituisce ogni sottoespressione ache è una lista di un carattere ripetuto cda Length@amoltiplicato per Boole[c==#2], che è 1se cè uguale al carattere immesso e 0altrimenti. Quindi Maxestrae la risposta.


7

Japt , 20 18 15 byte

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

Provalo online!

Risparmiato 5 byte grazie a obarakon e ETHproductions


1
Ho giocato con la mia soluzione per un po 'e ho finito con uno che era quasi tuo, ma più corto. Se usi fV+Vî+)... Ti farò capire il resto :-)
ETHproductions

@ETHproductions "If s is of length 0 or c is empty, l should be 0", potrei prenderlo troppo alla lettera, però
Tom,

Oh, non avevo capito che fallisce ogni volta sche non contiene alcuna istanza di c.
ETHproductions

7

Python , 38 byte

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

Provalo online!

Dennis ha salvato 3 byte eseguendo l'aggiornamento ca una stringa di caratteri duplicati anziché aggiornare ricorsivamente un numero per moltiplicare cper.


1
f=lambda s,c:c in s and-~f(s,c+c[0])salva 6 byte (3 se False non è consentito).
Dennis,


4

Haskell, 43 39 byte

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

Provalo online!

Esegui la stringa e sostituisci il carattere corrente con un contatore che viene aumentato ogni volta che è uguale co reimpostato in 0caso contrario. Prendi il massimo dell'elenco.

Grazie a @xnor per 4 byte.


Si può fare sum[n+1|c==k].
xnor

@xnor: Nice! Ho sperimentato *fromEnum(c==k)sia pointfree che lambda, ma era sempre più lungo di 2 o 3 byte.
nimi,

4

C # 116 115 byte

Il mio primo codice golf

Modificato perché l'invio iniziale era un frammento e mancava lo spazio dei nomi richiesto per regex

Modifica # 2 completa la riscrittura per supportare i personaggi con significati regex speciali

utilizzando 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
Non conosco C # ma sembra che il tuo codice si aspetti variabili ce ssia predefinito. Lo chiamiamo "frammento di codice" e non è consentito. Probabilmente potresti ristrutturare il tuo codice come una funzione anonima o impostare quelle variabili da inserire. Entrambi sono ammessi.
Wheat Wizard

Funziona? (Vedi sopra modifica)
Scopa

1
Ancora una volta non conosco C #, ma sembra che lo sia. Potresti dare un'occhiata ai nostri consigli per giocare a golf in C # qui per consigli più esperti in C #.
Wheat Wizard

Grazie per i collegamenti! Sicuramente esaminerò i suggerimenti di C #
Broom,

3
Ciao solo alcuni commenti generali per giocare a golf in C #, puoi definire la tua funzione come (s,c)=>. Devi usare System.Text.RegularExpressions.Regexo aggiungere un'istruzione using proprio prima della tua funzione.
LiefdeWen

4

JavaScript (ES6), 54 53 51 byte

-2 byte grazie a @Neil
-1 byte grazie a @apsillers

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

Riceve l'input nella sintassi accattivarsi: f("foobar")("o").

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

Un'altra opzione che utilizza evale for(54 byte)

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

Vecchia risposta utilizzando Regex (85 byte)

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

1
Penso che x==c?i++:i=0possa essere solo i=x==c&&i+1dal momento che un falserisultato sul x==cconfronto verrà trattato come un 0confronto e incremento numerico (e non sarà mai il valore di ritorno, poiché qualsiasi numero, incluso 0, in javrà sempre la priorità sullo zero-like falsein i)
apsillers

@apsillers Grazie, aggiornato, ma cosa intendi per non essere mai il valore di ritorno?
Justin Mariner l'

Dispiace per la confusione; Stavo solo spiegando che la modifica non avrebbe mai restituito il tuo programma false(poiché la sfida richiede sempre che restituisca un numero)
apsillers

1
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&jsembra salvare un paio di byte.
Neil,

1
Spiacente, ho pubblicato il codice sbagliato, intendevo postare f=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j, che è un byte più breve.
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))

Snippet compatibile 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 restituisce un sacco di stringhe vuote e singoli caratteri, nonché le esecuzioni, ma ciò non influisce sul risultato.


3

Micro , 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}

Provalo

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

Provalo

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

Provalo

Allargato:

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

Soluzione ricorsiva che tratta l'input della stringa come un array (nota: l'input iniziale è ancora una stringa) e consuma da sinistra a destra nel carattere C:

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

Tiene traccia del run in attuale te del best in globale T.

Spiegazione:

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`

L'impostazione tsu falsesu non corrispondenze funziona perché ogni volta che tviene incrementato, falseviene trattato come 0(ovvero, lo false + 1è 1) e falsenon confronterà mai la grattugia di qualsiasi valore in global-max T.


1
Bella soluzione, non avevo familiarità con la [C,...s]sintassi. Dovrebbe aiutarmi a slice()eliminare i byte dai miei post.
Rick Hitchcock,

2

Gelatina , 5 byte

=ŒgṀS

Questo è un collegamento / funzione diadico che accetta una stringa e un carattere. Si noti che non può funzionare come un programma completo, poiché l'input dagli argomenti della riga di comando utilizza la sintassi di Python e Python - a differenza di Jelly - non distingue le stringhe singleton dai caratteri.

Provalo online!

Come funziona

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

Richiede lo scambio con nella versione 16.0 o con ⎕ML←3(impostazione predefinita su molti sistemi).

⌈/0,≢¨⊂⍨⎕=⎕

Provalo online!

⎕=⎕ Booleano per l'uguaglianza tra due input

⊂⍨ auto-partizione (inizia partizioni in cui un elemento diverso da zero è maggiore del suo predecessore)

≢¨ conta ciascuno

0, anteporre uno zero (per i casi di input vuoto)

⌈/ max di quelli


Vecchia soluzione

Richiede prima per s , poi per c

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

Provalo online!

 richiesta di s

 per quello

(... )⎕S 1PCRE S earch per le lunghezze di occorrenze di

'+' un simbolo più (che significa uno o più)

 aggiunto a ciascuno degli elementi di

 il richiesto c

0, anteporre uno zero (per i casi di input vuoto)

⌈/ max di quelli

c deve essere indicato come vettore a 1 elemento di una stringa racchiusa se deve essere sottoposto a escape.


2

PHP, 70 67 byte

tre versioni:

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;

accetta input dagli argomenti della riga di comando; correre con -ro testarli online .


2

PHP , 70 byte

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

Provalo online!

PHP , 75 byte

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

Provalo online!

PHP , 83 byte

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

Provalo online!

+8 byte da evitare @

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

La versione da 67 byte fallirà per qualsiasi carattere speciale regex (e #ovviamente).
Tito,

... e ~potrebbe fallire per chr(207).
Tito

@Titus Fatto e Input possono essere solo personaggi Ascii
Jörg Hülsermann

buon occhio per ++$n! Volevi dire ascii stampabile. ;)
Tito,

1
echo$r?max($r):0;salva un byte
Titus il

2

JavaScript (ES6), 47 40 38 byte

(Salvato 7 byte grazie a @Neil e 2 byte grazie a @HermanLauenstein.)

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

Spiegazione:

Cerca in modo ricorsivo una corsa più lunga fino a quando non viene trovato nessuno.

Frammento:


1
Così semplice! Brillante!
apsillers,

Non puoi fare f=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])?
Neil,

O meglio, curry a s=>g=c=>c&&s.includes(c)&&1+g(c+c[0]).
Neil,

Funziona quasi, ma restituisce "false" e una stringa nulla per gli ultimi due casi. Ciò è stato risolto aggiungendo ||0, che è ancora più breve della mia soluzione.
Rick Hitchcock,

Non f=fa parte della versione curry, perché solo la funzione interna è ricorsiva.
Neil,

2

Gelatina, 10 9 byte

f⁴L
ŒgÇ€Ṁ

Spiegazione:

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.

Provalo online!


È possibile salvare un paio di byte con Œgf€L€Ṁ.
Dennis,


1

Haskell , 66 byte

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

Provalo online!

Una versione leggermente più facile da leggere - non inutile:

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

Raggruppa la stringa per lettera, quindi filtra per quei gruppi che contengono il carattere giusto, quindi trova le lunghezze, aggiunge 0 all'elenco delle lunghezze nel caso in cui non venga visualizzato e infine trova il valore massimo.


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


ingresso

["xxx xxxx xx", "x"]



1

CJam , 20 19 18 16 byte

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

Provalo online!

Spiegazione

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

sdovrebbe essere inserito in A1.
cdovrebbe essere inserito in A2.
La formula deve essere una formula di matrice ( Ctrl+ Shift+ Enter) che aggiunge parentesi graffe { }.

Tecnicamente, questo può gestire solo dove la corsa più lunga è inferiore a 1.048.576 (che è 2 ^ 20) perché è così che le righe che Excel corrente ti permetterà di avere in un foglio di lavoro. Dal momento che carica i milioni + di valori in memoria ogni volta che ricalcola, questa non è una formula veloce .


1

MATL , 15 byte

0i0v=dfd1L)0hX>

Provalo online!

L'algoritmo di base è molto semplice (non c'è bisogno di dividere!), Ma ho dovuto lanciare 0i0ve 0hconsentire i casi limite. Tuttavia, ho pensato che l'approccio fosse carino, e forse posso ancora trovare un'altra tecnica per gestire i casi limite: l'algoritmo trova la corsa più lunga nel mezzo di una stringa, ma non per singoli caratteri o stringhe vuote; Sto ancora testando se posso 'pad' le variabili in posti migliori per risultati migliori.

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.

Non funziona su vuoto c. Quindi, suppongo che ogni stringa contenga una sequenza infinita di stringhe vuote tra ogni carattere :)


1

R , 66 58 byte

-8 byte grazie a BLT e MickyT

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

restituisce una funzione anonima. TIO ha una differenza di 1 byte perché elnon funziona lì per motivi inspiegabili.

Provalo online!


Salvare un byte conr=rle(el(strsplit(s,'')))
BLT l'

1
Ignora il mio commento precedente se l'hai visto. function(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
Ne

@BLT elnon funziona su TIO (non ho idea del perché) e l'ho appena copiato e incollato dal codice di lavoro lì, quindi dovrò ricordare di rimetterlo in @MickyT molto intelligente! Grazie!
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 grazie a @ OlivierGrégoire

Accetta input scome a char[]e ccome achar

Spiegazione:

Provalo qui.

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;è più corto di {t=x==c?t+1:0;m=m>t?m:t;}.
Olivier Grégoire

Anche se è più lungo di Wayyyyyy, mi piace il mio primo pensiero:; s->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0))
Olivier Grégoire,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.