Restituisce l'ennesima cifra della sequenza delle serie di aliquote


20

0. DEFINIZIONI

Una sequenza è un elenco di numeri.
Una serie è la somma di un elenco di numeri.
L'insieme dei numeri naturali contiene tutti "numeri interi non negativi maggiori di zero".
Un divisore (in questo contesto) di un numero naturale j è un numero naturale i , tale che j ÷ i è anche un numero naturale.

1. PREAMBOLO

Un paio di altre domande su questo sito parlare del concetto di aliquota, o la sequenza di divisori di un numero naturale di una , che sono meno di una . Determinare numeri amichevoli implica calcolare la somma di questi divisori, chiamata somma aliquota o serie aliquota. Ogni numero naturale ha la sua somma aliquota, sebbene il valore della somma aliquota di un numero non sia necessariamente univoco per quel numero. ( Exempli gratia , ogni numero primo ha una somma aliquota di 1.)

2. SFIDA

Dato un numero naturale n, restituisce la nth cifra della sequenza di somme aliquote. Le prime diverse serie della sequenza, a partire dalla serie per 1, sono:

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

Concatenati, questi assomigliano a:

0113161748116110915121122111413661613

L'input può essere indicizzato zero o indicizzato uno, in base alle proprie preferenze. Le soluzioni devono essere programmi o funzioni in grado di restituire la 10.000a cifra (input fino a 9999o 10000). Vince la soluzione di lavoro più breve.

3. CASI DI PROVA

Le coppie input-output corrette dovrebbero includere, ma non sono limitate a, le seguenti:

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

Il numero che precede "o" è indicizzato 0; il numero seguente è 1 indicizzato.
Ulteriori casi di test possono essere forniti su richiesta.

4. RIFERIMENTI

OEIS ha un elenco di numeri e le loro somme aliquote.


2
Bella prima sfida, a proposito. :)
Martin Ender,

1
se la lingua non riesce a gestire stringhe di caratteri 10k ?? (ad esempio il terribile limite di Oracle SQL 4k ) la risposta è valida se è il limite di lingua?
Giacomo Garabello,

@MartinEnder, grazie! E grazie per quel link; era illuminante. C'è qualcosa là fuori che spiega come trattare le risposte in lingue con limitazioni? Non sono riuscito a trovare nulla, ma so che ciò non significa che non sia lì. :)
Joe,

Potrei essere completamente denso, ma come vengono calcolati i numeri in quella serie?
Tom Carpenter,

@TomCarpenter: per il primo elemento, prendi tutti i divisori di 1 che sono meno di 1 e sommali. (1 è l'unico divisore di 1, quindi il primo elemento finisce per essere zero.) Secondo elemento, i divisori di 2 che sono inferiori a 2 (solo 1 corrisponde a questo); terzo, divisori di 3 (ancora solo 1); e così via. I divisori di 4 sono {1, 2} e 1 + 2 == 3, quindi il quarto elemento è 3. Mi ci è voluto un po 'di tempo per capirlo;)
Joe

Risposte:


6

05AB1E , 14 11 10 byte

Calcola n = 9999 in circa 15 secondi. Codice:

ÌL€Ñ€¨OJ¹è

Spiegazione:

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

Utilizza la codifica CP-1252 . Provalo online! .


6

Mathematica, 51 byte

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

Una funzione senza nome che accetta e restituisce un numero intero e utilizza l'indicizzazione basata su 1. Gestisce l'input 10000all'istante.

Spiegazione

Questa è un'implementazione molto diretta della definizione, facendo uso del fatto che le nsomme del primo divisore sono sempre sufficienti per determinare la ncifra th. Come al solito, l'ordine di lettura di Mathematica golf è un po 'divertente però:

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

Questo genera un elenco con tutti i risultati dell'applicazione della funzione senza nome sulla sinistra a tutti i valori ida 1al ncompreso.

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

Iniziamo calcolando i divisori di i , sommandoli Tre sottraendo ise stessi in modo che sia solo la somma dei divisori inferiore i.

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

Ciò trasforma il risultato in un elenco delle sue cifre decimali.

##&@@...

E questo rimuove la testa "list", in modo che tutti gli elenchi di cifre vengano automaticamente concatenati nel risultato di Array . Per maggiori dettagli su come ##funziona, vedere la sezione "Sequenze di argomenti" in questo post .

