Mengembalikan digit ke-n dari urutan seri alikuot


20

0. DEFINISI

Sebuah urutan adalah daftar nomor.
Sebuah seri adalah jumlah daftar nomor.
Himpunan bilangan alami berisi semua "bilangan bulat non-negatif lebih besar dari nol".
Sebuah pembagi (dalam konteks ini) dari nomor alam j adalah nomor alam i , sehingga j ÷ saya juga sejumlah alami.

1. MUNGKIN

Beberapa pertanyaan lain di situs ini menyebutkan konsep alikuot, atau urutan pembagi bilangan asli a yang kurang dari a . Menentukan angka damai melibatkan menghitung jumlah pembagi ini, yang disebut jumlah alikuot atau seri alikuot. Setiap bilangan asli memiliki jumlah alikuotnya sendiri, meskipun nilai jumlah alikuot angka tidak selalu unik untuk angka itu. ( Exempli gratia , setiap bilangan prima memiliki jumlah alikuot 1.)

2. TANTANGAN

Dengan diberi nomor alami n, kembalikan ndigit ke-urutan dari jumlah alikuot. Beberapa seri pertama dalam urutan, dimulai dengan seri untuk 1, adalah:

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

Digabungkan, ini terlihat seperti:

0113161748116110915121122111413661613

Input dapat diindeks nol atau diindeks satu, sesuai dengan preferensi Anda. Solusi harus berupa program atau fungsi yang mampu mengembalikan angka 10.000 (input hingga 9999atau 10000). Solusi kerja terpendek menang.

3. KASUS UJI

Pasangan input-output yang benar harus mencakup, tetapi tidak terbatas pada, hal-hal berikut:

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

Angka sebelum "atau" diindeks 0; nomor berikut adalah 1-diindeks.
Kasus uji tambahan dapat disediakan berdasarkan permintaan.

4. REFERENSI

OEIS memiliki daftar angka dan jumlah alikuotnya.


2
Tantangan pertama yang bagus, btw. :)
Martin Ender

1
jika bahasa tidak dapat mengelola string 10k karakter ?? (misalnya batas Oracle SQL 4k yang mengerikan ) adalah jawabannya valid jika itu adalah batas bahasa?
Giacomo Garabello

@ MartinEnder, terima kasih! Dan terima kasih untuk tautannya; itu mencerahkan. Apakah ada sesuatu di luar sana yang menjelaskan cara memperlakukan jawaban dalam bahasa dengan batasan? Saya tidak dapat menemukan apa pun, tetapi saya tahu itu tidak berarti itu tidak ada di sana. :)
Joe

Saya mungkin benar-benar tebal, tetapi bagaimana angka-angka dalam seri itu dihitung?
Tom Carpenter

@ TomCarpenter: Untuk elemen pertama, ambil semua pembagi 1 yang kurang dari 1, dan tambahkan bersama-sama. (1 adalah satu-satunya pembagi dari 1, jadi elemen pertama berakhir menjadi nol.) Elemen kedua, pembagi 2 yang kurang dari 2 (hanya 1 yang cocok untuk ini); ketiga, pembagi 3 (masih baru 1); dan seterusnya. Pembagi dari 4 adalah {1, 2}, dan 1 + 2 == 3, jadi elemen keempat adalah 3. Butuh waktu lama bagi saya untuk mengetahuinya juga;)
Joe

Jawaban:


6

05AB1E , 14 11 10 byte

Hitung n = 9999 dalam waktu sekitar 15 detik. Kode:

ÌL€Ñ€¨OJ¹è

Penjelasan:

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

Menggunakan pengkodean CP-1252 . Cobalah online! .


6

Mathematica, 51 byte

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

Fungsi tanpa nama yang mengambil dan mengembalikan integer dan menggunakan pengindeksan berbasis 1. Menangani input secara 10000instan.

Penjelasan

Ini adalah implementasi definisi yang sangat mudah, memanfaatkan fakta bahwa njumlah pembagi pertama selalu cukup untuk menentukan ndigit ke-4. Seperti biasa, urutan bacaan Mathematica golf agak lucu:

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

Ini menghasilkan daftar dengan semua hasil penerapan fungsi yang tidak disebutkan namanya di sebelah kiri untuk semua nilai i dari 1hingga ninklusif.

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

Kita mulai dengan menghitung pembagi i, menjumlahkannya dengan Trdan mengurangii sendiri sehingga hanya jumlah pembagi yang kurang dari i.

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

Ini mengubah hasilnya menjadi daftar angka desimalnya.

##&@@...

Dan ini menghilangkan kepala "daftar", sehingga semua daftar digit secara otomatis digabungkan dalam hasil Array. Untuk detail lebih lanjut tentang cara ##kerjanya, lihat bagian "Urutan argumen" di posting ini .

