Produk 7-Distinct-Prime Terdekat

14

(via obrolan )

Entri OEIS A123321 mencantumkan urutan angka yang merupakan produk dari tujuh bilangan prima yang berbeda. Untuk singkatnya, kami akan menyebutnya nomor 7DP . Beberapa angka pertama dan pembagi yang sesuai di bawah ini:

510510 = 2 * 3 * 5 * 7 * 11 * 13 * 17
570570 = 2 * 3 * 5 * 7 * 11 * 13 * 19
690690 = 2 * 3 * 5 * 7 * 11 * 13 * 23
746130 = 2 * 3 * 5 * 7 * 11 * 17 * 19

Tantangannya di sini adalah menemukan nomor 7DP terdekat, dalam hal jarak absolut, dari input yang diberikan.

Memasukkan

Integer positif tunggal n dalam format apa pun yang nyaman .

Keluaran

Nomor 7DP terdekat dengan n , lagi dalam format apa pun yang nyaman. Jika dua nomor 7DP terikat untuk yang terdekat, Anda dapat menampilkan salah satu atau keduanya.

Aturan

  • Angka dapat dianggap sesuai dengan [int]tipe data default bahasa Anda (atau yang setara).
  • Program lengkap atau fungsi dapat diterima.
  • Celah standar dilarang.
  • Ini , jadi semua aturan golf biasa berlaku, dan kode terpendek menang.

Contohnya

5 -> 510510
860782 -> 870870
1425060 -> 1438710 (or 1411410, or both)
AdmBorkBork
sumber

Jawaban:

11

Python, 89 86 85 byte

f=lambda n,k=0:126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))and f(n+k,k%2*2+~k)or n

Algoritma ini adalah O (menakutkan) untuk memulai dan rekursi tidak benar-benar membantu, tetapi bekerja dengan baik selama n cukup dekat dengan angka 7DP.

Terima kasih kepada @xnor karena bermain golf 3 byte!

Uji di repl.it .

Bagaimana itu bekerja

Python tidak memiliki fitur bawaan atau faktorisasi, tetapi kita dapat mengidentifikasi angka 7DP dengan jumlah dan sifat pembagi mereka.

Dengan prinsip penggandaan, jumlah pembagi bilangan bulat dapat dihitung sebagai produk dari eksponen yang bertambah dari faktorisasi utamanya. Dengan demikian, σ 0 (n) ( fungsi pembagi ) adalah 2 m setiap kali n adalah nomor mDP.

σ 0 (n) = 128 dengan demikian merupakan kondisi yang diperlukan, tetapi itu tidak cukup; misalnya, σ 0 (2 127 ) = 128 , tetapi 2 127 jelas bukan angka 7DP. Namun, jika σ 0 (n) = 128 dan tidak ada kuadrat sempurna yang membagi n secara merata, maka n adalah angka 7DP.

Untuk input n , algoritma terdiri dalam memeriksa bilangan bulat n , n - 1 , n + 1 , n - 2 , n + 2 , dll. Dan mengembalikan yang pertama yaitu angka 7DP.

