Hole 2 - Prime Quine

9

Temukan Lubang 1 di sini .

Buatlah quine yang, ketika dijalankan, mengeluarkan blok kode sumbernya sendiri beberapa kali. Bahkan, ia harus menampilkannya n kali, di mana n di bilangan prima berikutnya.

Saya pikir sebuah contoh menunjukkan yang terbaik.

[MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]

Setiap Program akan menampilkan basis "blok" (jadi [MY QUINE]) kali prime number berikutnya .

Fungsi bawaan untuk menghitung apakah suatu bilangan prima, (seperti fungsi isPrime), atau untuk menentukan bilangan prima berikutnya (seperti fungsi nextPrime ()) tidak diperbolehkan.

  • Ini berarti bahwa fungsi untuk mendaftar jumlah pembagi tidak diperbolehkan
  • Fungsi yang mengembalikan faktorisasi utama juga tidak diizinkan

Ini harus quine yang benar (kecuali untuk beberapa kelonggaran, lihat poin berikutnya), jadi Anda tidak harus membaca kode sumber Anda sendiri.

Karena bahasa seperti Java dan C # sudah dirugikan, Anda tidak perlu menampilkan kode yang benar-benar berfungsi. Jika itu bisa dimasukkan ke dalam suatu fungsi (yang disebut) dan menampilkan quine berikutnya, Anda baik.

Ini kode-golf, jadi kode terpendek menang!

Regangkan Maniac
sumber
Tidak ada yang menjawab hole 1, jadi berapa skor yang dijawab semua orang untuk hole pertama ini?
Pengoptimal
1
Bisakah Anda mengklarifikasi bagian dengan fungsi utama? Bisakah kita menggunakannya atau tidak?
Martin Ender
3
Apa yang dianggap pemeriksaan prima dan apa yang tidak? Mempertimbangkan bahwa pemeriksaan prima dapat dibangun menggunakan quine apa pun jika jenis ini, aturannya tidak cukup jelas
bangga haskeller
@Optimizer: Setiap orang memiliki skor 0 untuk lubang pertama sampai seseorang menjawabnya.
Stretch Maniac
2
@ StretchManiac Anda harus menyebutkan dengan jelas dalam pertanyaan bahwa kedua daftar metode faktorisasi utama dan daftar metode pembagi juga tidak diperbolehkan. Silakan kirim pertanyaan di Sandbox waktu berikutnya.
Pengoptimal

Jawaban:

5

CJam, 31 byte

{'_'~]-3>U):U{)__,1>:*)\%}g*}_~

Cobalah online di penerjemah CJam .

Ide

Untuk memeriksa primality, kita akan menggunakan teorema Wilson , yang menyatakan bahwa bilangan bulat n> 1 adalah bilangan prima jika dan hanya jika (n - 1)! ≡ -1 (mod n) , yang benar jika dan hanya jika (n - 1)! + 1% n == 0 .

Kode

{                           }_~ e# Define a block and execute a copy.
                                e# The original block will be on top of the stack.
 '_'~]                          e# Push those characters and wrap the stack in an array.
      -3>                       e# Keep only the last three elements (QUINE).
         U):U                   e# Increment U (initially 0).
             {           }g     e# Do-while loop:
              )__               e# Increment the integer I on the stack (initially U).
                 ,1>            e#   Push [1 ... I-1].
                    :*          e#   Multiply all to push factorial(I-1).
                      )\%       e#   Push factorial(I-1) + 1 % I.
                                e# While the result is non-zero, repeat.
                                e# This pushes the next prime after U.
                           *    e# Repeat QUINE that many times.
Dennis
sumber
Bagaimana Anda menemukan metode pemeriksaan perdana
Pengoptimal
3
Ingat akan lebih akurat. Ini dikenal sebagai teorema Wilson.
Dennis
mp(is prime?) ada sekarang, jadi dalam versi terbaru CJam, orang bisa bermain golf ini sedikit lebih.
Lynn
1
@Mauris Ada di versi publik pertama, IIRC. Namun, pertanyaannya melarang dibangun di operator prima dan faktorisasi.
Dennis
1

CJam, 36 35 byte

{]W="_~"]U):U{)_,{)1$\%!},,2>}g*}_~

Ini pasti bisa bermain golf lebih lanjut.

Bagaimana itu bekerja:

{                               }_~   "Copy this code block and execute the copy";
 ]W=                                  "Take just the last element from the stack";
                                      "The other thing on stack is the block from above";
    "_~"]                             "Put "_~" on stack and wrap the 2 things in an array";
                                      "At this point, the string representation of stack"
                                      "elements is identical to the source code";
         U):U                         "Increment U and update U's value. This  variable"
                                      "actually counts the number of [Quine] blocks";
             {)_,{)1$\%!},,2>}g       "Find the next prime number"
                               *      "Repeat the array that many times, thus repeat the"
                                      "[Quine] block, the next prime times";

Terima kasih kepada Martin karena mengingatkan saya pada ]W=triknya :)

Cobalah online di sini

Pengoptimal
sumber
1

Mathematica, 248 222 byte

