Twist dari urutan sepele

15

pengantar

Pertimbangkan urutan bilangan bulat f yang didefinisikan sebagai berikut:

  1. f (2) = 2
  2. Jika n adalah prime yang aneh, maka f (n) = (f (n-1) + f (n + 1)) / 2
  3. Jika n = p · q adalah komposit, maka f (n) = f (p) · f (q)

Tidak terlalu sulit untuk melihat bahwa f (n) = n untuk setiap n ≥ 2 , dan dengan demikian menghitung f tidak akan menjadi tantangan yang sangat menarik. Mari kita memutar definisi: membagi dua case pertama dan menggandakan case kedua. Kami mendapatkan urutan baru g yang didefinisikan sebagai berikut:

  1. g (2) = 1
  2. Jika n adalah prime yang aneh, maka g (n) = g (n-1) + g (n + 1)
  3. Jika n = p · q adalah komposit, maka g (n) = g (p) · g (q)

Tugas

Tugas Anda adalah mengambil integer n ≥ 2 sebagai input, dan menghasilkan g (n) sebagai output. Anda tidak perlu khawatir tentang integer overflow, tetapi Anda harus dapat menghitung g (1025) = 81 dengan benar, dan algoritme Anda seharusnya bekerja secara teoritis untuk input besar yang sewenang-wenang.

Anda dapat menulis program atau fungsi lengkap. Hitungan byte terendah menang.

Contoh

Saya mengklaim di atas bahwa g (1025) = 81 , jadi mari kita hitung dengan tangan. Faktorisasi utama 1025 memberi

1025 = 5*5*41 => g(1025) = g(5)*g(5)*g(41)

Karena 41 adalah prima, kita dapatkan

g(41) = g(40) + g(42)

Selanjutnya, kami menghitung faktorisasi utama 40 dan 42 :

40 = 2*2*2*5 => g(40) = g(2)*g(2)*g(2)*g(5) = g(5)
42 = 2*3*7 => g(42) = g(2)*g(3)*g(7) = g(3)*g(7)

Untuk bilangan prima kecil ini kita dapatkan

g(3) = g(2) + g(4) = 1 + 1 = 2
g(5) = g(4) + g(6) = 1 + 2 = 3
g(7) = g(6) + g(8) = 2 + 1 = 3

Ini artinya

g(41) = g(40) + g(42) = g(5) + g(3)*g(7) = 3 + 2*3 = 9

dan

g(1025) = g(5)*g(5)*g(41) = 3*3*9 = 81

Uji kasus

Berikut adalah nilai g hingga 50 .

2 -> 1
3 -> 2
4 -> 1
5 -> 3
6 -> 2
7 -> 3
8 -> 1
9 -> 4
10 -> 3
11 -> 5
12 -> 2
13 -> 5
14 -> 3
15 -> 6
16 -> 1
17 -> 5
18 -> 4
19 -> 7
20 -> 3
21 -> 6
22 -> 5
23 -> 7
24 -> 2
25 -> 9
26 -> 5
27 -> 8
28 -> 3
29 -> 9
30 -> 6
31 -> 7
32 -> 1
33 -> 10
34 -> 5
35 -> 9
36 -> 4
37 -> 11
38 -> 7
39 -> 10
40 -> 3
41 -> 9
42 -> 6
43 -> 11
44 -> 5
45 -> 12
46 -> 7
47 -> 9
48 -> 2
49 -> 9
50 -> 9
Zgarb
sumber
Eerily mirip dengan A002487 , namun tidak (berbeda pada 15, 21, 25, 29, 33, 41, dan banyak lagi, tapi saya tidak dapat menemukan pola nyata mengapa.)
Gabriel Benamy
@GabrielBenamy Baiklah, urutan saya juga memuaskan a(2*n) = a(n), dan a(2*n+1) = a(n) + a(n+1)berlaku jika 2*n+1prime. Untuk banyak bilangan ganjil lainnya, barangkali urutan-urutannya setuju secara kebetulan.
Zgarb
Apakah mengembalikan True alih-alih 1 dapat diterima?
Dennis
@Dennis tantangannya adalah tentang mengevaluasi fungsi numerik, bukan masalah keputusan, jadi saya akan berasumsi tidak.
Pavel
1
@Pavel Ada dukungan berat yang mendukung dan, setidaknya dalam Python, True bertindak seperti 1 untuk semua maksud dan tujuan.
Dennis

Jawaban:

7

Haskell, 69 byte

