Execução mais longa de um caractere em uma string

19

Seu desafio: Escrever uma função que leva uma corda s, um personagem c, e encontra o comprimento da corrida mais longa de cno s. A duração da corrida será l.

Regras :

  • Se o scomprimento for 0 ou cvazio, ldeve ser 0.
  • Se não houver instâncias de cin s, ldeve ser 0.
  • As brechas padrão e as Regras de E / S padrão se aplicam.
  • Não importa onde sa sequência de cs esteja localizada, ldeve ser a mesma.
  • Quaisquer caracteres ASCII imprimíveis podem aparecer em se c.

Casos de teste :

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

Vencedor :

Como no a resposta mais curta em cada idioma vence.

MD XF
fonte
Você poderia incluir os casos de borda de vazio se um cque não está contido em um não vazio sem seus casos de teste?
Martin Ender
Que intervalo de caracteres pode aparecer em s/ c?
Martin Ender
6
cpode estar vazio? Em muitos idiomas, um caractere é apenas um número inteiro com semântica especial, e você também não pode ter um número inteiro vazio.
Martin Ender
14
Isso realmente não faz sentido para mim. Seus casos de teste sugerem que precisamos apoiá-lo. Se não precisarmos oferecer suporte, especificar a saída necessária não faz sentido, porque sempre posso dizer que não há suporte se minha solução fizer outra coisa nesse caso.
Martin Ender

Respostas:

12

05AB1E , 5 bytes

Código:

SQγOM

Usa a codificação 05AB1E . Experimente online!

Explicação:

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
Adnan
fonte
2
Ótima solução! Eu sabia que havia uma maneira de fazer isso assim, eu simplesmente não conseguia pensar nisso.
Riley
γ¢Mnão está funcionando como eu pensei que seria, pensei que seria de 3 bytes.
Magic Octopus Urn
8

Mathematica, 35 bytes

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

Função pura pegando uma lista de caracteres e outro caractere como entrada e retornando um número inteiro não negativo. Aprimorado no meu primeiro esforço, usando a observação de Adnan (vá para votação!), Que se deve testar a igualdade do caractere especial antes de dividir a matriz.

Thread[#==#2]verifica se cada caractere de entrada no primeiro argumento é igual ao caractere fornecido como o segundo argumento. Booleconverte os Trues e s resultantes Falseem 1s e 0s. Splitdivide a lista em execuções de elementos consecutivos; Tr/@soma cada sub-lista e Maxencontra o vencedor. (Por causa de como Maxfunciona, se o primeiro argumento for a lista vazia, essa função retornará -∞. Então, você sabe, não faça isso.)

primeira submissão (51 bytes)

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

Split@#divide a entrada em execuções de caracteres consecutivos, como {{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}no quarto caso de teste. /.a:{c_String..}:>substitui cada subexpressão aque é uma lista de um caractere repetido cpor Length@amultiplicado por Boole[c==#2], que é 1se é cigual ao caractere de entrada e 0não. Em seguida, Maxextrai a resposta.

Greg Martin
fonte
7

Japonês , 20 18 15 bytes

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

Experimente online!

Economizou 5 bytes graças ao obarakon e ETHproductions

Tom
fonte
11
Eu brinquei com minha própria solução por um tempo e acabei com uma que era quase sua, mas mais curta. Se você usar fV+Vî+)... Eu vou deixar você descobrir o resto para fora :-)
ETHproductions
@ETHproductions "If s is of length 0 or c is empty, l should be 0", eu poderia estar levando isso também literalmente embora
Tom
Ah, eu não tinha percebido que falha sempre sque não contém nenhuma instância de c.
ETHproductions
7

Python , 38 bytes

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

Experimente online!

Dennis salvou 3 bytes atualizando cpara uma sequência de caracteres duplicados em vez de atualizar recursivamente um número para multiplicar c.

xnor
fonte
11
f=lambda s,c:c in s and-~f(s,c+c[0])salva 6 bytes (3 se False não for permitido).
Dennis
5

05AB1E , 11 6 bytes

-5 bytes graças à carusocomputação

γvy²¢M

Experimente online!

γ      # split into chunks of consecutive equal elements
 vy    # For each chunk...
   ²¢  #  Count the number of input characters in this chunk
     M #  Push the largest count so far
Riley
fonte
γvy²¢Mpara 6 bytes, mesma ideia.
Urna de polvo mágico
4

Haskell, 43 39 bytes

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

Experimente online!

Execute a sequência e substitua o caractere atual por um contador que seja aumentado sempre que for igual cou redefinido para o 0caso contrário. Leve o máximo da lista.

Obrigado a @xnor por 4 bytes.

nimi
fonte
Você pode fazer sum[n+1|c==k].
Xnor
@xnor: Legal! Eu experimentei *fromEnum(c==k), pointfree e lambda, mas sempre foram 2 ou 3 bytes mais.
nimi
4

C # 116 115 bytes

Meu primeiro código de golfe

Editado porque o envio inicial era um snippet e faltava o namespace necessário para a regex

