Sequência repetitiva mais longa de um único dígito


17

Desafio:

Dado um número inteiro positivo, produza a subsequência de um dígito mais longa que ocorre pelo menos duas vezes, AND tem limites de outro dígito (ou o início / fim do número inteiro).

Um exemplo:

Entrada: 7888885466662716666
a subsequência mais longa de um único dígito seria 88888( 7[88888]5466662716666) com um comprimento de 5. No entanto, essa subsequência ocorre apenas uma vez no número inteiro.
Em vez disso, o resultado da entrada 7888885466662716666deve ser 6666( 78888854[6666]271[6666]), pois ocorre (pelo menos) duas vezes.

Regras do desafio:

  • O comprimento das subsequências tem prioridade sobre a quantidade de vezes que ocorre. (Ou seja, com entrada 8888858888866656665666, produzimos 88888( [88888]5[88888]66656665666; comprimento 5, ocorre duas vezes), e não 666( 88888588888[666]5[666]5[666]; comprimento 3, ocorre três vezes).
  • Se o comprimento de várias subsequências for igual, produziremos a que tiver o maior número de ocorrências. Ou seja, com a entrada 3331113331119111, produzimos 111( 333[111]333[111]9[111]; comprimento 3, ocorre três vezes), e não 333( [333]111[333]1119111; comprimento 3 também, mas ocorre duas vezes)
  • Se a contagem de ocorrências e o comprimento de várias subsequências forem iguais, você poderá gerar uma delas ou todas (em qualquer ordem). Ou seja, com a entrada 777333777333, os eventuais resultados são os seguintes: 777; 333; [777, 333]; ou [333, 777].
  • A subsequência deve ter limites de outros dígitos (ou o início / fim do número inteiro). Ou seja, com a entrada, 122222233433o resultado é 33( 1222222[33]4[33]; comprimento 2, ocorre duas vezes) e não 222( 1[222][222]33433comprimento 3, ocorre duas vezes com ambos inválidos).
    • Isso se aplica a todos os números contados no contador de ocorrências. Ou seja, com a entrada, 811774177781382o resultado é 8( [8]117741777[8]13[8]2; comprimento 1, ocorre três vezes) e não 77( 811[77]41[77]781382/ 811[77]417[77]81382; comprimento 2, ocorre duas vezes com um inválido) nem 1( 8[1][1]774[1]7778[1]382;; comprimento 1, ocorre quatro vezes com dois inválidos).
  • Você pode assumir que a entrada não conterá nenhum dígito 0(ela corresponderá [1-9]+). (Isso evita que seja necessário lidar com casos de teste como 10002000esse 000, onde a maioria dos idiomas seria impressa 0por padrão.)
  • Você pode assumir que a entrada sempre conterá pelo menos uma saída válida.
  • As E / S são flexíveis. Pode ser uma lista / matriz / fluxo de dígitos / bytes / caracteres ou como sequência em vez de um único número inteiro.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste:

Input:  7888885466662716666 / [7,8,8,8,8,8,5,4,6,6,6,6,2,7,1,6,6,6,6]
Output: 6666                / [6,6,6,6]

Input:  3331113331119111 / [3,3,3,1,1,1,3,3,3,1,1,1,9,1,1,1]
Output: 111              / [1,1,1]

Input:            777333777333                   / [7,7,7,3,3,3,7,7,7,3,3,3]
Possible outputs: 777; 333; [777,333]; [333;777] / [7,7,7]; [3,3,3]; [[7,7,7],[3,3,3]]; [[3,3,3],[7,7,7]]

Input:  122222233433 / [1,2,2,2,2,2,2,3,3,4,3,3]
Output: 33           / [3,3]

Input:  811774177781382 / [8,1,1,7,7,4,1,7,7,7,8,1,3,8,2] 
Output: 8               / [8]

Input:  555153333551 / [5,5,5,1,5,3,3,3,3,5,5,1] 
Output: 1            / [1]

Input:            12321              / [1,2,3,2,1]
Possible outputs: 1; 2; [1,2]; [2,1] / [1]; [2]; [[1],[2]]; [[2],[1]]

Input:  944949949494999494 / [9,4,4,9,4,9,9,4,9,4,9,4,9,9,9,4,9,4]
Output: 4                  / [4]

Input:  8888858888866656665666 / [8,8,8,8,8,5,8,8,8,8,8,6,6,6,5,6,6,6,5,6,6,6]
Output: 88888                  / [8,8,8,8,8]

Input:  1112221112221111               / [1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1]
Output: 111; 222; [111,222]; [222,111] / [1,1,1]; [2,2,2]; [[1,1,1],[2,2,2]]; [[2,2,2],[1,1,1]]

Input:  911133111339339339339339 / [9,1,1,1,3,3,1,1,1,3,3,9,3,3,9,3,3,9,3,3,9,3,3,9]
Output: 111                      / [1,1,1]

1
Caso de teste sugerido: 8888858888866656665666. Se eu interpretei o desafio corretamente, as soluções Brachylog e 05AB1E falharam.
Mr. Xcoder

@ Mr.Xcoder Adicionado, obrigado.
Kevin Cruijssen

@ Arnauld Hmm, seria um dos vencedores de qualquer maneira, na minha opinião, porque ocorre tantas vezes quanto 222quando limitado por outros números inteiros. Acho que não devemos contar a ocorrência que é uma substring de 1111. É melhor esperar pelo OP, de fato.
Mr. Xcoder

2
@Arnauld Para 1112221112221111estes são os subsequ�ncias e suas contagens: 1111 (1), 111 (2), 222 (2). Uma vez que só produz sequências que ocorrem pelo menos duas vezes, a saída pode ser um de: 111, 222, [111,222], [222,111]. (Veja a quarta regra para obter mais informações.) Basicamente 1111, apenas contará como 1111, e não como 1e 111ou 11e 11. Vou adicionar seu caso de teste, mas a saída é um ou ambos 111e 222.
Kevin Cruijssen 17/09/18

Respostas:


6

05AB1E , 14 bytes

γТ1›ÏD€gZQÏ.M

Experimente online!

Explicação

γ                # group consecutive equal elements
 Т              # count the occurrence of each group among the list of groups
   1›Ï           # keep only groups with a count greater than 1
      D€gZQÏ     # keep only those with a length equal to the greatest length
            .M   # get the most common item

@Riley: Infelizmente, esse seria o primeiro elemento que não é necessariamente o mais comum.
Emigna

Opa .. Eu perdi a bala.
Riley

5

Gelatina , 12 bytes

Œgœ-Q$LÐṀÆṃ'

Experimente online!

Versão anterior - 14 bytes

ŒgŒQ¬TịƲLÐṀÆṃ'

Experimente online!

Como funciona?

Œgœ-Q$LÐṀÆṃ' – Full program. Receives a list of digits as input.
Œg           – Group equal adjacent values.
  œ-Q$       – Multiset difference with itself deduplicate.
      LÐṀ    – Keep those that are maximal by length.
         Æṃ' – Mode. Returns the most common element(s).
-------------------------------------------------------------------------
ŒgŒQ¬TịƲLÐṀÆṃ' – Full program. Receives a list of digits as input.
Œg             – Group equal adjacent values.
  ŒQ           – Distinct sieve. Replace the first occurrences of each value by 1.
                 and the rest by 0. [1,2,3,2,3,2,5]ŒQ -> [1,1,1,0,0,0,1]       
    ¬T         – Negate and find the truthy indices.
      ịƲ       – Then index in the initial list of groups.
               – This discards the groups that only occur once.
        LÐṀ    – Find all those which are maximal by length.
           Æṃ' – And take the mode.

5

JavaScript (ES6), 79 73 68 bytes

Recebe a entrada como uma sequência. Retorna um número inteiro.

s=>[...s,r=q=0].map(o=d=>q=s^d?o[!o[q]|r[q.length]?q:r=q]=s=d:q+d)|r

Experimente online!

Comentado

s =>                      // s = input string, also used as the current digit
  [ ...s,                 // split s into a list of digit characters
    r =                   // r is the final result
    q =                   // q is the current digit sequence
    0                     // append a final dummy entry to force the processing of the last
  ]                       // sequence
  .map(o =                // o is an object used to keep track of encountered sequences
       d =>               // for each digit d in the array defined above:
    q =                   //   update q:
      s ^ d ?             //     if d is not equal to the current digit:
        o[                //       this statement will ultimately update o[q]
          !o[q] |         //         if q has not been previously seen
          r[q.length] ?   //         or the best result is longer than q:
            q             //           leave r unchanged
          :               //         else:
            r = q         //           set r to q
        ] = s = d         //       reset q to d, set the current digit to d
                          //       and mark q as encountered by setting o[q]
      :                   //     else:
        q + d             //       append d to q
  ) | r                   // end of map(); return r, coerced to an integer

Talvez eu esteja dizendo algo incorreto aqui, mas como ...sconverte a entrada em uma lista de caracteres de dígito, não é mais curto usar a entrada como uma lista de caracteres de dígito para começar, em vez de uma string? Eu permiti E / S flexível. (Mas eu estou supondo que ela interfere com outra parte do seu código?)
Kevin Cruijssen

2
@KevinCruijssen O problema é que preciso de uma iteração extra para processar a última sequência. Então, eu precisaria fazer [...s,0]mesmo se sjá houver uma lista.
Arnauld

4

Retina , 56 bytes

L`(.)\1*
O`
L$m`^(.+)(¶\1)+$
$#2;$1
N`
.+;

N$`
$.&
-1G`

Experimente online! O link inclui casos de teste. Explicação:

L`(.)\1*

Listar todas as subsequências de dígitos repetidas no máximo.

O`

Classifique a lista em ordem.

L$m`^(.+)(¶\1)+$
$#2;$1

Liste todas as subsequências múltiplas com sua "contagem".

N`

Classifique em ordem crescente de contagem.

.+;

Exclua as contagens.

N$`
$.&

Classifique em ordem crescente de comprimento. (Onde os comprimentos são iguais, a ordem anterior devido à contagem é preservada.)

-1G`

Mantenha o último valor, ou seja, o maior.


4

R , 102 bytes

function(i)rep(names(sort(-(x=(x=table(rle(i)))[rowSums(x>1)>0,,drop=F])[m<-max(rownames(x)),])[1]),m)

Experimente online!

Como ainda não havia uma resposta R, decidi tentar e bem ... não foi fácil. Realmente não sei se é uma boa abordagem, mas aqui vai.

Entradas e saídas vetores de caracteres.


Perto de 100 bytes é muito bom para R com esse desafio.
NGM



3

Powershell, 101 bytes

($args|sls '(.)\1*'-a|%{$_.Matches}|group|?{$_.Count-1}|sort @{e={$_.Name.Length,$_.Count}})[-1].Name

Script de teste explicado:

$f = {

(
    $args|          # for each argument (stings)
    sls '(.)\1*'-a| # searches all
    %{$_.Matches}|  # regex matches
    group|          # group it (Note: Count of each group > 0 by design)
    ?{$_.Count-1}|  # passthru groups with Count not equal 1
    sort @{         # sort all groups by 2 values
        e={$_.Name.Length,$_.Count}
    }
)[-1].Name          # returns name of last group (group with max values)

}

@(
    ,('7888885466662716666', '6666')
    ,('3331113331119111', '111')
    ,('777333777333', '777','333')
    ,('122222233433', '33')
    ,('811774177781382', '8')
    ,('555153333551','1')
    ,('12321', '1','2')
    ,('944949949494999494','4')
    ,('8888858888866656665666','88888')
    ,('1112221112221111','111','222')
) | % {
    $s,$e = $_
    $r = &$f $s
    "$($r-in$e): $r"
}

Resultado:

True: 6666
True: 111
True: 777
True: 33
True: 8
True: 1
True: 1
True: 4
True: 88888
True: 111


3

Haskell, 72 bytes

import Data.Lists
g!x|y<-countElem x g=(y>1,1<$x,y)
(argmax=<<(!)).group

Como funciona

(argmax=<<(!)).group       -- expands to: f i = argmax (group i !) (group i)
    group                  -- split the input list into subsequences of equal digits
                           -- e.g. "1112211" -> ["111","22","11"]

                           -- find the element of this list where the function !
                           -- returns the maximum value. First parameter to !
                           -- is the grouped input list, second parameter the
                           -- the element to look at 

g!x|
    y<-countElem x g       -- let y be the number of occurrences of x in g
  = (  ,   ,  )            -- return a triple of
     y>1                   -- a boolean y>1  (remember: True > False)  
        1<$x               -- length of x (to be exact: all elements in x
                           -- replaced by 1. This sorts the same way as the
                           -- length of x)
             y             -- y
                           -- a triples sorts lexicographical

Você não precisa usar as listas Haskell + como idioma porque o Data.Lists não faz parte da base?
ბიმო

@WO: não sei. Eu sempre usei um "Haskell" simples, mesmo quando importei uma biblioteca exótica (por exemplo, Glosspara saída gráfica ou Matrix). Eu uso "Haskell + something" se não quiser incluir a contagem de bytes para as importações. Acho que tivemos esse tópico na meta, mas não consigo mais encontrá-lo. Se bem me lembro, não tínhamos definição geral de "biblioteca padrão". Qual deve ser a referência para Haskell? O Relatório Haskell, a base do GHC, Haskell Plattform, outra coisa?
nimi

Na IMO, deve ser como em C / JavaScript / .. que (se importa) precisamos usar Haskell (GHC) ou Haskell (Hugs) etc. porque a implementação especifica uma linguagem no PPCG. Portanto, para uma resposta do GHC que inclua base e para todas as outras que eu não saberia: D
#

Você talvez tenha um link TIO para que possa ser testado? Ou a Data.Listsbiblioteca não está disponível no TIO ou em outro compilador Haskell online?
Kevin Cruijssen

1
@KevinCruijssen: sim Data.Listsestá faltando no TIO. Você pode testá-lo com esta versão .
nimi

3

R , 85 bytes

function(x,R=rle(x),a=ave(R$v,R,FUN=length))rep(R$v[o<-order(a<2,-R$l,-a)[1]],R$l[o])

Experimente online!

  • Entrada: um vetor de dígitos inteiros separados, por exemploc(1,8,8...)

  • Saída: um vetor de dígitos inteiros separados

Código desenrolado com explicação:

function(x){                # x is a vector of digits : e.g. c(1,1,8,8,1,1)

R = rle(x)                  # Get the sequences of consecutive repeating digits
                            # doing run length encoding on x, i.e. : R is a list
                            # with the digits (R$values) and the number of their
                            # consecutive occurrencies (R$lengths)
                            # N.B. you can use R$v for R$values and R$l for R$lenghts

a=ave(R$v,R,FUN=length)     # Group R$v by R$l AND R$v, count the occurrencies 
                            # for each group and "unroll" the value of each 
                            # group to the original R$v length.
                            # Here basically we count the occurrencies of the same 
                            # sequence.

o<-order(a<2,-R$l,-a)[1]    # Get the indexes used to order by a < 2 then by -R$l and
                            # finally by -a; store the first index in "o".
                            # Here basically we use order to select the first sequence 
                            # repeated at least twice, in case of ties the sequence 
                            # with the greatest length and in case of ties the most 
                            # repeated sequence.

rep(R$v[o],R$v[o])          # Using the index "o", we reconstruct the sequence repeating
                            # R$l[o] times R$v[o]
}

Versão alternativa que aceita vetor de dígitos inteiros ou de caracteres:

R , 88 bytes

function(x,R=rle(x),a=ave(R$v,R,FUN=length))rep(R$v[o<-tail(order(a>1,R$l,a),1)],R$l[o])

Experimente online!

  • Entrada: um vetor de caracteres ou dígitos separados, por exemplo, c("1","8","8"...)ouc(1,8,8...)

  • Saída: um vetor de caracteres separados se a entrada for um vetor de caracteres, um vetor de dígitos se a entrada for um vetor de dígitos


Você pode adicionar uma explicação? Não entendo como está funcionando.
jayce

@ JayCe: pronto! (Eu adicionei os detalhes que você bem sabe, apenas para usuários não-R;))
digEmAll

