Devuelve el enésimo dígito de la secuencia de series alícuotas

20

0. DEFINICIONES

Una secuencia es una lista de números.
Una serie es la suma de una lista de números.
El conjunto de números naturales contiene todos los "enteros no negativos mayores que cero".
Un divisor (en este contexto) de un número natural j es un número natural i , de modo que j ÷ i también es un número natural.

1. PREÁMBULO

Un par de otras preguntas en este sitio mencionan el concepto de la parte alícuota, o la secuencia de divisores de un número natural a que son menores que a . Determinar números amistosos implica calcular la suma de estos divisores, llamada suma alícuota o serie alícuota. Cada número natural tiene su propia suma alícuota, aunque el valor de la suma alícuota de un número no es necesariamente exclusivo de ese número. ( Exempli gratia , cada número primo tiene una suma alícuota de 1.)

2. DESAFÍO

Dado un número natural n, devuelve el ndígito th de la secuencia de sumas alícuotas. Las primeras series de la secuencia, comenzando con la serie para 1, son:

{0, 1, 1, 3, 1, 6, 1, 7, 4, 8, 1, 16, 1, 10, 9, 15, 1, 21, 1, 22, 11, 14, 1, 36, 6, 16, 13}

Concatenados, estos se ven así:

0113161748116110915121122111413661613

La entrada puede estar indexada a cero o indexada, según su preferencia. Las soluciones deben ser programas o funciones capaces de devolver el dígito 10.000 (entrada hasta 9999o 10000). La solución de trabajo más corta gana.

3. CASOS DE PRUEBA

Los pares de entrada-salida correctos deben incluir, entre otros, los siguientes:

   0 or     1    ->    0
   4 or     5    ->    1
  12 or    13    ->    6
9999 or 10000    ->    7

El número que precede a "o" está indexado en 0; el siguiente número es 1 indexado.
Se pueden proporcionar casos de prueba adicionales a pedido.

4. REFERENCIAS

OEIS tiene una lista de números y sus sumas alícuotas.

Joe
fuente
2
Bonito primer desafío, por cierto. :)
Martin Ender
1
si el idioma no puede manejar cadenas de caracteres 10k? (por ejemplo, el horrible límite de Oracle SQL 4k ) ¿es válida la respuesta si es el límite de idioma?
Giacomo Garabello
@MartinEnder, gracias! Y gracias por ese enlace; Fue esclarecedor. ¿Hay algo por ahí que explique cómo tratar las respuestas en idiomas con limitaciones? No pude encontrar nada, pero sé que eso no significa que no esté allí. :)
Joe
Puede que esté siendo completamente grueso, pero ¿cómo se calculan los números en esa serie?
Tom Carpenter
@TomCarpenter: Para el primer elemento, tome todos los divisores de 1 que sean menores que 1 y agréguelos. (1 es el único divisor de 1, por lo que el primer elemento termina siendo cero). Segundo elemento, los divisores de 2 que son menores que 2 (solo 1 se ajusta a esto); tercero, divisores de 3 (todavía solo 1); y así. Los divisores de 4 son {1, 2} y 1 + 2 == 3, por lo que el cuarto elemento es 3. Me tomó un tiempo descubrirlo también;)
Joe

Respuestas:

6

05AB1E , 14 11 10 bytes

Calcule n = 9999 en aproximadamente 15 segundos. Código:

ÌL€Ñ€¨OJ¹è

Explicación:

Ì           # Increment implicit input by 2
 L          # Generate the list [1 .. input + 2]
  ۄ        # For each, get the divisors
    ۬      # For each, pop the last one out
      O     # Sum all the arrays in the array
       J    # Join them all together
        ¹è  # Get the nth element

Utiliza la codificación CP-1252 . Pruébalo en línea! .

Adnan
fuente
6

Mathematica, 51 bytes