Ketika f dipanggil dengan argumen n , hal berikut terjadi:

  • Kode

    126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))

    tes jika n adalah tidak sejumlah 7DP sebagai berikut.

    Untuk semua bilangan bulat i sedemikian sehingga 1 <i <n , 1>>n%i<<7*(n/i%i<1)akan dievaluasi.

    • Jika n habis dibagi i tapi tidak dengan saya 2 , 1>>n%ihasil 1 dan (n/i%i<1)hasil 0 , mengakibatkan
      1 · 2 7 · 0 = 1 .

    • Jika n dapat dibagi dengan i 2 , 1>>n%idan (n/i%i<1)keduanya menghasilkan 1 , menghasilkan 1 · 2 7 · 1 = 128 .

    • Jika n tidak tidak habis dibagi oleh i , 1>>n%imenghasilkan 0 , menghasilkan 0 · 2 7 · x = 0 .


    Jumlah bilangan bulat yang dihasilkan akan 2 m - 2 jika n adalah nomor MDP (yang 2 m pembagi, tidak termasuk 1 dan n ) dan lebih besar jumlahnya dari 127 jika n memiliki faktor persegi yang sempurna. Dengan demikian, jumlahnya akan menjadi 126 jika dan hanya jika n adalah angka 7DP.

  • Untuk angka 7DP, jumlahnya adalah 126 , jadi XORing dengan 126 menghasilkan 0 , yang salah. Dengan demikian, bagian atau lambda dieksekusi dan f mengembalikan nilai saat ini dari n .

  • Jika n bukan angka 7DP, XOR akan mengembalikan nilai kebenaran yang tidak nol. Dengan demikian, bagian dan lambda dieksekusi.

    f(n+k,k%2*2+~k)

    panggilan rekursif f dengan nilai n yang diperbarui (potensi nomor 7DP berikutnya) dan k (perbedaan antara kandidat baru dan yang berikutnya).

    Jika k adalah bilangan bulat genap, non-negatif, k%2*2menghasilkan 0 dan ~kmenghasilkan - (k + 1) . Jumlah dari kedua hasil adalah - (k + 1) , yang merupakan bilangan bulat ganjil, negatif yang 1 lebih besar dalam nilai absolut daripada k .

    Jika k adalah bilangan bulat ganjil, negatif, k%2*2hasilkan 2 dan ~khasilkan - (k + 1) . Jumlah kedua hasil adalah 2 - (k + 1) = - (k - 1) , yang merupakan bilangan bulat genap, non-negatif yang 1 unit lebih besar dalam nilai absolut daripada k .

    Ini berarti bahwa k mengambil nilai 0, -1, 2, -3, 4, ⋯ .

    Ketika ditambahkan secara kumulatif ke n 0 (nilai awal n ), bilangan bulat yang dihasilkan adalah

    • n 0 + 0
    • ( n 0 + 0) - 1 = n 0 - 1
    • ( n 0 - 1) + 2 = n 0 + 1
    • ( n 0 + 1) - 3 = n 0 - 2
    • ( n 0 - 2) + 4 = n 0 + 2
    • dll.


    memastikan jumlah 7DP pertama kita jumpai adalah sebagai dekat dengan n 0 mungkin.

Dennis
sumber
Ide bagus dengan penghitung pembagi! Saya pikir Anda dapat bermain golf bolak-balik dengan memperbarui ksecara langsung f(n+k,k%2*2+~k), dimulai dengan k=0.
xnor
Perbaikan luar biasa. Terima kasih!
Dennis
9

Brachylog , 44 40 16 byte