ty! Faz sentido agora.
jayce

2

Vermelho , 256 250 bytes

func[s][p: func[b][sort parse b[collect[any keep[copy a skip thru any a]]]]first
last sort/compare collect[foreach d p p s[if 1 < k: length? to-block d[keep/only
reduce[form unique d k]]]]func[x y][(reduce[length? x/1 x/2])< reduce[length? y/1 y/2]]]

Experimente online!

Realmente, solução realmente longa desta vez ... (suspiro)

Toma a entrada como uma sequência.

Explicação:

f: func [ s ] [
    p: func [ b ] [                        ; groups and sorts the adjacent repeating items
        sort parse b [ 
            collect [                      
                any keep[
                    copy a skip thru any a ; gather any item, optionally followed by itself  
                ]
            ]
        ]
    ]
    t: copy []
    foreach d p p s [                     ; p p s transforms the input string into a block of sorted blocks of repeating digits
        if 1 < k: length? to-block d [    ; filters only the blocks that occur more than once
            insert/only t reduce [ form unique d k ] ; stores the digits and the number of occurences
                                          ; "8888858888866656665666" -> [["5" 3] ["666" 3] ["88888" 2]]
        ]
    ]
    first last sort/compare t func [ x y ] ; takes the first element (the digits) of the last block of the sorted block of items
        [ (reduce [ length? x/1 x/2 ]) < reduce [ length? y/1 y/2 ] ] ; direct comparison of the blocks
]

