Repita depois de mim!

23

Dada uma sequência como argumento, produza o comprimento da (s) mais longa (s) substring (s) repetida (s) sobreposta (s) ou zero se não houver essa sequência.

Você pode assumir que a sequência de entrada não está vazia.

Exemplos

abcdefabc: a substring abcé repetida nas posições 1 e 7, portanto, o programa deve gerar 3

abcabcabcabcab: abcabcou bcabcaou cabcabsão repetidos, portanto, o programa deve gerar 6 . (a substring abcabcabcabtambém é repetida, mas as ocorrências se sobrepõem, então não a aceitamos).

aaaaaaa: aaaé repetido nas posições 1 e 4, por exemplo, portanto, o programa deve gerar 3

abcda: aé repetido, então o programa deve gerar 1

xyz: sem sequência repetida → 0

ababcabcabcabcab: deve retornar 6

Isso é , e o menor número de bytes vence.

Arnaud
fonte
1
A string pode estar vazia? Se for esse o caso, seria permitido gerar False em vez de 0 ?
Dennis
@ Dennis Você pode assumir que a string não está vazia.
Arnaud

Respostas:

9

brainfuck, 226 bytes

,[<<<,]+[>>->[[[[>>[>>>]<+<-<[<<<]>>+<-]>[<+>-]>[>>>]<<[>[<+>-]]>[[<+>-]>+[<<<]>
>>-[+>[<<<]<[>+>[->]<<[<]>-]>[<+>>+<-]>>>[>>>]]>>]<]>+[,<<<+]->[<<<]>>>>>+[,+>>>
+]-[>>>]->]<[+<<<]+<<<++[->>>]+>>>->]<[,<<<]<[>>>+<<<-]>+>,>>>]<<.

Formatado:

,[<<<,]
+
[
  for each suffix
  >>->
  [
    for each prefix
    [
      for each suffix
      [
        for each char while no mismatch
        [
          >>[>>>]
          <+<-<[<<<]
          > >+<-
        ]
        >[<+>-]
        >[>>>]
        <<
        [
          mismatch
          >[<+>-]
        ]
        >
        [
          [<+>-]
          >+[<<<]
          >>>-
          [
            match
            +>[<<<]
            <
            [
              >+>[->]
              <<[<]
              >-
            ]
            >[<+> >+<-]
            >>>[>>>]
          ]
          >>
        ]
        <
      ]
      >+[,<<<+]
      ->[<<<]
      >>> >>+[,+>>>+]
      -[>>>]
      ->
    ]
    <[+<<<]
    +<<<++[->>>]
    +>>>->
  ]
  <[,<<<]
  <[>>>+<<<-]
  >+>,>>>
]
<<.

Espera a entrada com ou sem uma nova linha à direita e gera o resultado como um valor de byte .

Experimente online.

Isso verifica cada prefixo para ver se ocorre mais tarde na sequência, corta o primeiro caractere e repete o processo até que não haja mais caracteres.

A fita é dividida em nós de três células,

c 0 f

onde cé um caractere da sequência especificada e fé um sinalizador que pode ser um, negativo ou zero. Sinalizadores diferentes de zero são colocados entre os dois caracteres atualmente sendo comparados e negativos são reservados para as células após o final do prefixo atual e antes do início do sufixo atual (ou seja, antes do índice da correspondência potencial atual).

O resultado é armazenado à esquerda da string e é atualizado sempre que uma correspondência é encontrada.

(A cadeia é realmente processada ao contrário com um \x01anexo a ela.)

Mitch Schwartz
fonte
6

Gelatina , 12 bytes

œ-QL€
ŒṖÇ€FṀ

Experimente online!

Como funciona

ŒṖÇ€FṀ  Main link. Argument: s (string)

ŒṖ      Generate all partitions of s.
  ǀ    Apply the helper link to each partition.
    F   Flatten the resulting array of lengths.
     Ṁ  Take the maximum.


œ-QL€   Helper link. Argument: P (partition)

  Q     Yield the elements of P, deduplicated.
œ-      Multiset subtraction; remove exactly one occurrence of each string in P.
   L€   Compute the lengths of the remaining strings. 
Dennis
fonte
1
Todos saudam Jelly, a melhor linguagem de golfe com códigos!
Nissa
œ-Qé realmente legal.
Lynn
5

Perl 6 , 36 bytes

{m:ex/(.*).*$0/.map(*[0].chars).max}

Tente

Expandido:

{   # bare block lambda with implicit parameter 「$_」

  m           # match ( implicitly against 「$_」
  :exhaustive # every possible way
  /
    (.*)      # any number of characters ( stored in 「$0」 )
    .*
    $0
  /

  .map(

    *\        # the parameter to Whatever lambda
    [0]\      # the value that was in 「$0」 for that match
    .chars    # the number of characters

  ).max

}
Brad Gilbert b2gills
fonte
5

Retina , 35 32 30 bytes

Desafio bem legal.

M&!`(.*)(?=.*\1)
M%`.
O#^`
G1`

Experimente online

Explicação:

M&!`(.*)(?=.*\1)    # Prints overlapping greedy substrings occuring more than once
M%`.                # Replace each line with its length
O#^`                # Sort lines by number in reverse
G1`                 # Return the first line
mbomb007
fonte
Você pode salvar dois bytes usando M%`.como o segundo estágio.
Martin Ender
4

JavaScript (ES6), 79 68 66 bytes

f=(s,r,l=s.match(/(.*).*\1/)[1].length)=>s?f(s.slice(1),l<r?r:l):r
<input oninput=o.textContent=f(this.value)><pre id=o>