...[[#]]

Akhirnya, kami memilih ndigit th dari hasilnya.


4

Brachylog , 40 byte

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

Ini 1-diindeks, membutuhkan sekitar 0,15 detik untuk N = 100, 15 detik untuk N = 1000. Saat ini saya sedang menjalankan N = 10000, saya akan melaporkan waktu berjalan setelah berakhir (Jika perkiraan saya benar, ini akan memakan waktu sekitar 8 jam)

Sunting : dengan memperbaiki propagasi kendala prematur di Brachylog, sekarang (pada kode 3 byte lebih lama) membutuhkan waktu 2.5beberapa menit untuk 10000tetapi mengembalikan out of global stackkesalahan.

Penjelasan

  • Predikat Utama: 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
    
  • Predikat 1: menghitung jumlah pembagi

    :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
    
  • Predikat 2: menyatukan output dengan pembagi input

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

1
Anda dapat mengalokasikan lebih banyak tumpukan global dengan -Gopsi. Standarnya hanya 128M. Anda dapat menggunakan misalnya: swipl -G2Guntuk menggunakan 2 GO.
mat

4

Pyth, 26 21 20 15 byte

@sm`sf!%dTtUdSh

Cobalah online. Suite uji.

Menggunakan pengindeksan berbasis 0. Program ini O (n²) dan selesai untuk n = 9999 dalam waktu sekitar 14 menit pada mesin 2008 saya.


Ada apa dengan pencarian pembagi rumit itu? f!%dTr1djauh lebih pendek (tetapi juga lebih lambat)
Jakube

@Jakube whoops, memodifikasi versi yang salah untuk solusi 20 byte.
PurkkaKoodari

f!%TYtUTadalah apa yang saya miliki.
PurkkaKoodari

@ Jakube saya berubah menjadi itu. Ini masih berjalan untuk n = 9999, sudah lebih dari 5 menit sekarang: \
PurkkaKoodari

4

Jelly, 13 11 10 byte

2 byte berkat @Adnan dan 1 lagi berkat @Dennis.

ÆDṖSDµ€Fị@

Cobalah online!

Menggunakan pengindeksan berbasis 1. Selesaikan untuk n = 10.000 dalam waktu kurang dari 2 detik online.


ÆDṖSDµ€Fị@menghemat satu byte.
Dennis

@ Dennis, jadi apakah itu berlaku untuk seluruh rantai pertama?
PurkkaKoodari

@ Pietu1998: Ya, tepatnya: secara umum, pada waktu parse, diterapkan chain.pop() if chain else chains.pop(). Rantai yang baru mulai kosong, jadi rantai yang terakhir selesai digunakan sebagai gantinya.
Lynn

3

PHP, 90 byte

0 diindeks

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

Sama sekali tidak halus atau dengan cara yang pintar mendekati itu sama sekali.
Juga, seperti biasa, menghasilkan tiga pemberitahuan yang diabaikan.


3

J , 34 byte

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

Ini adalah indeks-nol dan menggunakan rumus di bawah ini untuk menghitung jumlah pembagi.

Rumus

Penjelasan

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

Pengindeksan adalah berbasis 1.

Kasing uji terakhir kali habis dalam kompiler online, tetapi hasilnya memberikan hasil yang benar dengan kompiler offline, dalam waktu sekitar 15 detik.

Cobalah 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])!!)

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

Ini adalah implementasi langsung dari definisi: foreach nsum pembagi itu dan mengubahnya menjadi string. Gabungkan semua string tersebut dan pilih elemen pada indeks yang diminta. Kemalasan Haskell hanya mengambil sebanyak ndari daftar yang tak terbatas [1..]sesuai kebutuhan.


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]

Implementasi metode yang cukup mudah dijelaskan dalam posting.

Cobalah secara Online! (Ideone)

Tidak cukup selesai dalam 5 detik yang dialokasikan dalam kompiler online untuk input 10000, tetapi selesai pada mesin saya untuk input yang sama dalam waktu sekitar 8,5 detik.


1

Oktaf, 71 byte

Yang ini hanya oktaf. Ini tidak akan berfungsi di MATLAB. Fungsi virtual dibuat yang berfungsi pada angka 1-diindeks. Ini mungkin dapat disederhanakan sedikit lebih jauh. Akan lihat malam ini.

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

Anda dapat mencoba online di sini .

Cukup jalankan perintah di atas, diawali dengan a=atau apa pun (hanya agar Anda dapat menggunakannya beberapa kali), lalu lakukan a(10000)atau apa pun. Diperlukan sekitar 7 detik untuk menghitung bahwa angka ke-10.000 adalah angka 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);}

Yah, setidaknya cepat. Rata-rata 0,3 detik untuk mendapatkan elemen 9999 / 10.000 di mesin saya. Ini hanya menghasilkan jumlah alikuot sebanyak indeks yang Anda tentukan. Ini berarti string akan sedikit lebih panjang daripada indeks Anda dalam kebanyakan kasus, karena beberapa jumlah alikuot memiliki 2 digit atau lebih, tetapi untuk sebagian besar, string hanya menghasilkan string sepanjang yang kami butuhkan.

Pemakaian:

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

Tidak Terkumpul:

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);
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.