2

Java (JDK 10) , 213 bytes

s->{int l=99,X[][]=new int[10][l],d,D=0,m=0,M=0;for(var x:s.split("(?<=(.))(?!\\1)"))X[x.charAt(0)-48][x.length()]++;for(;M<1&&l-->1;)for(d=0;d++<9;)if((m=X[d][l])>1&m>M){M=m;D=d;}for(;l-->0;)System.out.print(D);}

Experimente online!

Explicação (desatualizada)

s->{                                    // Lambda for Consumer<String>
 int l=99,                              //  Length of token, max is 99.
     X[][]=new int[10][l],              //  Array containing the occurrences per token
     d,                                 //  digit value
     D=0,                               //  digit holder for best sequence candidate
     m=0,                               //  holder of the current candidate
     M=0;                               //  best candidate for the current length of token.
 for(var x:s.split("(?<=(.))(?!\\1)"))  //  Tokenize the string into digit-repeating sequences
  X[x.charAt(0)-48][x.length()]++;      //   Add one occurrence for the token
 for(;M<1&&l-->1;)                      //  While no value has been found and for each length, descending. Do not decrease length if a value has been found.
  for(d=0;d++<9;)                       //   for each digit
   if((m=X[d][l])>1&m>M){               //    if the current occurrence count is at least 2 and that count is the current greatest for the length
    M=m;D=d;                            //     mark it as the current best
   }                                    //
 for(;l-->0;)System.out.print(D);       //  Output the best-fitting subsequence.
}                                       // 