Array[##&@@IntegerDigits[Tr@Divisors@#-#]&,#][[#]]&

Una función sin nombre que toma y devuelve un entero y usa indexación basada en 1. Maneja la entrada al 10000instante.

Explicación

Esta es una implementación muy directa de la definición, haciendo uso del hecho de que las nsumas del primer divisor siempre son suficientes para determinar el ndígito th. Como de costumbre, el orden de lectura de Mathematica golf es un poco divertido:

Array[...&,#]...&

Esto genera una lista con todos los resultados de aplicar la función sin nombre a la izquierda a todos los valores idesde 1hasta ninclusive.

...Tr@Divisors@#-#...

Comenzamos calculando los divisores de i, sumando Try restando ipara que sea solo la suma de divisores menor que i.

...IntegerDigits[...]...

Esto convierte el resultado en una lista de sus dígitos decimales.

##&@@...

Y esto elimina el encabezado de "lista", de modo que todas las listas de dígitos se concatenan automáticamente en el resultado de Array. Para obtener más detalles sobre cómo ##funciona, consulte la sección "Secuencias de argumentos" en esta publicación .

...[[#]]

Finalmente, seleccionamos el ndígito th del resultado.

Martin Ender
fuente
4

Brachylog , 40 bytes

:2-I,?:?:1yrc:Im.;0.
:1e:2f+.
>.>0,?:.%0

Esto está indexado en 1, toma alrededor de 0,15 segundos para N = 100, 15 segundos para N = 1000. Actualmente me estoy postulando N = 10000, informaré el tiempo de ejecución una vez que finalice (si mi estimación es correcta, debería tomar alrededor de 8 horas)

Editar : arreglando la propagación de restricciones prematuras en Brachylog, ahora (en un código de 3 bytes más largo) tarda unos 2.5minutos 10000pero devuelve un out of global stackerror.

Explicación

  • Predicado principal: Input = N

    :2-I,                 I = N - 2
         ?:?:1y           Find the N first valid outputs of predicate 1 with input N
               rc         Reverse and concatenate into a single number
                 :Im.     Output is the Ith digit of that number
                     ;    Or (I strictly less than 0)
                      0.  Output is 0
    
  • Predicado 1: calcula la suma de los divisores

    :1e                   Get a number between N and 1
       :2f                Find all valid outputs of predicate 2 with that number as input
          +.              Output is the sum of those outputs
    
  • Predicado 2: unifica la salida con un divisor de la entrada

    >.>0,                 Output is a number between Input and 0
         ?:.%0            Input is divisible by Output
    
Fatalizar
fuente
1
Puede asignar más pila global con la -Gopción. El valor predeterminado es solo 128M. Puede usar, por ejemplo: swipl -G2Gpara usar 2 GO.
mat
4

Pyth, 26 21 20 15 bytes

@sm`sf!%dTtUdSh

Pruébalo en línea. Banco de pruebas.

Utiliza indexación basada en 0. El programa es O (n²) y se completa para n = 9999 en aproximadamente 14 minutos en mi máquina 2008.

PurkkaKoodari
fuente
¿Qué pasa con esa complicada búsqueda de divisores? f!%dTr1des mucho más corto (pero también más lento)
Jakube
@Jakube whoops, modificó la versión incorrecta para la solución de 20 bytes.
PurkkaKoodari
f!%TYtUTes lo que solía tener
PurkkaKoodari
@Jakube Cambié a eso. Todavía se está ejecutando para n = 9999, han pasado más de 5 minutos ahora: \
PurkkaKoodari
4

Jalea, 13 11 10 bytes

2 bytes gracias a @Adnan y 1 más gracias a @Dennis.

ÆDṖSDµ€Fị@

Pruébalo en línea!

Utiliza indexación basada en 1. Completa para n = 10000 en menos de 2 segundos en línea.

PurkkaKoodari
fuente
ÆDṖSDµ€Fị@Guarda un byte.
Dennis
@Dennis, ¿se aplica eso a toda la primera cadena?
PurkkaKoodari
@ Pietu1998: Sí, precisamente: en general, en tiempo de análisis, se aplica a chain.pop() if chain else chains.pop(). La cadena recién iniciada está vacía, por lo que se utiliza la última cadena terminada.
Lynn
3

PHP, 90 bytes

0 indexado

<?php for(;strlen($s)<=$a=$argv[1];$s.=$n)for($n=0,$j=++$i;--$j;)$i%$j||$n+=$j;echo$s[$a];

Absolutamente no sutil o con una forma inteligente de abordarlo.
Además, como de costumbre, produce tres avisos que se ignoran.

usuario55641
fuente
3

J , 34 bytes

{[:;1<@":@(-~>:@#.~/.~&.q:)@+i.@>:

Esto está indexado a cero y utiliza la siguiente fórmula para calcular las sumas de divisores.

Fórmula

Explicación

{[:;1<@":@(-~>:@#.~/.~&.q:)@+i.@>:  Input: n
                                >:  Increment n
                             i.@    Create the range [0, 1, ..., n]
    1                       +       Add one to each to get [1, 2, ..., n+1]
          (               )@        For each value
                        q:            Get the prime factors
                   /.~&.              For each group of equal prime factors
                #.~                     Raise the first to the first power, the second
                                        squared and so on, and sum them
             >:@                        Increment that sum
                      &.q:            Reduce the groups using multiplication
           -~                         Subtract the initial value from that sum
       ":@                            Convert each to a string
     <@                               Box each
 [:;                                Unbox each and concatenate the strings
{                                   Select the character from that string at index n
                                    and return it
millas
fuente
2

MATL , 16 15 bytes

:"@@q:\~fsV]vG)

La indexación se basa en 1.

El último caso de prueba expira en el compilador en línea, pero da el resultado correcto con el compilador fuera de línea, en aproximadamente 15 segundos.

Pruébalo en línea!

:         % Take input n. Push [1 2 ... n]
"         % For each k in [1 2 ... n]
  @       %   Push k
  @q:     %   Push [1 2 ... k-1]
  \       %   Modulo. Zero values correspond to divisors
  ~f      %   Indices of zeros. These are the divisors
  s       %   Sum
  V       %   Convert to string
]         % End for each
v         % Concatenate all stack contents vertically
G)        % Take n-th digit. Implicitly display
Luis Mendo
fuente
2

Haskell, 52 bytes

(([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!)

Ejemplo de uso: (([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!) 12-> 6.

Es una implementación directa de la definición: foreach nsuma sus divisores y los convierte en una cadena. Concatene todas esas cadenas y elija el elemento en el índice solicitado. La holgazanería de Haskell solo toma tantos ns de la lista infinita [1..]como sea necesario.

nimi
fuente
1

Python 3.5, 103 93 92 bytes:

R=range;A=lambda f:''.join([str(sum([j for j in R(1,i)if i/j%1==0]))for i in R(1,f+1)])[f-1]

Implementación bastante sencilla del método descrito en la publicación.

¡Pruébelo en línea! (Ideone)

No termina dentro de los 5 segundos asignados en el compilador en línea para la entrada 10000, pero termina en mi máquina para la misma entrada en aproximadamente 8,5 segundos.

R. Kap
fuente
1

Octava, 71 bytes

Este es solo Octave. No funcionará en MATLAB. Se crea una función virtual que funciona en números indexados 1. Probablemente se pueda simplificar un poco más. Echaré un vistazo esta noche.

@(x)c((c=num2str(arrayfun(@(n)sum(b(~rem(n,b=(1:n-1)))),1:x)))~=' ')(x)

Puedes probar en línea aquí .

Simplemente ejecute el comando anterior, con el prefijo a=o lo que sea (solo para que pueda usarlo varias veces), y luego haga a(10000)o lo que sea. Se tarda unos 7 segundos en calcular que el dígito 10000 es un 7.

Tom Carpenter
fuente
1

Java 8, 220 bytes

import java.util.stream.IntStream;
char a(int n){return IntStream.range(1,n+2).map(i->IntStream.range(1,i).filter(k->i%k==0).sum()).mapToObj(Integer::toString).collect(java.util.stream.Collectors.joining("")).charAt(n);}

Bueno, al menos es rápido. El promedio de 0.3 segundos para obtener el elemento 9999/10000 en mi máquina. Solo genera tantas sumas de alícuotas como el índice que especificó. Esto significa que la cadena será un poco más larga que su índice en la mayoría de los casos, ya que algunas sumas de alícuotas tienen 2 o más dígitos, pero en su mayor parte, solo genera una cadena tan larga como la que necesitamos.

Uso:

public static void main(String[] args) {
    System.out.println(a(0));
    System.out.println(a(4));
    System.out.println(a(12));
    System.out.println(a(9999));
}

Sin golf:

public static void main(String[] args) {
    System.out.println(all(0));
    System.out.println(all(4));
    System.out.println(all(12));
    System.out.println(all(9999));
}

static int aliquotSum(int n) {
    return IntStream.range(1, n).filter(k -> n % k == 0).sum();
}

static IntStream sums(int n) {
    return IntStream.range(1, n + 2).map(i -> aliquotSum(i));
}

static String arraycat(IntStream a) {
    return a.mapToObj(Integer::toString).collect(java.util.stream.Collectors.joining(""));
}

static char all(int index) {
    return arraycat(sums(index)).charAt(index);
}
Justin
fuente