Subsecuencia repetida más larga de un solo dígito


17

Desafío:

Dado un número entero positivo, genera la subsecuencia de un solo dígito más larga que ocurre al menos dos veces, Y tiene límites de otro dígito (o el inicio / final del entero).

Un ejemplo:

Entrada: 7888885466662716666
La subsecuencia más larga de un solo dígito sería 88888( 7[88888]5466662716666) con una longitud de 5. Sin embargo, esta subsecuencia solo ocurre una vez en el entero.
En cambio, el resultado para la entrada 7888885466662716666debe ser 6666( 78888854[6666]271[6666]), ya que ocurre (al menos) dos veces.

Reglas de desafío:

  • La longitud de las subsecuencias tiene prioridad sobre la cantidad de veces que ocurre. (Es decir, con entrada 8888858888866656665666, salimos 88888( [88888]5[88888]66656665666; longitud 5, ocurre dos veces), y no 666( 88888588888[666]5[666]5[666]; longitud 3, ocurre tres veces).
  • Si la longitud de las subsecuencias múltiples es igual, sacamos la que tiene el mayor recuento de ocurrencias. Es decir, con entrada 3331113331119111, salimos 111( 333[111]333[111]9[111]; longitud 3, ocurre tres veces), y no 333( [333]111[333]1119111; longitud 3 también, pero ocurre dos veces)
  • Si el recuento de ocurrencia y la longitud de las subsecuencias múltiples son iguales, puede generar cualquiera de ellos o todos (en cualquier orden). Es decir, con la entrada 777333777333, las salidas posibles son: 777; 333; [777, 333]; o [333, 777].
  • La subsecuencia debe tener límites de otros dígitos (o el inicio / final del número entero). Es decir, con la entrada, 122222233433el resultado es 33( 1222222[33]4[33]; longitud 2, ocurre dos veces) y no 222( 1[222][222]33433, longitud 3, ocurre dos veces con ambos inválidos).
    • Esto se aplica a todos los números que se cuentan para el contador de ocurrencias. Es decir, con la entrada, 811774177781382el resultado es 8( [8]117741777[8]13[8]2; longitud 1, ocurre tres veces) y no 77( 811[77]41[77]781382/ 811[77]417[77]81382; longitud 2, ocurre dos veces con un inválido) ni 1( 8[1][1]774[1]7778[1]382; longitud 1, ocurre cuatro veces con dos inválidos).
  • Puede suponer que la entrada no contendrá ningún dígito 0(coincidirá [1-9]+). (Esto es para evitar tener que lidiar con casos de prueba como el 10002000que debería generar 000, donde la mayoría de los idiomas generarían 0de forma predeterminada).
  • Puede suponer que la entrada siempre contendrá al menos una salida válida.
  • Las E / S son flexibles. Puede ser una lista / matriz / secuencia de dígitos / bytes / caracteres o como una cadena en lugar de un solo entero.

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de código de golf lo desalienten de publicar respuestas con idiomas que no sean de código. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Se aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código.
  • Además, se recomienda agregar una explicación para su respuesta.

Casos de prueba:

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 prueba sugerida: 8888858888866656665666. Si interpreté el desafío correctamente, fallan las soluciones Brachylog y 05AB1E.
Sr. Xcoder

@ Mr.Xcoder Añadido, gracias.
Kevin Cruijssen

@Arnauld Hmm, en mi opinión, sería uno de los ganadores de todos modos porque ocurre tantas veces como 222cuando está limitado por otros enteros. Supongo que no deberíamos contar la ocurrencia de la que es una subcadena 1111. Sin embargo, es mejor esperar al OP.
Sr. Xcoder

2
@Arnauld Para 1112221112221111estas son las subsecuencias y su población en: 1111 (1), 111 (2), 222 (2). Ya que sólo da salida a secuencias que ocurren al menos dos veces, la salida puede ser uno de: 111, 222, [111,222],[222,111] . (Consulte la cuarta regla para obtener más información.) Básicamente 1111solo contará como 1111, y no como 1y 111o 11y 11. Agregaré su caso de prueba, pero el resultado es uno o ambos de 111y 222.
Kevin Cruijssen

Respuestas:


6

05AB1E , 14 bytes

γТ1›ÏD€gZQÏ.M

Pruébalo en línea!

Explicación

γ                # 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: Desafortunadamente, ese sería el primer elemento que no es necesariamente el más común.
Emigna

Vaya ... me perdí esa bala.
Riley

5

Jalea , 12 bytes

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

Pruébalo en línea!

Versión anterior - 14 bytes

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

Pruébalo en línea!

¿Cómo 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

Toma la entrada como una cadena. Devuelve un entero.

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

Pruébalo en línea!

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

Tal vez estoy diciendo algo incorrecto aquí, pero dado que ...sconvierte la entrada en una lista de caracteres de dígitos, ¿no es más corto tomar la entrada como una lista de caracteres de dígitos para comenzar, en lugar de una cadena? He permitido E / S flexibles. (¿Pero supongo que interfiere con otra parte de su código?)
Kevin Cruijssen

2
@KevinCruijssen El problema es que necesito una iteración adicional para procesar la última secuencia. Así que tendría que hacerlo [...s,0]incluso si sya es una lista.
Arnauld

4

Retina , 56 bytes

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

N$`
$.&
-1G`

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

L`(.)\1*

Liste todas las subsecuencias de dígitos repetidas al máximo.

O`

Ordenar la lista en orden.

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

Enumere todas las subsecuencias múltiples con su "conteo".

N`

Ordenar en orden ascendente de recuento.

.+;

Eliminar los recuentos.

N$`
$.&

Ordenar en orden ascendente de longitud. (Cuando las longitudes son iguales, se conserva el orden anterior debido al recuento).

-1G`

Mantenga el último, es decir, el valor más largo.


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)

Pruébalo en línea!

Como todavía no había una respuesta R, decidí intentarlo, y bueno ... no fue fácil. Realmente no sé si es un buen enfoque, pero aquí va.

Entradas y salidas de vectores de caracteres.


Cerca de 100 bytes es bastante bueno para R con este desafío.
ngm



3

Powershell, 101 byte

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

Script de prueba 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"
}

Salida:

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

Cómo 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

¿No necesita usar las listas de Haskell + como idioma porque Data.Lists no es parte de la base?
ბიმო

@BWO: no lo sé. Siempre he usado un "Haskell" simple, incluso cuando importé una biblioteca exótica (por ejemplo, Glosspara salida gráfica o Matrix). Uso "Haskell + algo" si no quiero incluir el recuento de bytes para las importaciones. Creo que teníamos este tema en meta, pero ya no puedo encontrarlo. Si no recuerdo mal, no teníamos una definición general de "biblioteca estándar". ¿Cuál debería ser la referencia para Haskell? El Informe Haskell, la base de GHC, la plataforma Haskell, ¿algo más?
nimi

En mi opinión, debería ser como con C / JavaScript / ... que (si es importante) necesitamos usar Haskell (GHC) o Haskell (Abrazos) etc. porque la implementación especifica un lenguaje en PPCG. Entonces, para una respuesta de GHC que incluiría base y para todos los demás, no lo sabría: D
ბიმო

¿Quizás tenga un enlace TIO para poder probarlo? ¿O la Data.Listsbiblioteca no está disponible en TIO u otro compilador Haskell en línea?
Kevin Cruijssen

1
@KevinCruijssen: sí Data.Listsfalta en TIO. Puedes probarlo con esta versión .
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])

Pruébalo en línea!

  • Entrada: un vector de dígitos enteros separados, p. Ej.c(1,8,8...)

  • Salida: un vector de dígitos enteros separados

Código desenrollado con explicación:

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

Versión alternativa que acepta el vector de números enteros o 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])

Pruébalo en línea!

  • Entrada: un vector de caracteres o dígitos separados, por ejemplo, c("1","8","8"...)oc(1,8,8...)

  • Salida: un vector de caracteres separados si la entrada era un vector de caracteres, un vector de dígitos si la entrada era un vector de dígitos


¿Puedes agregar una explicación? No entiendo cómo está funcionando.
JayCe

@ JayCe: hecho! (He agregado detalles que usted bien sabe, solo para usuarios que no son R);
digEmAll

ty! Tiene sentido ahora.
JayCe

2

Rojo , 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]]]

Pruébalo en línea!

Realmente, una solución muy larga esta vez ... (suspiro)

Toma la entrada como una cadena.

Explicación:

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

Pruébalo en línea!

Explicación (obsoleta)

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
Me temo que hay un pequeño defecto en su j*o>Mcheque. Si entiendo correctamente, toma el máximo length * occurrence-count. Pero para un caso de prueba como, 1113311133933933933933por ejemplo, 111sería (3 * 2 = 6) y 33sería (2 * 6 = 12). Por lo tanto, produce 33la mayor ocurrencia, en lugar de 111ser la más larga, al menos dos veces. También,var r="";for(;O-->0;)r+=D;return r; se pueden golfed que for(;O-->0;)System.out.print(D);en Java 10, o incluso más corto en Java 11: return(D+"").repeat(O);.
Kevin Cruijssen

@KevinCruijssen Creo que lo arreglé.
Olivier Grégoire

1
De hecho, se ve mejor, y una buena forma de jugar al golf al mismo tiempo. Simplemente olvidaste actualizar tu explicación. Y puede jugar al golf 1 byte más cambiando int X[][]=new int[10][99],d,l=99,a int l=99,X[][]=new int[10][l],d,.
Kevin Cruijssen

1
@KevinCruijssen ¡Gracias! También jugué al golf un byte más escribiendod++<9 lugar de ++d<10. Perdón por el resto: estoy bastante cansado hoy = _ =
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]}

Pruébalo en línea!

Entradas y salidas de matrices de caracteres.

El enfoque es bastante sencillo: identificamos las ejecuciones de dígitos consecutivos ( chunkusando unario +como función de identidad) y tomamos el máximo, primero por el tamaño de la ejecución (restablecer a cero si su recuento de ocurrencia es <2), luego por el recuento mismo .


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

Véalo en acción en: https://regex101.com/r/0U0dEp/1 (solo mire la primera coincidencia en cada caso de prueba)

Esto es solo por diversión, ya que regex no es un lenguaje de programación real en sí mismo, y la solución es limitada: P

Debido a que un grupo de ancho cero, como (?:)+solo coincide una vez y no se repite indefinidamente, y debido a que PCRE realiza copias de grupos cuantificados con límites internamente, tuve que usar un número mágico allí ("{1,592}"), que significa que solo podemos buscar hasta 592 conjuntos de dígitos contiguos por delante para encontrar un conjunto de la competencia que podría ser más largo que el que está actualmente bajo inspección. Más información sobre este concepto aquí .


1

Perl 5 , 88 bytes

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

Pruébalo en línea!

Ligeramente sin golf, con pruebas:

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}&@@#&]&

Pura función. Toma una lista de dígitos como entrada y devuelve una lista de subsecuencias (sin ningún orden en particular) como salida. No estoy seguro si la cláusula "debe aparecer al menos dos veces" se puede manejar de manera más limpia. Pruébalo en línea!


1
¿Podría quizás agregarle un enlace TIO?
Kevin Cruijssen

Si realmente insistes ...
LegionMammal978

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.