Dicoret 44 masih teratur 44; (

:I=+.>0,.$pPdPl7

Contoh:

?- run_from_atom(':I=+.>0,.$pPdPl7',1425060,Z).
Z = 1438710 .

Mungkinkah bahasa ini tidak selalu payah? Saya mengalahkan Jelly dan MATL!

Kasing uji dengan 5 adalah yang terpanjang dan membutuhkan sekitar 10 detik pada mesin saya.

Ini akan menjadi 12 byte jika $ptidak disadap (kita tidak perlu>0,. bagian itu)

Penjelasan

Brachylog menggunakan pemrograman logika kendala secara default untuk semua aritmatika integer. Apalagi pelabelan built-in= berfungsi pada domain yang mungkin tidak terbatas.

Itu berturut-turut menyatukan variabel tanpa kendala (yaitu dalam (-inf, inf)) seperti:0, 1, -1, 2, -2, 3, … .

Oleh karena itu, kita bisa mendapatkan nomor 7DP terdekat dengan mencari nomor pertama yang Idisatukan (-inf, inf)(menggunakan pengulangan otomatis), yang Input + Imerupakan angka 7DP.

:I=                Label variables in [Input, I]. I has no constraints and Input is known
   +.              Unify Output with Input + I
     >0,           Output > 0 (wouldn't be needed if $p failed for numbers less than 1)
        .$pP       Unify P with the list of prime factors of Output
            dP     Check that P with duplicates removed is still P
              l7   Check that the length of P is 7
Fatalisasi
sumber
1
Saya mengalahkan Jelly dan MATL! Tetapi hanya dengan 0 byte :-P
Luis Mendo
1
@LuisMendo Akan 13 byte jika saya memperbaiki bug $p. Secara teori saya tidak perlu >0,, tetapi implementasi saya buggy: P
Fatalize
1
@ DavidC Ya, karena dimulai pada input dan kemudian mencoba semua angka seperti Input+1, Input-1, Input+2, Input-2, Input+3, ...itu : karena itu 7DP pertama yang ditemukan dengan metode itu akan menjadi yang terdekat.
Fatalkan tanggal
1
@ ahm Memperbaiki bug setelah tantangan diposting membuat jawaban tidak bersaing, jadi saya akan membiarkannya pada 16, meskipun sekarang bisa 12 byte ( >0,.tidak diperlukan)
Fatalize
1
codegolf.stackexchange.com/a/111998/59995 Dicoret 444 masih 444. Saya akan terkesan ketika kita melihat dicoret 4444.
NoSeatbelts
7

Jelly, 17 byte

Pµạ³,
×⁹ÆRœc7Ç€ṂṪ

Bekerja secara teori, tetapi membutuhkan waktu bertahun-tahun untuk menyelesaikannya.


Berikut adalah versi yang benar-benar berfungsi untuk input yang diberikan, tetapi secara teoritis gagal untuk input besar:

Pµạ³,
50ÆRœc7Ç€ṂṪ

Coba di sini. Ini menghasilkan semua bilangan prima hingga 50, kemudian menemukan semua 7-kombinasi bilangan prima dalam daftar itu, dan kemudian semua produk mereka. Akhirnya, ia hanya menemukan elemen terdekat dari daftar itu dengan argumen yang diberikan.

Tentu saja, setelah 7DP kami mengandung bilangan prima lebih tinggi dari 50, ini akan gagal. Versi teoritis menghasilkan semua bilangan prima hingga 256n untuk input n , tetapi sebaliknya berfungsi dengan cara yang sama.

Bukti

Biarkan p(x)menunjukkan prima berikutnya setelah x. Batas atas (sangat longgar) untuk produk 7DP terdekat dengan x adalah:

p(x) * p(p(x)) * p(p(p(x))) * ... * p(p(p(p(p(p(p(x)))))))

Jadi kita hanya perlu memeriksa bilangan prima dalam [2 ... p (p (p (p (p (p (p (x))))))))))] . Postulat Bertrand mengatakan bahwa p (x) ≤ 2x , jadi cukup untuk memeriksa semua bilangan prima hingga 128x .

Lynn
sumber
×⁹ÆRœc7P€µạ³ỤḢịatau ×⁹ÆRœc7P€µạ³NMị(mencetak array semua solusi) menghemat beberapa byte. Juga, ×⁹dapat diubah +⁴untuk meningkatkan efisiensi.
Dennis
5

MATL , 21 17 16 14 13 byte

Terima kasih kepada Dennis untuk saran yang menghapus 4 byte, dan yang lain menyimpan 1 byte lebih!

t17*Zq7XN!pYk

Ini berfungsi secara teori, tetapi kehabisan memori untuk input di atas 6(kompiler online).

Versi yang lebih efisien menggunakan 21 byte , dan menghitung semua kasus uji dalam waktu sekitar satu detik:

t3e4/k16+_YqZq7XN!pYk

Cobalah online!

Penjelasan

Versi hemat memori

Ambil input N = 860782sebagai contoh. Itu sudah cukup untuk mempertimbangkan bilangan prima hingga M = 29, yang merupakan perdana pertama yang dikalikan dengan 2*3*5*7*11*13melebihi N . Dalam contoh ini 2*3*5*7*11*13*29 = 870870,. Perdana berikutnya adalah 31. Setiap produk yang melibatkan yang prima atau lebih besar akan setidaknya 2*3*5*7*11*13*31 = 930930, dan itu dijamin tidak menjadi solusi, karena melebihi 870870yang melebihi N .