x#a|x<3=1|a>x=a#2+(x-1)#2|mod x a<1,a<x=a#2*div x a#2|b<-a+1=x#b
(#2)

Contoh penggunaan: (#2) 1025->81

Parameter adihitung sampai membelah xatau mencapai x(yaitu xprima). Ini menjadi salah satu byte pendek untuk menguji untuk a > xdan menambahkan kondisi lebih lanjut ( a < x) untuk uji modulus bukan pengujian untuk a == x, karena mantan mengikat auntuk x+1, yang membantu dalam panggilan rekursif. Membandingkan:

|a==x=(x+1)#2+(x-1)#2|mod x a<1=
|a>x=a#2+(x-1)#2|mod x a<1,a<x=
nimi
sumber
4

Jelly , 18 byte

‘;’Ñ€Sµ1n2$?
ÆfÇ€P

Cobalah online!

Ini pada dasarnya hanya terjemahan langsung dari spesifikasi. (Setelah memikirkannya sedikit, saya menduga bahwa jika ada rumus tertutup untuk menemukan urutan, itu akan lebih banyak byte daripada pendekatan langsung.)

Penjelasan

Kami memiliki dua fungsi yang saling rekursif. Inilah fungsi pembantu (yang menghitung g (n) untuk prime n ):

‘;’Ñ€Sµ1n2$?
           ?  If
        n2$     the input is not equal to 2 (parsed as a group due to $)
      µ       then do all the following (parsed as a group due to µ):
‘;’             Find the list [n+1, n-1];
   р           Call the main program on each element (i.e. [g(n+1),g(n-1)]);
     S          and return the sum of the list (i.e. g(n+1)+g(n-1)).
              Otherwise:
       1        Return 1.

Dan inilah program utamanya, yang menghitung g (n) untuk setiap n :

ÆfÇ€P
Æf            Factorize the input into its prime factors;
  ǀ          Call the helper function on each element of that list;
    P         Then take the product.

Jelas, jika kita memanggil program utama pada bilangan prima, semuanya adalah no-op kecuali Ç, sehingga mengembalikan g (n) dalam kasus ini. Sisa program menangani perilaku untuk komposit n .


sumber
4

JavaScript (ES6), 59 byte

f=(n,d=2)=>n-2?d<n?n%d?f(n,d+1):f(n/d)*f(d):f(n-1)+f(n+1):1

Uji

Arnauld
sumber
3

Python 2, 85 69 byte

g=lambda n,k=3:(n&~-n<1)or n%k and g(n,k+2)or(g(k+1)+g(k-1))*g(n/k,k)
orlp
sumber
3

Jelly , 13 byte

Æfḟ2µ‘,’߀€SP

Cobalah online!

Bagaimana itu bekerja

Æfḟ2µ‘,’߀€SP  Main link. Argument: n

Æf             Yield the array of prime factors of n.
  ḟ2           Remove all occurrences of 2.
    µ          Begin a new, monadic chain. Argument: A (array of odd prime factors)
     ‘         Increment all elements of A.
       ’       Decrement all elements of A.
      ,        Pair; yield [A+1, A-1].
        ߀€    Map the main link over all elements of A+1 and A-1.
           S   Column-wise reduce by addition.
            P  Reduce by multiplication.
Dennis
sumber
3

Clojure, 126 byte

(defn t[n](if(= n 2)1(let[a(+(.indexOf(for[b(range 2 n)](mod n b)2)0))](if(> a 1)(*(t(/ n a))(t a))(+(t(dec n))(t(inc n)))))))

Yay! Hampir dua kali lipat jawaban Python!

Tidak disatukan dan penjelasan:

(defn trivial [n]
  ; Define the function.
  (if (= n 2) 1
  ; If the number is 2, return 1
    (let [a (+ 2 (.indexOf (for [b (range 2 n)] (mod n b)) 0))]
      ; Let a be the lowest prime factor of n
      (if (> a 1)
        ; The .indexOf function returns -1 if a is a prime, so -1 + 2 = 1.
        ; Checks if a is a prime.
        (* (trivial (/ n a)) (trivial a))
        ; If a is prime, return the trivial(a/n) * trivial(a).
        (+ (trivial (dec n)) (trivial (inc n)))))))
        ; Else, return trivial(n-1) + trivial(n + 1).
clismique
sumber
Keren, saya tidak tahu Anda bisa melakukannya (.indexOf (for [...] ...) x)!
NikoNyrh
Versi 118 byte saat ini menghasilkan 11 untuk (t 1025), mungkin ifitu dimaksudkan :when? Tapi kemudian nthdari lemparan daftar kosong IndexOutOfBoundsException.
NikoNyrh
@NikoNyrh Ya, itu seharusnya tidak terjadi - saya mengujinya juga, dan kode itu tidak valid. Akan kembali ke versi aslinya.
clismique
2

Mathematica, 83 byte

Which[#<4,#-1,PrimeQ@#,Tr[#0/@({#-1,#+1}/2)],0<1,1##&@@#0/@Divisors@#~Part~{2,-2}]&

Fungsi rekursif tanpa nama dari satu argumen integer positif, mengembalikan integer. Tidak terlalu pendek, pada akhirnya. Tr[#0/@({#-1,#+1}/2)](dalam kasus di mana input adalah prima) memanggil fungsi pada kedua anggota pasangan yang dipesan {(#-1)/2,(#+1)/2}dan menambahkan hasilnya; ini bagus karena fungsi memiliki nilai yang sama pada (#-1)/2dan #-1, misalnya. Demikian pula, 1##&@@#0/@Divisors@#~Part~{2,-2}memanggil fungsi pada pembagi terkecil kedua #dan pembagi complememtary (pembagi pembesar kedua) dan mengalikan jawaban bersama-sama.

Greg Martin
sumber
Bagaimana cara fungsi rekursif tanpa nama bekerja?
Pavel
1
Lihat bagian tentang #0di jawaban ini .
Greg Martin
2

Clojure, 120 byte

(defn g[n](if(= n 2)1(if-let[F(first(for[i(range 2 n):when(=(mod n i)0)]i))](*(g F)(g(/ n F)))(+(g(dec n))(g(inc n))))))

Penggunaan :whenuntuk mendapatkan pembagi n, Fadalah niljika pembagi tersebut tidak ditemukan ( nprima).

NikoNyrh
sumber
Anda ingin bertengkar, tuan? Sudah menyala. (Kompetisi persahabatan?)
clismique