Editar: salvou 11 13 bytes graças a @Arnauld.

Neil
fonte
4

Haskell , 79 bytes

(""%)
(a:b)!(c:d)|a==c=1+b!d
_!_=0
a%c@(e:d)=maximum[a!c,""%d,(a++[e])%d]
_%_=0

Experimente online!

Assistente de Trigo
fonte
2
Parece que o primeiro argumento de %pode acumular uma subsequência não contíguas, dando falsos positivos como 2 para aaem axayaa,
xnor
O que @xnor disse. Acho que a chamada recursiva a%destá errada, mas também desnecessária. O que também significa que você pode usar em maxvez de maximum.
Ørjan Johansen
1
Eu acho que mudar a%dpara ""%dconsertar isso.
Xnor
Ah, certo, ainda é necessário (e som) quando aestá vazio.
Ørjan Johansen
1
Eu acho que sum[1|(x,y)<-zip a c,x==y]pode ser usado em vez de a!c.
Laikoni
2

JavaScript, 120

function r(a,b,m){return b=-~b,t=a.slice(0,b),n=a.indexOf(t,b),m=b>m&&!~n?m:b,a!=t&&r(a,b,m)||(a?r(a.slice(1),m,m):~-m)}
C5H8NNaO4
fonte
2

Casca , 11 bytes

L►L§fo↓2`xQ

Experimente online!

Nota: Husk é mais recente que esse desafio.

Explicação

L►L§fo↓2`xQ  Implicit input, say x = "ababc"
          Q  Nonempty substrings: ["a","b","ab",..,"ababc"]
    f        Keep those that satisfy this:
              Take s = "ab" as an example.
   §    `x    Split x along s: ["","","c"]
     o↓2      Drop the first two pieces: ["c"]
              This is truthy (i.e. nonempty).
             Result is ["a","b","ab","a","b","ab"]
 ►L          Take element with maximal length: "ab"
             If the list is empty, "" is used instead.
L            Length: 2
Zgarb
fonte
2

Perl 5 com -p, 40 bytes

$_+=(sort map{y///c}/(?=(.+).*\1)/g)[-1]

Experimente online!

Dom Hastings
fonte
1

Mathematica, 75 65 bytes

10 bytes salvos devido a @JingHwan Min .

Max@StringLength@StringCases[#,a___~~___~~a___:>a,Overlaps->All]&

Função anônima. Pega uma string como entrada e retorna um número como saída.

LegionMammal978
fonte
Eu não acho que você precise do começo e do fim BlankNullSequence (___)quando Overlaps->Allestiver lá. Max@StringLength@StringCases[#,a___~~___~~a___:>a,Overlaps->All]&ficaria bem.
JungHwan Min
@JungHwanMin Obrigado, estava confundindo com StringReplace: P
LegionMammal978
1

Pitão - 16 bytes

Preciso jogar golfe convertendo todas as cordas em comprimentos e encontrando o máximo.

eSlM+ksmft/dTd./

Conjunto de Teste .

Maltysen
fonte
1

Clojure, 112 bytes

#(apply max(for[R[(range(count %))]j R i R](let[[b e](split-at i(drop j %))](if((set(partition i 1 e))b)i 0)))))

faz um loop duas vezes sobre os números 0em n - 1( nsendo o comprimento da string), solta os jcaracteres e divide o restante em partes "inicial" e "final". Cria um conjunto de todas as substrings ede comprimento be o utiliza como uma função para verificar se bé encontrado a partir daí. Retorna o comprimento de bse encontrado e 0, caso contrário, retorna o máximo desses valores.

Seria interessante ver uma versão mais curta.

NikoNyrh
fonte
1

Retina , 24 bytes

L$v`(.*).*\1
$.1
N`
G-1`

Experimente online!

Um aquecimento para eu aprender os novos recursos do Retina 1.

Explicação

L$v`(.*).*\1
$.1

Um estágio List, retorna todas as correspondências para a regex (.*).*\1, que corresponde a qualquer padrão no formato "ABA", onde A e B são duas substrings arbitrárias (possivelmente vazias). As opções adicionais fornecidas para este estágio são v, que considera correspondências sobrepostas e $que aplica uma substituição a cada uma das correspondências antes de devolvê-la: a substituição é indicada na segunda linha e corresponde ao comprimento ( .) do primeiro grupo de captura ( qual seria a subcadeia "A" no exemplo anterior).

N`

Agora temos todos os comprimentos de substrings repetidos, esse estágio simplesmente os classifica em ordem numérica, do mais curto ao mais longo.

G-1`

Por fim, esse estágio grep ( G) mantém apenas o último -1resultado ( ), que é o comprimento da substring repetida mais longa.

Leo
fonte
0

Javascript, 165 bytes

function a(s){var l=s.length/2,z=1,f='';while(z<=l){var t=s.substr(0,z),c=0;for(var i=0;i<s.length;i++){if(s.substr(i,z)===t){c++;if(c>1){f=t}}}z++}return f.length}

Casos de teste

console.log(a('abcabcabcabc')) // Output 6
console.log(a('xyz'))          // Output 0
console.log(a('aaaaaaa'));     // Output 3
console.log(a('abcdefabc'));   // Output 3
Lalith Prasad
fonte
2
Bem-vindo à Programação de quebra-cabeças e código de golfe. Infelizmente, isso retorna 2 para entrada ababcabcabcabcab, mas a sequência cabcabé repetida.
Dennis