Créditos


1
Receio que exista uma pequena falha no seu j*o>Mcheque. Se bem entendi, é preciso o máximo length * occurrence-count. Mas para um caso de teste como 1113311133933933933933por exemplo, 111seria (3 * 2 = 6) e 33seria (2 * 6 = 12). Portanto, ele gera 33a ocorrência mais alta, em vez de 111ser a mais longa, pelo menos duas vezes. Além disso, var r="";for(;O-->0;)r+=D;return r;pode ser golfed para for(;O-->0;)System.out.print(D);em Java 10, ou até mesmo mais curto em Java 11: return(D+"").repeat(O);.
Kevin Cruijssen 18/09/18

@KevinCruijssen Acho que consertei.
Olivier Grégoire

1
Isso realmente parece melhor e uma maneira agradável de jogar bytes de golfe ao mesmo tempo. Você esqueceu de atualizar sua explicação. E você pode jogar mais 1 byte de golfe mudando int X[][]=new int[10][99],d,l=99,para int l=99,X[][]=new int[10][l],d,.
Kevin Cruijssen 18/09/18

1
@KevinCruijssen Thanks! Também joguei mais um byte ao escrever em d++<9vez de ++d<10. Desculpe pelo resto: estou um pouco cansado hoje = _ =
Olivier Grégoire

