Números colapsados


23

Definamos la función a en números naturales n , escrita como base 10 dígitos dkdk1d1d0 , como sigue:

Siempre que haya dígitos adyacentes iguales didi1 , reemplácelos por su sumadi+di1 de izquierda a derecha. Si hubo tales dígitos, repita el mismo procedimiento.

En otras palabras, en cada iteración tomamos con avidez todos los pares de dígitos adyacentes iguales y los reemplazamos por su suma al mismo tiempo (usando el par más a la izquierda si se superponen).

Ejemplo

Tomemos 9988 por ejemplo:

  1. Los primeros dígitos adyacentes que son iguales son los dos 9
  2. Entonces los reemplazamos por 9 + 9=18 que nos da 1888
  3. Como todavía estamos en el primer cruce de izquierda a derecha y todavía había dos 8 s, primero debemos reemplazarlos.
  4. Entonces tenemos 1816
  5. Algo cambió, por lo que debemos hacer otra iteración.
  6. Pero no hay tales dígitos, así que nos detenemos

Por lo tanto el 9988th número en esa secuencia es 1816 .

Reto

Los primeros 200 términos son:

0,1,2,3,4,5,6,7,8,9,10,2,12,13,14,15,16,17,18,19,20,21,4,23,24,25,26,27,28,29,30,31,32,6,34,35,36,37,38,39,40,41,42,43,8,45,46,47,48,49,50,51,52,53,54,10,56,57,58,59,60,61,62,63,64,65,12,67,68,69,70,71,72,73,74,75,76,14,78,79,80,81,82,83,84,85,86,87,16,89,90,91,92,93,94,95,96,97,98,18,10,101,102,103,104,105,106,107,108,109,20,21,4,23,24,25,26,27,28,29,120,121,14,123,124,125,126,127,128,129,130,131,132,16,134,135,136,137,138,139,140,141,142,143,18,145,146,147,148,149,150,151,152,153,154,20,156,157,158,159,160,161,162,163,164,165,4,167,168,169,170,171,172,173,174,175,176,24,178,179,180,181,182,183,184,185,186,187,26,189,190,191,192,193,194,195,196,197,198,28

Su tarea es generar esa secuencia, ya sea

  • dado n , devuelva el nth número en esa secuencia,
  • dado n , devuelve los primeros n números en esa secuencia
  • o generar la secuencia indefinidamente.

Puede elegir su envío para usar 0 - o 1 índice, pero especifique cuál.

Casos de prueba

Puede usar los términos dados anteriormente, sin embargo, aquí hay algunos más grandes:

222 -> 42
1633 -> 4
4488 -> 816
15519 -> 2019
19988 -> 2816
99999 -> 18189
119988 -> 21816
100001 -> 101
999999 -> 181818

Respuestas:




5

Jalea , 11 bytes

DŒg+2/€FVµ¡

Este es un programa completo innecesariamente lento.

Pruébalo en línea!

Versión alternativa, 12 bytes.

DŒg+2/€FVµƬṪ

Un byte más largo, pero mucho más rápido. Funciona como un programa o una función.

Pruébalo en línea!

Cómo funciona

DŒg+2/€FVµƬṪ  Main link. Argument: n (integer)

         µ    Combine the previous links into a chain. Begin a new one.
D               Decimal; yield n's digit array in base 10.
 Œg             Group adjacent, identical digits into subarrays.
   +2/€         Map non-overlapping, pairwise sum over the subarrays.
                If there is an odd number of digits in a subarray, the
                last digit will remain untouched.
       F        Flatten; dump all sums and digits into a single array.
        V       Eval; turn the result into an integer.
          Ƭ   Execute the chain 'til the results are no longer unique.
              Return all unique results.
           Ṫ  Tail; extract the last result.

La versión de 11 bytes hace lo mismo, excepto que llama al enlace n veces para la entrada n , en lugar de llamarlo hasta que se alcanza un punto fijo.


3
No es innecesario si ahorra 1 byte :-)
Luis Mendo

4

Haskell, 70 bytes

until((==)=<<f)f
f(a:b:c)|a==b=show(2*read[a])++f c|1<2=a:f(b:c)
f a=a

La entrada se toma como una cadena.

Pruébalo en línea!


Hasta el momento no le ahorra nada, pero con la misma longitud puede reemplazar la segunda cláusula con |x<-b:c=a:f xo incluso f(a:c)=a:f c, en caso de que una u otra en realidad pueda conducir a una mejora :)
falla el

