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.



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

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.


7

Japonês , 20 18 15 bytes

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

Experimente online!

Economizou 5 bytes graças ao obarakon e ETHproductions


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.


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


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.


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

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

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.


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:\


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
}

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.


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.


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.


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 .


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;

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:


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!


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.


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"]



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.

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 .


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


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!


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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.