...[[#]]

Infine, selezioniamo il n cifra th dal risultato.


4

Brachylog , 40 byte

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

Questo è 1-indicizzato, richiede circa 0,15 secondi per N = 100, 15 secondi per N = 1000. Attualmente sto correndoN = 10000 , segnalerò il tempo di esecuzione una volta terminato (se la mia stima è corretta, dovrebbero essere necessarie circa 8 ore)

Modifica : correggendo la propagazione prematura dei vincoli in Brachylog, ora (su un codice più lungo di 3 byte) occorrono circa 2.5minuti per10000 ma restituisce un out of global stackerrore.

Spiegazione

  • Predicato principale: 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
    
  • Predicato 1: calcola la somma dei divisori

    :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
    
  • Predicato 2: unifica l'output con un divisore dell'input

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

1
È possibile allocare più stack globali con l' -Gopzione. L'impostazione predefinita è solo 128M. Ad esempio puoi usare: swipl -G2Gper usare 2 GO.
mat

4

Pyth, 26 21 20 15 byte

@sm`sf!%dTtUdSh

Provalo online. Suite di test.

Utilizza l'indicizzazione basata su 0. Il programma è O (n²) e si completa per n = 9999 in circa 14 minuti sulla mia macchina del 2008.


Che succede con quella complicata ricerca di divisori? f!%dTr1dè molto più breve (ma anche più lento)
Jakube,

@Jakube whoops, ha modificato la versione errata per la soluzione a 20 byte.
PurkkaKoodari,

f!%TYtUTè quello che avevo.
PurkkaKoodari,

@Jakube L'ho cambiato. Funziona ancora per n = 9999, sono passati più di 5 minuti: \
PurkkaKoodari

4

Gelatina, 13 11 10 byte

2 byte grazie a @Adnan e 1 altro grazie a @Dennis.

ÆDṖSDµ€Fị@

Provalo online!

Utilizza l'indicizzazione basata su 1. Completa per n = 10000 in meno di 2 secondi online.


ÆDṖSDµ€Fị@salva un byte.
Dennis,

@Dennis, questo vale per l'intera prima catena?
PurkkaKoodari,

@ Pietu1998: Sì, precisamente: in generale, al momento dell'analisi, viene applicato chain.pop() if chain else chains.pop(). La catena appena avviata è vuota, quindi viene utilizzata l'ultima catena finita.
Lynn,

3

PHP, 90 byte

0 indicizzato

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

Assolutamente non sottile o con un modo intelligente di affrontarlo.
Inoltre, come al solito, produce tre avvisi che vengono ignorati.


3

J , 34 byte

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

Questo è indicizzato a zero e utilizza la formula seguente per calcolare le somme dei divisori.

Formula

Spiegazione

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

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

L'indicizzazione è basata su 1.

L'ultimo caso di test scade nel compilatore online, ma fornisce il risultato corretto con il compilatore offline, in circa 15 secondi.

Provalo online!

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

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

Esempio di utilizzo: (([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!) 12->6 .

È un'implementazione diretta della definizione: foreach nsum è divisori e convertilo in una stringa. Concatena tutte queste stringhe e seleziona l'elemento nell'indice richiesto. La pigrizia di Haskell prende solo quante più ns dall'elenco infinito, [1..]se necessario.


1

Python 3.5, 103 93 92 byte:

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]

Implementazione piuttosto semplice del metodo descritto in post.

Provalo online! (Ideone)

Non termina completamente entro i 5 secondi assegnati nel compilatore online per l'input 10000, ma termina sulla mia macchina per lo stesso input in circa 8,5 secondi.


1

Ottava, 71 byte

Questo è solo Octave. Non funzionerà in MATLAB. Viene creata una funzione virtuale che funziona su numeri con 1 indice. Probabilmente può essere ulteriormente semplificato. Daremo un'occhiata stasera.

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

Puoi provare online qui .

Basta eseguire il comando sopra, con il prefisso a=o qualsiasi altra cosa (solo per poterlo utilizzare più volte), quindi fare a(10000)o altro. Sono necessari circa 7 secondi per calcolare che la 10000a cifra è un 7.


1

Java 8, 220 byte

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

Beh, almeno è veloce. Sono in media 0,3 secondi per ottenere l'elemento 9999 / 10000th sulla mia macchina. Genera solo un numero di aliquote pari all'indice specificato. Ciò significa che la stringa sarà leggermente più lunga del tuo indice nella maggior parte dei casi, poiché alcune somme aliquote hanno 2 o più cifre, ma per la maggior parte genera solo una stringa di cui abbiamo bisogno.

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

Ungolfed:

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.