M dihitung sebagai bilangan prima pertama lebih besar dari max(N/(2*3*5*7*11*13), 16). The maxFungsi digunakan untuk memastikan bahwa setidaknya 17diambil. Untuk menyimpan beberapa byte, kode tersebut diganti 2*3*5*7*11*13 = 30030dengan 30000, dan berfungsi sebagai maxtambahan. Perubahan ini valid karena memberi nilai lebih besar.

t      % Take input implicitly. Duplicate
3e4/k  % Divide input by 30000 and round down (rounding here is only needed
       % due to a bug in the "next prime" function)
16+    % Add 16
_Yq    % Next prime
Zq     % Prime numbers up to that value
7XN    % Combinations of those primes taken 7 at a time. Gives a 2D array
       % with each combination on a different row
!p     % Product of each row
Yk     % Output product that is closest to the input. Implicitly display

Versi tidak efisien memori

Untuk lebih mengurangi jumlah byte, divisi dapat dihapus; sebenarnya, itu sudah cukup untuk dikalikan dengan 17(terima kasih, @ Dennis). Ini memastikan bahwa prime berikutnya dimasukkan (oleh postulat Bertrand ) dan bahwa hasilnya setidaknya 17. Ini bekerja secara teori, tetapi kehabisan memori untuk input yang lebih besar dari sekitar 6.

Di dalam kode, bagian

3e4/k  % Divide input by 30000 and round down (rounding here is only needed
       % due to a bug in the "next prime" function)
16+    % Add 16
_Yq    % Next prime

diganti oleh

17*    % Multiply by 17
Luis Mendo
sumber
3

Pyke, 32 byte

#PDl 7q.ID}lRlqi*(#)DF-X,)R],She

Coba di sini!

Perhatikan ini tidak berfungsi online - itu habis. Versi ini hanya memeriksa 2 bilangan prima yang berbeda dan harus bekerja lebih cepat. Ketika ada 2 angka dengan jarak yang sama jauh dari target, ia memilih yang lebih rendah.

Ini melewati semua angka sampai menemukan yang lebih besar dari input dan 7DP. Untuk setiap nomor, itu menghilangkannya jika bukan 7DP. Ia kemudian memiliki daftar 7DP hingga input dengan yang lebih besar. Itu kemudian mengambil salah satu yang paling dekat dengan input.

Biru
sumber
3

Julia, 59 byte

!n=sort(map(prod,combinations(17n|>primes,7))-n,by=abs)[]+n

Ini sangat tidak efisien, tetapi berfungsi untuk kasus uji pertama dalam praktik dan untuk teori lainnya.

Dengan biaya 5 byte lebih - untuk total 64 byte - efisiensi dapat ditingkatkan secara dramatis.

!n=sort(map(prod,combinations(n>>14+17|>primes,7))-n,by=abs)[]+n

Cobalah online!

Latar Belakang

Seperti disebutkan dalam jawaban @ LuisMendo , himpunan bilangan prima yang harus kita pertimbangkan untuk angka 7DP terdekat cukup kecil. Cukup untuk set yang berisi angka 7DP yang lebih besar dari input n , yang akan benar jika dan hanya jika itu berisi p utama ≥ 17 sehingga 30300p = 2 · 3 · 5 · 7 · 11 · 13 · p ≥ n .

In Pada interval yang mengandung setidaknya satu bilangan prima membuktikan bahwa interval [x, 1,5x) berisi setidaknya satu bilangan prima setiap kali x ≥ 8 . Sejak 30030/16384 ≈ 1,83 , itu berarti harus ada p prima dalam (n / 30030, n / 16384) setiap kali n> 8 · 30300 = 242400 .