2

Ruby , 68 67 bytes

->a{(b=a.chunk &:+@).max_by{|x|[(c=b.count x)<2?0:x[1].size,c]}[1]}

Experimente online!

Matrizes de entradas e saídas de caracteres.

A abordagem é bastante direta: identificamos as execuções de dígitos consecutivos ( chunkusando unário +como função de identidade) e obtemos o máximo - primeiro pelo tamanho da execução (redefina para zero se sua contagem de ocorrências for <2) e depois pela própria contagem .


2

PCRE, 152 bytes

(\d)(?<!(?=\1)..)(?=(\1*)(?!\1).*(?!\1).\1\2(?!\1))(?!(?:(?=\2((\3?+)(\d)(\5*)))){1,592}?(?=\2\3.*(?!\5).\5\6(?!\5))(?:\1(?=\1*\4\5(\7?+\5)))*+(?!\1))\2

Veja em ação em: https://regex101.com/r/0U0dEp/1 (basta ver a primeira correspondência em cada caso de teste)

Isso é apenas diversão, já que o regex não é uma linguagem de programação real por si só, e a solução é limitada: P

Como um grupo de largura zero, como (?:)+apenas corresponde uma vez e não se repete indefinidamente, e porque o PCRE faz internamente cópias de grupos quantificadas com limites, tive que usar um número mágico ("{1.592}"), que significa que podemos procurar até 592 conjuntos de dígitos contíguos à frente para encontrar um conjunto concorrente que pode ser maior que o atualmente sob inspeção. Mais informações sobre esse conceito aqui .


