Renvoie le nième chiffre de la séquence de séries d'aliquotes


20

0. DÉFINITIONS

Une séquence est une liste de nombres.
Une série est la somme d'une liste de nombres.
L'ensemble des nombres naturels contient tous les «entiers non négatifs supérieurs à zéro».
Un diviseur (dans ce contexte) d'un nombre naturel j est un nombre naturel i , tel que j ÷ i est également un nombre naturel.

1. PRÉAMBULE

Quelques autres questions sur ce site mentionnent le concept de l'aliquote, ou la séquence de diviseurs d'un nombre naturel a qui sont inférieurs à a . La détermination des nombres amiables implique le calcul de la somme de ces diviseurs, appelée somme aliquote ou série aliquote. Chaque nombre naturel a sa propre somme aliquote, bien que la valeur de la somme aliquote d'un nombre ne soit pas nécessairement unique à ce nombre. ( Exempli gratia , chaque nombre premier a une somme aliquote de 1.)

2. DÉFI

Étant donné un nombre naturel n, renvoyez le nième chiffre de la séquence de sommes aliquotes. Les premières séries de la séquence, en commençant par la série pour 1, sont:

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

Concaténés, ils ressemblent à:

0113161748116110915121122111413661613

L'entrée peut être indexée zéro ou un indexée, selon votre préférence. Les solutions doivent être des programmes ou des fonctions capables de renvoyer le 10 000e chiffre (entrée jusqu'à 9999ou 10000). La solution de travail la plus courte l'emporte.

3. CAS D'ESSAI

Les paires d'entrée-sortie correctes doivent inclure, mais sans s'y limiter, les éléments suivants:

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

Le nombre précédant le "ou" est indexé sur 0; le nombre suivant est indexé sur 1.
Des cas de test supplémentaires peuvent être fournis sur demande.

4. RÉFÉRENCES

OEIS a une liste de nombres et leurs sommes aliquotes.


2
Joli premier défi, btw. :)
Martin Ender

1
si la langue ne peut pas gérer les chaînes de caractères 10k ?? (par exemple, la terrible limite Oracle SQL 4k ) la réponse est-elle valable s'il s'agit de la limite de langue?
Giacomo Garabello

@MartinEnder, merci! Et merci pour ce lien; c'était instructif. Y a-t-il quelque chose qui explique comment traiter les réponses dans des langues avec des limitations? Je n'ai rien trouvé, mais je sais que cela ne veut pas dire que ce n'est pas là. :)
Joe

Je suis peut-être complètement épaisse, mais comment les nombres de cette série sont-ils calculés?
Tom Carpenter

@TomCarpenter: Pour le premier élément, prenez tous les diviseurs de 1 inférieurs à 1 et ajoutez-les ensemble. (1 est le seul diviseur de 1, donc le premier élément finit par être zéro.) Deuxième élément, les diviseurs de 2 qui sont inférieurs à 2 (seulement 1 correspond à cela); troisièmement, des diviseurs de 3 (toujours juste 1); etc. Les diviseurs de 4 sont {1, 2} et 1 + 2 == 3, donc le quatrième élément est 3. Il m'a fallu un certain temps pour le comprendre aussi;)
Joe

Réponses:


6

05AB1E , 14 11 10 octets

Calculez n = 9999 en 15 secondes environ. Code:

ÌL€Ñ€¨OJ¹è

Explication:

Ì           # 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

Utilise l' encodage CP-1252 . Essayez-le en ligne! .


6

Mathematica, 51 octets

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

Une fonction sans nom qui prend et renvoie un entier et utilise une indexation basée sur 1. Gère l'entrée 10000instantanément.

Explication

Il s'agit d'une mise en œuvre très simple de la définition, utilisant le fait que les premières nsommes de diviseur sont toujours suffisantes pour déterminer le ne chiffre. Comme d'habitude, l'ordre de lecture de Mathematica au golf est un peu drôle cependant:

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

Cela génère une liste avec tous les résultats de l'application de la fonction sans nom à gauche à toutes les valeurs ide 1à ninclus.

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

Nous commençons par calculer les diviseurs de i, en les additionnant Tret en se soustrayant ipour que ce soit juste la somme des diviseurs inférieure à i.

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

Cela transforme le résultat en une liste de ses chiffres décimaux.

##&@@...

Et cela supprime la tête "liste", de sorte que toutes les listes de chiffres sont automatiquement concaténées dans le résultat de Array. Pour plus de détails sur le ##fonctionnement, consultez la section "Séquences d'arguments" dans ce post .