4

JavaScript, 48 47 46 bytes

Entrada y salida como cadenas. Devuelve el nthtérmino de la secuencia.

f=s=>s-(s=s.replace(/(.)\1/g,x=>x/5.5))?f(s):s

Pruébalo en línea

  • 1 byte guardado gracias a Arnauld
  • 1 byte guardado gracias a tsh

1
x[0]*2->x/5.5
tsh

Gracias @tsh. No hubiera pensado en eso.
Shaggy

3

Perl 6 , 37 bytes

{($_,{S:g[(\d)$0]=2*$0}...*==*)[*-1]}

Pruébalo en línea!

Esta es una función que genera el enésimo término de la secuencia, dado n como argumento.

($_, { ... } ... * == *)es la secuencia de cambios sucesivos en el número de entrada, generado por la expresión entre corchetes (una simple sustitución de expresiones regulares) y se detiene cuando * == *, es decir, cuando los dos últimos números de la secuencia son iguales. Luego, [*-1]toma solo el elemento final de esa secuencia como valor de retorno.


Puede guardar bytes quitando ==*y reemplazando *-1con $_, ya que siempre hay menos que nreemplazos para un número n. 33 bytes
Jo King

3

Retina , 16 bytes

+`(.)\1
$.(2*$1*

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

+`

Repita hasta que la entrada deje de cambiar.

(.)\1

Reemplazar pares de dígitos adyacentes ...

$.(2*$1*

... con el doble del dígito. ( $1*genera una cadena de $1 _s, 2*duplica eso y $.(toma la longitud. En realidad, el motor Retina es más inteligente que eso y simplemente se duplica $1).


3

C # (.NET Core) , 231 , 203 , 200 , 196 , 192 bytes

EDITAR: la función ahora es de 185 bytes más 18 para using System.Linq;

¡Gracias a BMO (para 1> 0 es igual a verdadero más eliminación de nueva línea) y al Sr. XCoder (para declaraciones f =! F)!

EDIT2: hasta 182 bytes más 18 para using System.Linq agradecer a dana por compartir algunos consejos de golf!

EDIT3: ¡Gracias a Encarnación de la ignorancia por int [] -> var, eliminación de cortocircuito && -> & y cambio de ToArray -> ToList! (178 bytes + 18 usando)

EDIT4: La realización de la ignorancia perdió 4 bytes al cambiar una asignación. ¡Dummy, debería haber contado! Gracias de nuevo: D

p=>{var f=1>0;while(f){var t=p.Select(n=>n-48).ToList();p="";f=!f;for(var j=0;j<t.Count;j++){if(j<t.Count-1&t[j]==t[1+j]){p+=t[j]+t[++j];f=!f;continue;}p+=t[j];}};return p;};

Pruébalo en línea!




2

Japt v2.0a0 -h, 15 14 bytes

Devuelve el nthtérmino de la secuencia.

Æ=s_r/(.)\1/ÏÑ

Intentalo

Esto debería funcionar para 10 bytes, pero parece haber un error en el método de reemplazo recursivo de Japt.

e/(.)\1/ÏÑ


2

05AB1E , 11 bytes

Δγε2ôSO}˜J

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Δ             # Continue until the (implicit) input no longer changes:
 γ            #  Split the integer in chunks of the same adjacent digits
              #   i.e. 199999889 → [1,99999,88,9]
  ε     }     #  Map each to:
   2ô         #   Split it into parts of size 2
              #    i.e. 99999 → [99,99,9]
     S       #   Split each part into digits
              #    i.e. [99,99,9] → [[9,9],[9,9],[9]]
       O      #   And take the sum of each part
              #    i.e. [[9,9],[9,9],[9]] → [18,18,9]
         ˜    #  Flatten the list
              #   i.e. [[1],[18,18,9],[16],[9]] → [1,18,18,9,16,9]
          J   #  Join everything together
              #   i.e. [1,18,18,9,16,9] → 118189169
              # (And output the result implicitly at the end)
              #  i.e. output = 28189169

2

Wolfram Language 108 bytes