Akhirnya, ketika n <510510 , p = 17 sudah cukup jelas, jadi kita hanya perlu mempertimbangkan bilangan prima hingga n / 16384 + 17 .

Dengan biaya efisiensi, kita dapat mempertimbangkan bilangan prima hingga 17n sebagai gantinya. Ini bekerja ketika n = 1 dan jauh lebih besar dari n / 16384 + 17 untuk nilai n yang lebih besar .

Bagaimana itu bekerja

17n|>primesdan n>>14+17|>primes(bithift sama dengan membaginya dengan 2 14 = 16384 ) menghitung rentang prima yang disebutkan dalam paragraf sebelumnya. Kemudian, combinations(...,7)hitung semua array dari tujuh bilangan prima yang berbeda dalam rentang itu, dan pemetaan prodatas mereka yang menghitung produk mereka, yaitu, angka 7DP dari mana kita akan memilih jawabannya.

Selanjutnya, -nkurangi n prom setiap 7DP angka, lalu urutkan sort(...,by=abs)perbedaan dengan nilai absolutnya. Akhirnya, kami memilih perbedaan pertama dengan []dan menghitung angka 7DP yang sesuai dengan menambahkan n dengan +n.

Dennis
sumber
2

Pyth, 30 byte

L&{IPbq7lPby#.W!syMH,hhZa0teZ,

Cobalah online!

Suite uji.

(5 terlalu lama untuk dijalankan)

Penjelasan

L&{IPbq7lPby#.W!syMH,hhZa0teZ,

L&{IPbq7lPb     Defines a function y, whose argument is b:
 &                  Return if both the following are true:
  {IPb                  the prime factorization contains no duplicate; and:
      q7lPb             the number of prime factors is 7

           y#.W!syMH,hhZa0teZ,   The main programme. Input as Q.
                             ,QQ Implicit arguments, yield [Q,Q].
             .W                  While
               !syMH                   both numbers do not satisfy y:
                    ,hhZ             increment the first number
                          teZ        and decrement the second number
                        a0           while making it non-negative.
Biarawati Bocor
sumber
1

Mathematica 136 80 75 byte

Ini adalah pendekatan langsung, bekerja keluar dari n.

nadalah produk prime 7-berbeda jika jumlah faktor prima adalah 7 ( PrimeNu@#==7) dan tidak satu pun dari faktor-faktor ini muncul lebih dari sekali ( SquareFreeQ@#&).

g@n_:=(k=1;While[!(PrimeNu@#==7&&SquareFreeQ@#&)⌊z=n-⌊k/2](-1)^k⌋,k++];z)

Kiriman saya sebelumnya (136 bytes) menemukan produk 7-berbeda-prime pertama di atas ndan, jika ada, produk 7-berbeda-prime pertama di bawah ini n. Itu kemudian hanya menentukan mana yang lebih dekat n. Jika produknya sama, maka keduanya akan dikembalikan.

Versi saat ini memeriksa n-1, n + 1, n-2, n + 2 ... hingga mencapai produk 7-berbeda-prime pertama. Versi yang lebih efisien ini mengadopsi pendekatan yang diambil Dennis.

Kemajuan kunci digunakan ⌊k/2](-1)^k⌋untuk mengembalikan seri, 0, 1, -1, 2, -2 ... Nol digunakan untuk memeriksa apakah nitu sendiri adalah produk 7-berbeda-prima. Karena alasan ini, Floor(yaitu, ⌊...⌋) digunakan sebagai ganti Ceiling.


g[5]
g[860782]
g[1425060]

510510

870870

1438710

DavidC
sumber
1

05AB1E , 10 byte

°Åp7.ÆPs.x

Cobalah online!

Mencoba semua kombinasi 7 dari 10 prima input pertama **. Kehabisan memori untuk input yang lebih besar dari 1.

Versi 14 byte yang jauh lebih efisien:

5°/7+Åp7.ÆPs.x

Cobalah online!

Menggunakan bilangan prima pertama (input / 100000 + 7).

Grimmy
sumber