1

Perl 5 , 88 bytes

my($m,%s);++$i%2*$s{$_}++&&($n=$s{$_}/9+length)>$m&&($a=$_,$m=$n)for pop=~/((.)\2*)/g;$a

Experimente online!

Ligeiramente não-destruído, com testes:

sub f {
  my($m,%s);
  my($i,$n,$a);           #not needed in golfed version
  ++$i % 2  *  $s{$_}++
  && ($n=$s{$_}/9+length) > $m
  && ($a=$_, $m=$n)
    for pop=~/((.)\2*)/g; #i.e. 7888885466662716666 => 7 88888 5 4 6666 2 7 1 6666
  $a
}
for(map[/\d+/g],split/\n/,join"",<DATA>){ #tests
  my($i,@e)=@$_;
  printf "%-6s   input %-24s   expected %-10s   got %s\n",
    (grep f($i) eq $_, @e) ? "Ok" : "Not ok", $i, join('|',@e), f($i);
}
__DATA__
Input:  7888885466662716666     Output: 6666
Input:  3331113331119111        Output: 111
Input:  777333777333            Output: 777|333
Input:  122222233433            Output: 33
Input:  811774177781382         Output: 8
Input:  555153333551            Output: 1
Input:  12321                   Output: 1|2
Input:  944949949494999494      Output: 4
Input:  8888858888866656665666  Output: 88888
Input:  1112221112221111        Output: 111|222

1

Wolfram Language (Mathematica) , 67 bytes

#&@@@MaximalBy[Select[Tally@Split@#,Last@#>1&],{Length@#,#2}&@@#&]&

Função pura. Pega uma lista de dígitos como entrada e retorna uma lista de subsequências (em nenhuma ordem específica) como saída. Não tenho certeza se a cláusula "deve aparecer pelo menos duas vezes" pode ser tratada de maneira mais limpa. Experimente online!


1
Você poderia adicionar um link TIO para ele?
Kevin Cruijssen 18/09/18

Se você realmente insiste em ... #
40718

1

Japt -h , 12 bytes

Entrada e saída são strings.

ò¦ ñÊf@ÓZè¶X

Tente

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.