Enteros ordenados por sus raíces digitales.

24

La raíz digital (también suma digital repetida) de un entero positivo es el valor (de un solo dígito) obtenido por un proceso iterativo de suma de dígitos, en cada iteración utilizando el resultado de la iteración anterior para calcular una suma de dígitos. El proceso continúa hasta que se alcanza un número de un solo dígito.

Por ejemplo, la raíz digital de 65536 es 7 , porque 6 + 5 + 5 + 3 + 6 = 25 y 2 + 5 = 7 .


Ordenar todas las raíces digitales no tiene mucho sentido, ya que solo comenzaría con infinitos 1 s.

En su lugar, crearemos listas de todos los enteros de un solo dígito junto con sus raíces digitales, luego todos los números de dos dígitos junto con sus raíces digitales, luego el triple, cuádruple, etc.

Ahora, para cada una de esas listas, lo ordenaremos de manera que todos los enteros con raíces digitales de 1 aparezcan primero, luego todos los enteros con raíces digitales de 2 y así sucesivamente. La clasificación será estable, de modo que la lista de enteros con ciertas raíces digitales debe estar en orden ascendente después de la clasificación.

Finalmente concatenaremos estas listas en una sola secuencia. Esta secuencia comenzará con todos los números de un solo dígito, luego todos los números de dos dígitos (ordenados por su raíz digital), luego todos los números de tres dígitos y así sucesivamente.


Reto:

Tome un entero positivo n como entrada y envíe el número n 'en la secuencia descrita anteriormente. Puede elegir si la lista tiene un índice 0 o un índice 1 .

La secuencia es así:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 19, 28, 37, 46, 55, 64, 73, 82, 91, 11, 20, 29 ... 
72, 81, 90, 99, 100, 109, 118, ... 
981, 990, 999, 1000, 1009, 1018, 1027, ...

Casos de prueba:

Los casos de prueba están indexados en 1.

   n   f(n)  
   9      9
  10     10
  11     19
  40     13
  41     22
  42     31
  43     40
  44     49
  45     58
 600    105
 601    114
 602    123
 603    132
 604    141
 605    150
4050   1453
4051   1462
4052   1471
4053   1480
4054   1489
4055   1498

Más fácil de copiar:

n =    9, 10, 11, 40, 41, 42, 43, 44, 45, 600, 601, 602, 603, 604, 605, 4050, 4051, 4052, 4053, 4054, 4055, 
f(n) = 9, 10, 19, 13, 22, 31, 40, 49, 58, 105, 114, 123, 132, 141, 150, 1453, 1462, 1471, 1480, 1489, 1498

Aclaraciones:

  • Es posible que no muestre todos los n primeros elementos. Solo deberás generar el n 'th.
  • El código debe funcionar teóricamente para todos los enteros hasta 10 ^ 9 , pero está bien si se agota el tiempo de espera en TIO (u otros intérpretes con restricciones de tiempo) para entradas mayores de 999 .
  • Se alientan las explicaciones.

Es , por lo que gana el código más corto en cada idioma. ¡No se desanime por otras soluciones en el idioma en el que desea jugar golf, incluso si son más cortas de lo que puede manejar!

Stewie Griffin
fuente
2
Nota divertida: esto aún no está en OEIS
apnorton

Respuestas:

16

Python 2 , 78 60 52 46 45 bytes

-6 bytes gracias a GB .
-1 byte gracias a Jakob .

n=input()
b=10**~-len(`n`)
print~-b+n/b+n%b*9

Pruébalo en línea!

Finalmente llegó a una forma cerrada, 1 indexada.


Python 2 , 78 bytes

0 indexado.

d=10;k=1
exec'\nk+=9\nif k>d+7:k=d;d*=10\nif k>=d:k-=d/10*9-1'*input()
print k

Pruébalo en línea!