Edite # 2 reescrita completa para suportar caracteres com significados especiais de regex

using System.Linq; s => c => System.Text.RegularExpressions.Regex.Replace (s, "[^" + c + "]", ++ c + ""). Divisão (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)};
Vassoura
fonte
3
Não sei c #, mas parece que seu código espera variáveis ce sseja predefinido. Chamamos isso de "snippet de código" e não é permitido. Você provavelmente poderia reestruturar seu código como uma função anônima ou definir essas variáveis ​​para entrada. Ambos são permitidos.
Wheat Wizard
Isso funciona? (Ver edição acima)
Broom
11
Mais uma vez, não sei c #, mas parece que sim. Você pode conferir nossas dicas para jogar golfe em C # aqui para obter conselhos mais experientes em C #.
Wheat Wizard
Obrigado pelos links! Definitivamente vou ler as dicas de C # #
Broom
3
Olá, apenas alguns comentários gerais sobre golfe em C #, você pode definir sua função como (s,c)=>. Você precisa usar System.Text.RegularExpressions.Regexou adicionar uma instrução using antes de sua função.
precisa saber é o seguinte
4

JavaScript (ES6), 54 53 51 bytes

-2 bytes graças a @ Neil
-1 byte graças a @apsillers

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

Toma de entrada na sintaxe currying: f("foobar")("o").

Snippet de teste

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>

Outra opção usando evale for(54 bytes)

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

Resposta antiga usando Regex (85 bytes)

s=>c=>c?Math.max(...s.match(eval(`/${/\w/.test(c)?c:"\\"+c}*/g`)).map(x=>x.length)):0
Justin Mariner
fonte
11
Eu acho que x==c?i++:i=0pode ser apenas i=x==c&&i+1porque um falseresultado na x==ccomparação será tratado como 0comparações e incrementos numéricos (e nunca será o valor de retorno, já que qualquer número, incluindo 0, in jsempre terá prioridade sobre o zero-like falsein i)
apsillers
@apsillers Obrigado, atualizado, mas o que você quer dizer com nunca ser o valor de retorno?
Justin Mariner
Desculpe pela confusão; Eu estava apenas explicando que a mudança nunca iria fazer o seu retorno programa false(uma vez que o desafio sempre exige que ele retorne um número)
apsillers
11
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&jparece economizar alguns bytes.
Neil
11
Desculpe, eu postei o código errado, eu pretendia postar f=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j, que é um byte mais curto.
Neil
4

JavaScript (Firefox 30-57), 75 72 bytes

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

Fragmento compatível com 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 retorna um monte de cadeias vazias e caracteres únicos, além das execuções, mas isso não afeta o resultado.

Neil
fonte
3

Micro , 112 bytes

{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:\
raddish0
fonte
2

Perl 6 ,  45 43  42 bytes

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

Teste-o

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

Teste-o

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

Teste-o

Expandido:

-> $_, $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
}
Brad Gilbert b2gills
fonte
2

JavaScript, ES6, 52

Solução recursiva que trata a entrada de sequência como uma matriz (nota: a entrada inicial ainda é uma sequência) e consome o caractere da esquerda para a direita C:

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

Rastreia a execução atual te a melhor global em T.