Sunting: Memperbaiki penggunaan fungsi terkait prima, tetapi juga meningkatkan quining sedikit.

Sunting: Terima kasih kepada Dennis karena memperkenalkan saya pada teorema Wilson.

1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#\2&@@("*"&,For[i=n,Mod[++i!/i+1,i]>0,0];i]")&,For[i=n,Mod[++i!/i+1,i]>0,0];i]

Ini mengasumsikan bahwa kernel keluar antara menjalankan quine berikutnya (atau setidaknya nreset), karena bergantung pada nyang tidak terdefinisi sebelum instance pertama [MyQuine]dijalankan.

Ini mungkin bisa dipersingkat banyak, tapi saya tidak punya banyak pengalaman dengan quines, terutama di Mathematica.

Berikut ini penjelasannya:

1;

Ini tidak melakukan apa-apa, tetapi jika digabungkan ke akhir quine sebelumnya, ini mengalikan hasil dari ekspresi terakhir dengan 1(yang merupakan no-op) dan tanda titik koma menekan output. Ini memastikan bahwa hanya salinan [MyQuine]cetakan yang terakhir .

n=If[ValueQ@n,n+1,1];

Ini Menginisialisasi nke 1dalam salinan pertama [MyQuine]dan kemudian menambahkan dengan 1di setiap salinan lanjut - yaitu ini hanya menghitung berapa banyak salinan ada di n.

Lewati terus hingga akhir sekarang:

For[i=n,Mod[++i!/i+1,i]>0,0];i

Ini menemukan prime berikutnya menggunakan teorema Wilson .

StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("QUINE_PREFIX"*"QUINE_SUFFIX")&,NEXTPRIME[n]]

Inilah quine yang sebenarnya. Itu membuat NextPrime@nsalinan kode itu sendiri. Ini juga agak aneh. Ya, saya mengalikan dua string di sana, dan tidak ada yang tidak memiliki hasil yang berarti. QUINE_PREFIXberisi semua kode sebelum dua string dan QUINE_SUFFIXberisi semua kode setelah dua string. Sekarang biasanya Anda menggunakan Apply(atau @@) untuk mengubah daftar menjadi serangkaian argumen. Tetapi Anda bisa mengganti apa saja Headdengan Apply- mis. Perkalian. Jadi, meskipun ini merupakan produk, saya masih bisa mengubahnya menjadi dua argumen untuk fungsi saya. Fungsi itu tidak:

#<>ToString[1##,InputForm]<>#2

Di mana #argumen pertama (string awalan), #2adalah argumen kedua (string suffix), ##adalah urutan dari kedua argumen. Saya perlu menambahkan 1untuk menjaga perkalian - jika tidak ##akan percikan ke daftar argumen untuk ToString. Bagaimanapun, ToString[1##,InputForm]&@@("abc"*"def")kembali "abc"*"def"... hanya apa yang saya butuhkan!

Saya pikir dengan semua hal yang saya butuhkan di sekitar quine, evalquine berbasis akan lebih tepat di sini. Saya akan memeriksanya nanti atau besok.

Martin Ender
sumber
@ MartinBüttner pertanyaannya harus diedit
bangga haskeller
Heh, saya juga dapat menggunakan Teorema Wilson untuk membawa entri saya setara dengan Denis ';)
Pengoptimal
@ Pengoptimal Tapi dalam kasus saya, tidak ada bahaya menyinggung siapa pun karena saya masih menggunakan 7 kali lebih banyak byte dari kalian berdua;)
Martin Ender
@ MartinBüttner Saya tahu: D Itu sebabnya saya tidak menggunakannya :)
Pengoptimal
0

J - 60 char

Gunakan metode prima berikutnya seperti jawaban lainnya. (Itu 4 p:sedikit.)

((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''

Trik J kecil yang lucu adalah yang f :gbertindak seperti fketika diberi satu argumen dan gketika diberi dua. Jadi, jika Anda menulis, katakan f :;'a'f :;'a'f :;'a'itu bertingkah seperti f'a';'a';'a', yang bagus karena itu adalah daftar kotak yang itemnya 'a'dan panjangnya adalah jumlah kemunculannya.

Jadi kita bisa mengangkatnya menjadi semacam quiney. The fkita gunakan terlihat seperti (foo $~ bar), di mana fookonstruksi bagian string yang kita ulangi berulang, barmenemukan bilangan prima berikutnya dan mengalikan dengan 60, panjang string di foo.

   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
180
   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
300
algoritme hiu
sumber
Bisakah Anda memodifikasi kode Anda untuk memenuhi spesifikasi baru? Metode yang menghasilkan perdana berikutnya tidak diizinkan. Terima kasih.
Stretch Maniac
0

Python 2.7, 214

from sys import*;R,s=range,chr(35)
def N(n):
 if n<3:return n+1
 for p in R(n+1,n+n):
    for i in R(2, p):
     if p%i==0:break
     else:return p
P=file(argv[0]).read();print(P.split(s)[0]+s)*N(P.count(chr(37)));exit(0)
#
pelaku diet
sumber