...[[#]]

Enfin, nous sélectionnons le ne chiffre dans le résultat.


4

Brachylog , 40 octets

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

Ceci est indexé sur 1, prend environ 0,15 seconde pour N = 100, 15 secondes pour N = 1000. Je cours actuellement N = 10000, je signalerai le temps d'exécution une fois qu'il sera terminé (si mon estimation est correcte, cela devrait prendre environ 8 heures)

Edit : en corrigeant la propagation prématurée des contraintes dans Brachylog, cela prend maintenant (sur un code plus long de 3 octets) environ 2.5quelques minutes 10000mais renvoie une out of global stackerreur.

Explication

  • Prédicat 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
    
  • Prédicat 1: calcule la somme des diviseurs

    :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
    
  • Prédicat 2: unifie la sortie avec un diviseur de l'entrée

    >.>0,                 Output is a number between Input and 0
         ?:.%0            Input is divisible by Output
    

1
Vous pouvez allouer plus de pile globale avec l' -Goption. La valeur par défaut est uniquement 128M. Vous pouvez utiliser par exemple: swipl -G2Gpour utiliser 2 GO.
mat

4

Pyth, 26 21 20 15 octets

@sm`sf!%dTtUdSh

Essayez-le en ligne. Suite de tests.

Utilise l'indexation basée sur 0. Le programme est O (n²) et se termine pour n = 9999 en environ 14 minutes sur ma machine 2008.


Que se passe-t-il avec cette recherche compliquée de diviseurs? f!%dTr1dest beaucoup plus court (mais aussi plus lent)
Jakube

@Jakube whoops, a modifié la mauvaise version de la solution à 20 octets.
PurkkaKoodari

f!%TYtUTc'est ce que j'avais.
PurkkaKoodari

@Jakube J'ai changé pour ça. Il fonctionne toujours pour n = 9999, depuis plus de 5 minutes maintenant: \
PurkkaKoodari

4

Gelée, 13 11 10 octets

2 octets grâce à @Adnan et 1 de plus grâce à @Dennis.

ÆDṖSDµ€Fị@

Essayez-le en ligne!

Utilise l'indexation basée sur 1. Se termine pour n = 10000 en moins de 2 secondes en ligne.


ÆDṖSDµ€Fị@enregistre un octet.
Dennis

@Dennis, cela s'applique-t-il à l'ensemble de la première chaîne?
PurkkaKoodari

@ Pietu1998: Oui, précisément: en général, au moment de l'analyse, est appliqué à chain.pop() if chain else chains.pop(). La chaîne nouvellement démarrée est vide, donc la dernière chaîne terminée est utilisée à la place.
Lynn

3

PHP, 90 octets

0 indexé

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

Absolument pas subtile ou avec une façon intelligente de l'aborder.
De plus, comme d'habitude, produit trois avis qui sont ignorés.


3

J , 34 octets

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

Il est indexé sur zéro et utilise la formule ci-dessous pour calculer les sommes du diviseur.

Formule

Explication

{[:;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

2

MATL , 16 15 octets

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

L'indexation est basée sur 1.

Le dernier cas de test expire dans le compilateur en ligne, mais il donne le résultat correct avec le compilateur hors ligne, dans environ 15 secondes.

Essayez-le en ligne!

:         % 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

2

Haskell, 52 octets

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

Exemple d'utilisation: (([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!) 12->6 .

C'est une implémentation directe de la définition: pour chaque nsomme, il s'agit de diviseurs et convertissez-la en chaîne. Concatène toutes ces chaînes et sélectionne l'élément à l'index demandé. La paresse de Haskell ne prend que autant de ns de la liste infinie [1..]que nécessaire.


1

Python 3.5, 103 93 92 octets:

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]

Implémentation assez simple de la méthode décrite dans l'article.

Essayez-le en ligne! (Ideone)

Ne se termine pas tout à fait dans les 5 secondes allouées dans le compilateur en ligne pour l'entrée 10000, mais il se termine sur ma machine pour la même entrée dans environ 8,5 secondes.


1

Octave, 71 octets

Celui-ci est uniquement Octave. Cela ne fonctionnera pas dans MATLAB. Une fonction virtuelle est créée qui fonctionne sur des nombres indexés 1. Cela peut probablement être simplifié un peu plus. Va voir ce soir.

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

Vous pouvez essayer en ligne ici .

Exécutez simplement la commande ci-dessus, préfixée avec a=ou autre (juste pour que vous puissiez l'utiliser plusieurs fois), puis faites a(10000)ou quoi que ce soit. Il faut environ 7 secondes pour calculer que le 10000ème chiffre est un 7.


1

Java 8, 220 octets

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

Eh bien, c'est rapide au moins. Il faut en moyenne 0,3 seconde pour obtenir l'élément 9999 / 10000e sur ma machine. Il génère uniquement autant de sommes aliquotes que l'index que vous avez spécifié. Cela signifie que la chaîne sera légèrement plus longue que votre index dans la plupart des cas, car certaines sommes aliquotes ont 2 chiffres ou plus, mais pour la plupart, elles ne génèrent que la longueur d'une chaîne dont nous avons besoin.

Usage:

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

Non 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);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.