Solusi terbaik yang saya temukan sejauh ini untuk teka-teki kode golf yang saya kerjakan termasuk dua doa yang agak gemukrange
. Saya sangat baru di golf kode, terutama di Python, jadi saya bisa menggunakan beberapa tips.
Fragmen yang relevan adalah ini
[x for x in range(n+1,7**6)if`x`==`x`[::-1]*all(x%i for i in range(2,x))]
Batas atas yang pertama range
bukan yang tajam. Seharusnya setidaknya 98690, dan semua yang lain sama (berdasarkan golf), semakin kecil perbedaan antara batas atas ini dan 98690 semakin baik, berdasarkan kinerja 1 . Saya menggunakan 7 6 (= 117649) karena 7**6
merupakan ekspresi Python terpendek yang dapat saya buat yang sesuai dengan tagihan.
Sebaliknya, batas bawah di yang pertama range
, serta kedua batas di yang kedua, tegas. TKI, program (dalam bentuk saat ini) akan menghasilkan hasil yang salah jika batas tersebut diubah.
Apakah ada cara untuk mempersingkat satu atau kedua ekspresi
range(n+1,7**6)
range(2,x)
?
BTW, dalam hal ini, alias range
, katakanlah, r
tidak memperoleh apa-apa:
r=range;rr
rangerange
EDIT: FWIW, program lengkapnya adalah ini:
p=lambda n:[x for x in range(n+1,7**6)if`x`==`x`[::-1]*all(x%i for i in range(2,x))][0]
p(n)
harus menjadi prime palindromic terkecil yang lebih besar dari n
. Juga, p
jangan rekursif. Peringatan: Ini sudah sangat lambat!
1 Ya, saya tahu: kinerja tidak relevan dalam kode golf, tapi itu sebabnya saya menulis "semuanya sama (golf-wise, that is)". Sebagai contoh, pilihan saya 7**6
, dan bukan alternatif yang "jelas-setara" yang lebih jelas, tetapi berkinerja buruk 9**9
. Saya suka benar - benar menjalankan upaya kode golf saya, yang berarti tidak membiarkan kinerja menurun ke titik yang membutuhkan waktu bertahun-tahun untuk menjalankan kode. Jika saya dapat membantu, tentu saja.
p=lambda n:(x for x in xrange(n+1,7**6)if`x`==`x`[::-1]*all(x%i for i in xrange(2,x))).next()
. Tentu saja, sementara Anda pada saat itu, mungkin juga berubahxrange(2,x)
untukxrange(2,int(x**.5+1))
dan membuat pengujian Anda benar-benar cepat. Jelas kode ini setara dengan kode Anda, lebih lama dan lebih cepat.Jawaban:
Buat satu loop
Seperti, Anda memiliki dua loop: satu iterasi di atas
x
yang mungkin merupakan bilangan prima palindromik, yang lain iterasii
untuk memeriksa apakahx
prima dengan divisi percobaan. Seperti yang Anda perhatikan, loop adalah Python mengambil banyak karakter, seringkali untuk menulisrange
, tetapi juga untuk menuliswhile _:
ataufor x in _
. Jadi, solusi Python golf harus bersusah payah menggunakan loop sesedikit mungkin.komentar feersum "Program golf terbaik sering membuat koneksi mengejutkan antara bagian yang berbeda dari program" sangat berlaku di sini. Pemeriksaan prima mungkin tampak seperti subrutin terpisah yang
all(x%i for i in range(2,x))
merupakan ekspresi klasik. Tapi kita akan melakukannya dengan cara lain.Idenya adalah menggunakan Teorema Wilson . Untuk setiap prime potensial
k
, kami menyimpan produk yang sedang berjalan(k-1)!
, dan memeriksa apakah ini merupakan kelipatank
. Kita bisa melacaknya(k-1)!
sementara kita menguji potensik
untuk menjadi palindrom utama dengan menjaga produk yang berjalanP
.Sebenarnya, kita akan menggunakan versi yang lebih kuat dari Teorema Wilson yang
(k-1)! % k
sama dengan 0 untuk kompositk
dan hanya untuk angka komposit, kecualik=4
memberi2
, dan(k-1)!**2 % k
sama dengan0
persis untuk angka komposit. Kami akan memperbaruiP
ke samak!**2
melalui pembaruanP*=k*k
.(Lihat jawaban ini untuk metode ini yang digunakan untuk menemukan bilangan prima dengan Python.)
Menyatukan semuanya:
Ini belum sepenuhnya golf - kondisi khususnya ditulis tidak efisien. Kita dapat mengompres kondisi untuk memeriksa itu
k
adalah palindrom sementara pada saat itu menegakkan kondisi lain melalui ketimpangan dirantai.sumber
str
, tetapi trik ini mendapatkan hanya satu sehingga banyak ... perbaikan besar datang dari algoritma yang lebih baik, seperti biasa.`k`*(k>n)*(P%k>0)!=`k`[::-1]
, yang mencukur 4AFAIK, tidak juga.
Rentang umumnya digunakan dalam golf python karena merupakan cara terpendek untuk menghasilkan daftar angka yang bertambah / berkurang.
Yang mengatakan, itu tampaknya sedikit (7 byte) lebih pendek untuk menghindari menggunakan jangkauan dan alih-alih memanggil loop sementara:
Terima kasih kepada @xnor (seperti biasa) untuk meningkatkan logika kondisi sementara :)
sumber
while(`n`!=`n`[::-1])+0in(n%i for i in range(2,n)):n+=1
. Saya sepertinya tidak bisa menghilangkan pasangan pertama karena masalah prioritas operator.while`n`*all(n%i for i in range(2,n))!=`n`[::-1]:n+=1
Saat menggunakan algoritma iteratif seperti metode Newton atau menghitung fraktal, di mana Anda biasanya perlu melakukan iterasi tanpa benar-benar peduli dengan indeks Anda dapat menyimpan beberapa karakter dengan mengulangi string pendek sebagai gantinya.
Pada tujuh iterasi ini impas dengan
range
. Untuk iterasi yang lebih banyak gunakan backtics dan angka besarIni berjalan 56.349 kali yang seharusnya cukup untuk semua tujuan praktis. Bermain-main dengan angka dan operator memungkinkan Anda melakukan hardcode berbagai nomor dengan cara ini.
sumber
'1'*4
lebih pendek dari'asdf'
)