ToExpression[""<>ToString/@Total/@Flatten[Partition[#,UpTo@2]&/@Split@IntegerDigits@#,1]]&~FixedPoint~#&

Explicación

IntegerDigits transforma el número de entrada en una lista de sus dígitos.

Split agrupa los dígitos repetidos consecutivos.

Partition[#, UpTo@2]&/@ divide series de dígitos similares en listas de, como máximo, longitudes de 2.

Flatten[...,1] elimina llaves ocasionales demasiado anidadas, por ejemplo, {{2,2}} se convierte en {2,2}

Total/@sumas totales de dígitos emparejados. Los dígitos aislados no necesitan sumarse.

ToString convierte los totales (y dígitos aislados) en cadenas.

""<> une todas las cadenas de la lista.

ToExpression Convierte el resultado en un entero.

...~FixedPoint~#& aplica la función hasta que el resultado deja de cambiar.


2

C # (compilador interactivo de Visual C #) con indicador /u:System.Text.RegularExpressions.Regex, 70 bytes

s=>{for(;s[0]!=(s[0]=Replace(s[0],@"(.)\1",m=>m.Value[0]*2-96+"")););}

Salidas modificando la entrada. Toma una lista que contiene una cadena para la entrada.

¡Gracias a @dana por jugar al golf 23 bytes completos!

Pruébalo en línea!


95 + 34 - 33 + 1 para el espacio extra que necesita en los argumentos de la línea de comandos, iirc
solo ASCII

Las funciones anónimas recursivas deben definirse primero, y la definición se incluye en el recuento de bytes.
Encarnación de la ignorancia

Oh, es recursivo
solo ASCII el

1
¡Agradable! Creo que puedo entenderlo un poco más
Encarnación de la ignorancia

Esa es una puntuación bastante buena teniendo en cuenta que es C # :)
dana

1

Limpio , 118 bytes

import StdEnv,Data.List
$[a,b:t]|a==b=[1,(a*2)rem 10]%(1-a/5,1)++ $t=[a: $[b:t]]
$l=l

limit o iterate$o map digitToInt

Pruébalo en línea!

Toma el primer valor repetido ( limit) de la lista infinita de aplicaciones ( iterate) de una lambda que realiza un solo paso del proceso de colapso. Entrada tomada como a [Char].


1

Rojo , 84 83 80 bytes

func[n][if parse s: form n[to some change[copy d skip d](2 * do d)to end][f s]s]

Pruébalo en línea!

Devuelve el nthtérmino de la secuencia.

Explicación:

Red[]
f: func [ n ] [
    if parse s: form n [  ; parse the input converted to a string
        to some change [  ; find and change one or more
            copy d skip   ; digit (in fact any character, no predefined character classes)
            d             ; followed by itself
        ] (2 * do d)      ; with its doubled numeric value 
        to end            ; go to the end of the string
    ] [ f s ]             ; call the function with the altered string if parse returned true
    s                     ; finally return the string 
]


1

C # (compilador interactivo de Visual C #) , 111 bytes

s=>{var t=s;do{s=t;t="";for(int i=0;i<s.Length;)t+=s[i]%48*(s[i++]!=(s+0)[i]?1:2*++i/i);}while(t!=s);return t;}

Pruébalo en línea!

ENORME crédito a @ASCIIOnly por jugar al golf ~ 30;) Al principio, los dos estábamos publicando actualizaciones simultáneamente, ¡pero en algún momento fue claramente a la ciudad!

-2 gracias a @EmbodimentOfIgnorance!

Menos código de golf ...

// s is the input as a string
s=>{
  // t is another string used
  // to hold intermediate results
  var t=s;
  // the algorithm repeatedly
  // processes s and saves the
  // result to t
  do{
    // copy the last result to s
    // and blank out t
    s=t;
    t="";
    // iterate over s
    for(int i=0;i<s.Length;)
      // append either 1 or 2 times
      // the current digit to t
      t+=s[i]%48*
        // compare the current digit
        // to the next digit. to prevent
        // an out-of-bounds exception,
        // append a 0 to s which either
        // gets ignored or collapses
        // to 0
        (s[i++]!=(s+0)[i]
          // if they are different, then
          // the multiplier is 1
          ?1
          // if they are the same, then
          // the multiplier is 2, and we
          // have to increment i
          :2*++i/i);
  }
  // continue this until the input
  // and output are the same
  while(t!=s);
  return t;
}



@ASCIIOnly - Buen movimiento :) (s[i++]-48)*2=>s[i++]*2-96
dana


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.