ovs
fuente
2
Esperaba ver una solución que no creara la secuencia completa. Bien hecho :-)
Stewie Griffin
¿Cómo obtuvo la solución de forma cerrada? (editar: parece que hay una explicación en wikipedia )
sevko
@sevko El 78-byter fue mi solución original (una variante algo no golfista aquí ). Esto ya funciona sin calcular ninguna raíz cúbica, sino generando la secuencia número por número, según las reglas que observé en la secuencia. En base a estos cálculos iterativos, se puede contar cuántas veces se ejecuta cada expresión.
ovs
@sevko con la ayuda de WolframAlpha pude construir un formulario cerrado. Al principio, el programa que usaba el formulario cerrado era mucho más largo (~ 95 bytes) pero con algo de golf y WolframAlpha llegó a su forma actual.
ovs
4

Python 3 , 80 bytes

f=lambda i,k=1:k>i and sorted(range(k//10,k),key=lambda n:n%-9)[i-k]or f(i,k*10)

Pruébalo en línea!

1 indexado. Esto es lo mejor que pude manejar en Python 3 (bueno, excepto por el byte 78 , que es un puerto de mi solución Python 2 a continuación; creo que este es mucho más genial, sin embargo). Los programas completos de Python 2 tienen la ventaja de este desafío en particular, porque input()necesita una conversión inten Python 3 (+5 bytes), execes una función, en lugar de una declaración (+2 bytes) y /realiza la división de enteros por defecto si sus argumentos son enteros en Py 2 (+1 byte), por lo que esto es definitivamente más corto que portar la respuesta de ovs .

Cómo funciona

Preparar

f=lambda i,k=1:k>i and ... or f(i,k*10)

Esto define una función recursiva f que toma un argumento entero iy otro, k , que por defecto es 1 . Mientras k ≤ i , la función f devuelve f (i, 10k) , multiplicando k por 10 cada vez hasta que sea mayor que i .

Rango objetivo e indexación correcta

...range(k//10,k)...[i-k]

Después de este conjunto de operaciones, nos quedamos con i , la entrada inicial y la variable k que representa la potencia más pequeña de 10 mayor que i . De esta manera, podemos generar el rango (entero) [floor (k / 10), k) , que básicamente incluye todos los enteros que son:

  • mayor o igual que la potencia más alta de 10 menor o igual que i
  • menor que k , la potencia más pequeña de 10 mayor que i

Como ignoramos los enteros menores que x = piso (k / 10) , debemos cambiar la indexación para tener en cuenta los números que faltan. La forma obvia es restar su recuento, x , de i , de modo que indexemos en la lista (después de la clasificación, que se describe a continuación), por lo tanto, tenemos ix . Sin embargo, ya que la lista contiene 9k / 10 , los artículos, y la indexación en una lista en el índice -y para algunos positivos y produce el y ésimo elemento del extremo en Python, esto es simplemente equivalente a la indexación con ik , por lo tanto, el ahorro de 4 bytes.

Ordenar cada fragmento por la raíz digital

sorted(...,key=lambda n:n%-9)

La fórmula para la función raíz digital es 1 + ((n-1) mod 9) (consulte la sección Fórmula de congruencia de este artículo de Wikipedia ). Como 1 se agregaría de esta manera a cada uno de ellos, es superfluo al ordenar, por lo que nos quedamos con (n-1) mod 9 . La forma en %que funciona el operador de Python cuando se le dan números negativos en el RHS es muy conveniente, porque podemos usar n pymod -9 en su lugar para guardar aún otro byte anterior.


Python 2 , 72 bytes

Inspirado por la presentación de Chas Brown .

lambda i:sorted(range(1,10**len(`i`)),key=lambda n:(len(`n`),n%-9))[i-1]

Pruébalo en línea!

Sr. Xcoder
fuente
4

Pitón 2 , 73 71 70 bytes

lambda n:sorted(range(10**len(`n`)),key=lambda i:(len(`~i`),i%9))[n]+1

Pruébalo en línea!

2 bytes thx a Sr. XCoder ; y 1 byte gracias a H.PWiz .

Esto está indexado a 0.

Chas Brown
fuente
Bueno, i%9debería ser suficiente en lugar de i%9+1... de esta manera superaste mi 72 byter: DD:
Sr. Xcoder
@ Mr.Xcoder: ¡Ja! Tienes razón ...
Chas Brown
len(`~i`)debería funcionar
H.PWiz
4

Jalea ,  15 14 10  9 bytes

D,Ḣ$‘Ḍḅ9’

Pruébalo en línea!

¿Cómo?

Utiliza una versión de golf de la solución de forma cerrada creada por ovs en su respuesta de Python ...

La fórmula expuesta por los ovs es: 9 * (n% b) + (n / b) + b - 1 donde b = 10 floor (log (n, 10))

Ahora, si c es el recuento de dígitos decimales de n, entonces b-1 es c-1 nueves en decimal.
Esto es lo mismo que nueve veces el valor de c-1 en decimal (por ejemplo111*9=999 ).

Además n / b es el principal dígitos de n y n% b es el resto de los dígitos como un número decimal.

Una fórmula como b * x + y puede implementarse como una conversión de la [x,y]base b
(es decir, b ^ 1 * x + b ^ 0 * y = b * x + y )

Como tal, podemos tomar un número, n (por ejemplo 7045), dividirlo en los dígitos iniciales y finales, colocando el dígito inicial al final ( [[0,4,5],7]), agregar uno a todos los dígitos del primer elemento para atender la adición de b-1 ( [[1,5,6],7]) convierte esto de listas decimales a enteros ( [156,7]), y lo convierte de base nueve ( 1411).

En la implementación a continuación, agregamos uno a todos los dígitos de ambos elementos cuando abastecemos a b-1 ( [[0,4,5],8]), convertimos de listas decimales a enteros ( [156,8]), convertimos de base nueve ( 1412) y luego restamos el que este proceso agregó ( 1411).

D,Ḣ$‘Ḍḅ9’ - Link: positive integer, n    e.g. 4091
D         - to base ten                       [4, 0, 9, 1]
   $      - last two links as a monad:
  Ḣ       -   head (modifies the list too)    4
 ,        -   pair (the modified list) with   [[0, 9, 1], 4]
    ‘     - increment (vectorises)            [[1, 10, 2], 5]
     Ḍ    - from base ten (vectorises)        [202, 5] (since 1*10^2+10*10^1+2*10^0 = 100+100+2 = 202)  
      ḅ9  - convert from base 9               1823 (since 202*9^1 + 5*9^0 = 202*9 + 6*9 = 1818 + 5 = 1823)
        ’ - decrement                         1822

Anterior, 14 byter:

æċ⁵DL,’%9ƊƲÞị@

Pruébalo en línea!

Éste construye la lista hasta la siguiente potencia de 10 por encima de la entrada al ordenar estos números naturales para [digitalRoot, digitCount]luego encontrar el valor en el índice ingresado.

Jonathan Allan
fuente
3

Haskell , 94 88 bytes

([n|x<-[0..],i<-[1..9],n<-[10^x..10^(x+1)-1],until(<10)(sum.map(read.pure).show)n==i]!!)

Pruébalo en línea! 0 indexado.

Explicación:

La comprensión de la lista genera la secuencia como una lista infinita en la que indexamos con !!:

  • x es uno menos que el número actual de dígitos y se extrae de la lista infinita [0,1,2,3, ...]
  • iitera sobre el rango de 1a9 y se usa para ordenar por las raíces digitales
  • n itera sobre todos los números con x+1 dígitos
  • until(<10)(sum.map(read.pure).show) calcula la raíz digital ( vea aquí una explicación )
  • nse agrega a la lista si su raíz digital es igual i.
Laikoni
fuente
2

Retina , 65 bytes

.
9
.+
*
L$`
$`
O$`_(_{9})*(_*)
$2
_+
$.&
N$`
$.&
"$+L`^|\d+"^~G`

Pruébalo en línea! 1 indexado. Explicación:

.
9
.+
*
L$`
$`

Construya una lista de líneas de _s desde 0 hasta la próxima potencia de 10 (exclusivo).

O$`_(_{9})*(_*)
$2

Ordénelos todos en orden de raíz digital.

_+
$.&

Convierte de unario a decimal.

N$`
$.&

Ordénelos en orden de longitud.

"$+L`^|\d+"^~G`

Extrae el nelemento th.

Neil
fuente
2

Pyth ,  36 31 25 24 23  22 bytes

1 indexado.

@o%tN9rFK^LThBlt`Q-QhK

¡Banco de pruebas!

Cómo funciona (anticuado)

@smo%tN9dcU^TKhs.lQT^LTSK – Full program. Q = input.
             Khs.lQT      – Take floor(log10(Q))+1 and store it in K.
          U^T             – Generate [0 ... T^K).
         c                – Cut at locations...
                    ^LTSK – Of the powers of 10 less than K.
  m     d                 – Map over those.
   o  N                   – Sort them by...
    %t 9                  – Themselves decremented, modulo 9.
@s                        – Flatten the result and retrieve the Q'th entry.
Sr. Xcoder
fuente
2

05AB1E , 19 11 bytes

Puerto de mi respuesta de Python .

-6 bytes (!) Gracias a Kevin Cruijssen .

g<°©‰`9*®O<

Pruébalo en línea!

Code           Explanation            Stack
               implicit input         [n]
g              length                 [len(n)]
 <             decrement              [len(n)-1]
  °            10 ** a                [10**(len(n) - 1)]
   ©           store value            [10**(len(n) - 1)]
    ‰          divmod                 [[n // 10**(len(n) - 1), n % 10**(len(n) - 1)]]
     `         push items to stack    [n // 10**(len(n) - 1), n % 10**(len(n) - 1)]
      9*       multiply by 9          [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9]
        ®      retrieve value         [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9, 10**(len(n) - 1)]
         O     sum the stack          [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1)]
          <    decrement              [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1) - 1]
               implicit output
ovs
fuente
Me ganaste, estaba trabajando en una respuesta que era un puerto de tu respuesta de Python. ;) 13 bytes:g<°©÷¹®%9*®O< . Aquí la explicación que estaba a punto de publicar .
Kevin Cruijssen
1
@KevinCruijssen muchas gracias. El registro parece ser bastante útil. Pude bajarlo dos bytes más usando divmod.
ovs
1

Perl 6 ,  68  58 bytes

{({|(10**$++..^10**++$).sort({({.comb.sum}…*==*).tail})}…*)[$_]}

Pruébelo basado en 0

{sort({.chars,({.comb.sum}…*==*).tail},^10**.chars)[$_]}

Pruébalo basado 1

Expandido:

{  # bare block lambda with implicit parameter $_

  sort(
    {
      .chars,         # sort by the length first

      (  # generate sequence to find digital sum

        { .comb.sum } # one round of digital sum
         * == *      # stop when the digital sum matches itself (1..9)

      ).tail          # get the last value
    },

    ^                 # Range up to (and excluding)
      10 ** .chars    # the next power of 10

  )[ $_ ] # index into the sequence
}
Brad Gilbert b2gills
fuente
1

Ruby , 43 38 bytes

->x{9*(x%b=10**~-x.to_s.size)+x/b+b-1}

Pruébalo en línea!

Originalmente un puerto de la excelente respuesta de Python por ovs, luego simplificó un poco más.

GB
fuente
1

Java 8, 68 bytes

n->{int b=(int)Math.pow(10,(n+"").length()-1);return~-b+n/b+n%b*9;}

Aburrido puerto de la respuesta Python 2 de @ovs , ¡así que asegúrate de votarlo!
-1 byte gracias a @Jakob

Pruébalo en línea.

Kevin Cruijssen
fuente
1

K4 , 38 bytes

Solución:

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:

Ejemplos:

q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:40
13
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:601
114
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:4051
1462

Explicación:

La solución del puerto de Jonathan Allan cuando me quedo sin memoria construyendo las raíces digitales de 1 a 1e9.

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\: / the solution
                                  10\: / convert to base 10
                                1+     / add 1
                              x:       / save as x
                             #         / take from x
                     (      )          / do together
                          #x           / count x
                        c:             / save as c
                      1+               / add 1
                   1_                  / drop the first
                  _                    / cut at these indices
           ( ;   )                     / 2-item list
              c-1                      / length - 1
            0                          / .. zero
      10/:'                            / convert each from base 10
   9/:                                 / convert from base 9
-1+                                    / subtract 1

Prima:

La traducción de la solución de ovs es más simple pero más larga:

-1+b+/1 9*(_%;.q.mod).\:x,b:10 xexp#1_$x:
callejero
fuente
Se establece explícitamente que: "El código debe funcionar teóricamente para todos los enteros hasta 10 ^ 9 " . Parece que esto no ...?
Stewie Griffin
Urgh Luego usaré una de las respuestas extra ya que me quedaré sin memoria tratando de calcular hasta 10e6 y mucho menos 10e9. Se arreglará más tarde.
StreetSter
0

J, 24 bytes

(]/:([:+/[:".&>":)^:_"0)

Esta expresión tácita está envuelta en parens para indicar que debe tratarse por sí misma en lugar de como parte de cualquier expresión siguiente (como los argumentos).

La frase '] /:' ordena (ascendente '/:') la matriz original ']' por la suma '+ /' de los dígitos La expresión

". &> ":

convierte un número en un vector de caracteres con '":', luego aplica su inverso '".' - carácter a número: aplicado a cada elemento '&>'. Entonces, 65536 -> '65536' -> 6 5 5 3 6.

La conjunción de potencia '^:' cerca del final de la expresión aplica el código que acabamos de explicar (a la izquierda) un número específico de veces. En este caso, el número especificado de veces es infinito '_', lo que significa seguir aplicando hasta que el resultado deje de cambiar.

El '' 0 'final significa aplicar la expresión completa a la izquierda a cada elemento escalar (0-dimensional) a la derecha, que sería la matriz de números a los que queremos aplicar esto.

DevonMcC
fuente
¿Cómo está creando la (s) lista (s) de entrada? Estoy escribiendo una solución en K, pero la mitad de la respuesta es generar las listas ...
streetster
Supuse que las listas se ingresan externamente. No veo dónde crear la lista es parte del problema.
DevonMcC
" Tome un número entero positivo n como entrada , y envíe el enésimo número en la secuencia descrita anteriormente". Debe crear la secuencia (o encontrar una forma de moverse generando la secuencia; vea otras respuestas).
Callejero
0

Elixir , 239 bytes

q=:math
e=Enum
r=fn x,f->cond do
x<10->x
1->f.(e.sum(Integer.digits x),f)end end
fn p->e.at(e.at(Stream.unfold({0,[0]},fn {a,c}->{c,{a+1,c++e.sort(trunc(q.pow 10,a)..trunc(q.pow 10,a+1)-1,&r.(&1,r)<=r.(&2,r))}}end),1+trunc q.log10 p),p)end

Pruébalo en línea!

Explicación entrante (lentamente)! No creo que pueda ser mucho más corto que esto, pero siempre estoy abierto a sugerencias

Dave
fuente
0

Perl 5 -pF , 27 bytes

$_=9x$#F+$_%10**$#F*9+$F[0]

Pruébalo en línea!

Utiliza la fórmula de @ ovs y las explicaciones de @ JonathanAllen para obtener un código compacto y agradable.

Xcali
fuente