Explicação:

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`

Definir tcomo falsenão correspondências funciona porque sempre que té incrementado, falseé tratado como 0(ou seja, false + 1é 1) e falsenunca será comparado a um valor maior que qualquer valor no global-max T.

apsillers
fonte
11
Solução agradável, eu não estava familiarizado com a [C,...s]sintaxe. Deve me ajudar slice()com os bytes de minhas próprias postagens.
Rick Hitchcock
2

Gelatina , 5 bytes

=ŒgṀS

Este é um link / função diádica que recebe uma string e um caractere. Observe que ele não pode funcionar como um programa completo, pois a entrada dos argumentos da linha de comando usa a sintaxe do Python, e o Python - ao contrário do Jelly - não distingue as strings singleton dos caracteres.

Experimente online!

Como funciona

=Œ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.
Dennis
fonte
2

APL (Dyalog) , 18 11 bytes

Requer trocando com a versão 16.0 ou ter ⎕ML←3(default em muitos sistemas).

⌈/0,≢¨⊂⍨⎕=⎕

Experimente online!

⎕=⎕ Booleano para igualdade entre duas entradas

⊂⍨ partição automática (iniciar partições em que um elemento diferente de zero é maior que seu predecessor)

≢¨ registro cada

0, preceder um zero (para os casos de entrada vazia)

⌈/ max daqueles


Solução antiga

Solicita primeiro s , depois c

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

Experimente online!

 prompt para s

 por isso

(... )⎕S 1PCRE S Earch para os comprimentos de ocorrências de

'+' um símbolo de adição (significando um ou mais)

 anexado a cada um dos elementos de

 o c solicitado

0, preceder um zero (para os casos de entrada vazia)

⌈/ max daqueles

c deve ser fornecido como um vetor de 1 elemento de uma cadeia fechada, se precisar escapar.

Adão
fonte
2

PHP, 70 67 bytes

três versões:

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;

recebe entrada de argumentos de linha de comando; executar -rou testá-los online .

Titus
fonte
2

PHP , 70 bytes

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

Experimente online!

PHP , 75 bytes

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

Experimente online!

PHP , 83 bytes

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

Experimente online!

+8 bytes a evitar @

<?=($a=$argv[2])&&preg_match_all("<".preg_quote($a)."+>",$argv[1],$t)?strlen(max($t[0])):0;
Jörg Hülsermann
fonte
A versão de 67 bytes falhará para qualquer caractere especial de regex (e, é #claro).
Titus
... e ~pode falhar chr(207).
Titus
@Titus Feito e entrada só pode ser caracteres ASCII
Jörg Hülsermann
bom olho para ++$n! Você quis dizer ascii imprimível. ;)
Tito
11
echo$r?max($r):0;salva um byte
Titus
2

JavaScript (ES6), 47 40 38 bytes

(Economizou 7 bytes graças a @Neil e 2 bytes graças a @HermanLauenstein.)

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

Explicação:

Procura recursivamente por uma execução mais longa até que nenhuma seja encontrada.

Snippet:

Rick Hitchcock
fonte
11
Tão simples! Brilhante!
Apsillers
Você não pode fazer f=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])?
Neil
Ou melhor ainda, faça o curry s=>g=c=>c&&s.includes(c)&&1+g(c+c[0]).
31517 Neil
Isso quase funciona, mas retorna "false" e uma string nula para os dois últimos casos. Isso é corrigido pelo acréscimo ||0, ainda mais curto que a minha solução.
Rick Hitchcock
A f=parte não faz parte da versão com curry, porque apenas a função interna é recursiva.
Neil
2

Geléia, 10 9 bytes

f⁴L
ŒgÇ€Ṁ

Explicação:

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.

Experimente online!

DaggerOfMesogrecia
fonte
Você pode salvar alguns bytes com Œgf€L€Ṁ.
Dennis
1

Haskell , 66 bytes

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

Experimente online!

Uma versão um pouco mais fácil de ler - não sem sentido:

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

Agrupa a sequência por letra, depois filtra os grupos que contêm o caractere correto, localiza os comprimentos, anexa 0 à lista de comprimentos, caso não apareça, e finalmente encontra o valor máximo.

vroomfondel
fonte
1

Mathematica, 109 bytes

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


entrada

["xxx xxxx xx", "x"]

J42161217
fonte
1

CJam , 20 19 18 16 bytes

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

Experimente online!

Explicação

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.
Gato de negócios
fonte
1

Excel, 56 bytes

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

sdeve ser inserido em A1.
cdeve ser inserido em A2.
A fórmula deve ser uma fórmula de matriz ( Ctrl+ Shift+ Enter) que adicione colchetes { }.

Tecnicamente, isso só pode manipular onde a execução mais longa é menor que 1.048.576 (que é 2 ^ 20) porque é assim que as linhas do Excel atual permitem que você tenha uma planilha. Como ele carrega os milhões de valores na memória sempre que recalcula, essa não é uma fórmula rápida .

Engenheiro Toast
fonte
1

MATL , 15 bytes

0i0v=dfd1L)0hX>

Experimente online!

O algoritmo básico é muito simples (sem uso de divisão!), Mas eu tive que incluir 0i0ve 0hpermitir os casos extremos. Ainda assim, achei que a abordagem era boa e talvez ainda encontre outra técnica para lidar com os casos extremos: o algoritmo encontra a execução mais longa no meio de uma string, mas não para caracteres únicos ou strings vazios; Ainda estou testando se posso 'preencher' as variáveis ​​em lugares melhores para obter melhores resultados.

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.

Não funciona em vazio c. Então, novamente, suponho que cada string contenha uma execução infinita de strings vazias entre cada caractere :)

Sanchises
fonte
1

R , 66 58 bytes

-8 bytes graças a BLT e MickyT

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

retorna uma função anônima. O TIO tem uma diferença de 1 byte porque elnão funciona lá por razões inexplicáveis.

Experimente online!

Giuseppe
fonte
Salvar um byte comr=rle(el(strsplit(s,'')))
BLT
11
Ignore meu comentário anterior, se você o viu. Tem um melhor para vocêfunction(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
MickyT
O @BLT elnão funciona no TIO (não faço ideia do porquê) e eu apenas o copiei e colei do código de trabalho lá, então terei que lembrar de colocar isso de volta no @MickyT muito inteligente! Obrigado!
Giuseppe
1

Java 8, 67 65 bytes

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

-2 bytes graças a @ OlivierGrégoire

Recebe a entrada scomo a char[]e ccomochar

Explicação:

Experimente aqui.

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
Kevin Cruijssen
fonte
11
m=m>(t=x==c?t+1:0)?m:t;é mais curto que {t=x==c?t+1:0;m=m>t?m:t;}.
Olivier Grégoire
Mesmo que seja wayyyyyy mais, eu gosto do meu primeiro pensamento: s->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0);)
Olivier Grégoire