Quines hakkında hiper


27

Hyperprogramming'ten ilham alan : N + N, N × N, N ^ N hepsi bir arada .
@MartinEnder ve @trichoplax'a kum havuzundaki yardımları için teşekkürler.

Tanımlar

Hyperquines

Bir tanımlama hyperquine düzenin n bir Quine'a benzeri tam program veya fonksiyon olarak P ye uyan için geçerli olan tüm kuralları doğru quines ek olarak, aşağıdaki yapıya sahiptir ve.

P karakteri birleşimidir oluşur grupları , n aynı karakter kopya. Ne zaman P yürütülür, çıkış karakterinin bir daha kopya güçlendirilecek aynı gruplar, birleşimidir.

Örnekler

  • Kaynak kodun aabbccçıktısını ürettiği varsayımsal bir programlama dilinde aaabbbccc, bu program 2. dereceden oluşan bir hiperkin oluşturur .

  • Tanım yok değil farklı olması, farklı grupların karakterleri gerektirir.

    Eğer kaynak kod aabbccçıktıyı aaaabbbbccccverirse, program 1. sıraya göre bir hiperkindir ; kaynak kodu, altı karakter çiftinin çıktısı olan altı tek karakter grubundan oluşur.

  • In GS2 , boş bir program baskılar \nve program \nbaskılar \n\n. Ancak, ne \nde \n\nonlar tüm özelliklerini karşılamak olmadığı hyperquines vardır uygun quines ; kaynak kodun hiçbir bölümü çıktının farklı bir bölümünü kodlamaz.

Aşırı zincirler

Bir tanımlama hyperquine zincir uzunluğu n bir sonlu dizisi olarak n tam programlar veya N fonksiyonları
(P 1 , ..., p , n ) o biri aşağıdaki kısıtlamalar.

  1. P 1 ,…, P n-1'in çıktıları sırasıyla P 2 ,…, P n'dir .

  2. P 1 ,…, P n , hiperkinlerdir.

  3. Emirleri P 1 , ..., p , n bir formu kesin artan sekansını bitişik tamsayı.

Son olarak, bir tanımlamak sonsuz hyperquine zincir tam programları veya fonksiyonların sonsuz dizisi olarak (P 1 , P 2 , ...) gibi her bir başlangıç aralığı olduğu (P 1 , ..., p , n ) uzunlukta bir hyperquine zincirini oluşturmaktadır n .

Örnekler

  • Kaynak kodun aabbccçıktı ürettiği varsayımsal bir programlama dilinde aaabbbccc, sırayla çıktıyı üreten aaaabbbbccccçift ​​( aabbcc, aaabbbccc), uzunluğu 2 olan bir hiperkin zincirini oluşturur .

    Unutmayınız ki aaaabbbbcccc- zincirdeki son hiperkinin çıktısı - belirli bir çıktı üretmek zorunda değildir; geçerli bir kaynak kod olması gerekmiyor bile.

  • Eğer, bir önceki örnekten devam aaaabbbbccccçıktı üretir aaaaabbbbbccccc, triplet ( aabbcc, aaabbbccc, aaaabbbbcccc) uzunluğunda bir hyperquine zincirini oluşturmaktadır 3 .

    Bu model sonsuza devam ederse dizisi ( aabbcc, aaabbbccc, aaaabbbbcccc, ...) sonsuz hyperquine zincirini oluşturmaktadır.

  • Programların (çifti abc, aabbccçıkışları ile) ( aabbcc, aaaabbbbcccc) 'dir olmayan hyperquines emir her ikisi de, çünkü bir hyperquine zincir 1 bir kesin artan sekansı oluşturmayan, böylece.

  • Programların (çifti aabbcc, aaaabbbbccccçıkışları ile) ( aaaabbbbcccc, aaaaabbbbbccccc) 'dir olmayan hyperquines emirleri, çünkü, bir hyperquine zincir 1 ve 4 de, bitişik bir tamsayı dizisi oluşturmayan, böylece.

kurallar

Görev

Seçtiğiniz bir programlama dilinde , önemsiz olmayan bir hiperkin zinciri, yani en az 2 hiperkinden oluşan bir zincir yazın.

Her zaman olduğu gibi, programlarınız herhangi bir biçimde herhangi bir girdi alamaz veya kendi kaynak kodlarına erişemez.

Tercümanınız örtük bir yeni satır basarsa, hiperkuinleriniz bunu hesaba katmak zorundadır .

Tüm standart boşluklar - özellikle de kuyruklarla ilgili olanlar - geçerlidir.

puanlama

En uzun hiperquine zinciri kazanır. İki veya daha fazla gönderimler eşitlik varsa, en kısa hyperquine ile başlar bunlar arasında teslim (karakterleri ölçülen kazanır). Her zamanki gibi, gönderim zamanı nihai başkasıdır.


Sen kaynak kodu, çıkış, karakter sayısı ve yürütülmesi için aynı karakter kodlamasını kullanmalıdır. Örneğin, Python programı print 42olduğu değil tercüman tek karakter olarak her bayt davranır beri, 2 karakterli UTF-32 sunulması. Tercih ettiğiniz dil karakter tabanlı değilse, tüm bireysel baytları karakter olarak kabul edin.


3
Tamam, belki Helka'nın mücadelesi imkansız değildi, ama elbette bu: D
Beta Decay

1
@ BetaDecay Gerçekten mi? :)
Martin Ender

Yanıtlar:


10

Befunge-98 , sonsuz düzen, 54 52 38 36 bayt

İkinci yaklaşım - sonsuz düzen, 36 bayt

Bu program aslında 34. hiperkinde kırılır, çünkü ASCII değeri "string yorumlamasını bozar (ve 59'da ;), ancak bu değerin saklanmasını asla yürütülmeyecek bir konuma (yani (0, 1)yerine (0, 0)) mahsup ederiz .

1+::0*x01pn'!1+:#jr;,kg10@k!:kg10;#"

Çevrimiçi deneyin: 1 , 2 , 10 , 34 , 42

açıklama

INSTRUCTIONS  STACK (PYTHON PSEUDOCODE)           EXPLANATION
1+            [n]                                 Push n many 1s onto the stack, then sum them up
::            [n]*(at least 3)                    Duplicate that sum at least twice
0*            [n]*(at least 2)+[0]                Push a whole lot of zeros, then multiply them all together
x             [n]*(at least 1)                    Pop a vector off the stack (n, 0) and set the IP delta to that; now the IP is only executing every nth character
01p           [n]*(at least 1)                    Place n in the program at coordinates (0, 1); this is just for storage
n             []                                  Clear the stack
'!1+          ['"']                               '!' is character 33; one less than 34, or '"'
:#jr          ['"']                               We duplicate the 34 (all we care is that it's a rather large number), then turn around and skip that many spaces
                                                  The IP, having jumped 34*n instructions to the left, is now way in the negatives
                                                  Execution resumes on the other side of the program (the following instructions have been reversed for readability
"             [the program of order 1]            The quote-at-the-end-of-the-program is a common trick for one-liner Befunge quines
#; ... ;                                          Jumps into a loop (when the IP hits one semicolon it skips to the next, restarting the loop)
01gk:         [(rest of string), char*(n+2)]      This duplicates the letter n+1 times*, leaving n+2 copies on the stack
!k@                                                If the number on the top of the stack is zero (i.e. we are printing), it will execute '@',
                                                  ending the program; otherwise, it will NOT execute '@' and will instead continue normally
                                                  Vague* 'k' instruction FTW
10gk,                                             If we aren't done yet, print the character n+1 times* (and restart the loop)

* 'k' is a very strange instruction. It pops a number off the stack; if the number is zero, it skips the command in front of it. If the number is greater than zero,
  it will execute the instruction that many times PLUS ONE. This is actually strangely advantageous in this program.

İlk yaklaşım - sipariş 34, 52 bayt (inceleme kullanır, teknik olarak yasal değildir)

Yukarıdaki yazıda yer alan nedenden ötürü, bu program 34. sıradadır (test etmesem de).

1+::0*x:00p'1\k:00gk,1#;:00g*0g00gk:$00gk,1+:'4-!k@;

Çevrimiçi deneyin!


2
Çıktısı doğru gibi görünen ve bu kesinlikle etkileyici olsa da, ben bir ikna olmadım uygun quine kullanabilirsiniz gdoğrudan programın kaynak kodunu okumak için fikir olarak görülmektedir. Bu, pek Befunge uzmanı olmadığımı söyledi, bu yüzden bir şeyi yanlış anlıyor olabilirim.
Dennis,

gBurada iki amaç için kullanıyorum : veri depolamak ve kaynak kodu okumak için. İkincisi biraz kabataslak olabilir, esolangs.org/wiki/Befunge#Quineg kaynak kodunu okumak için de bir örnek kullanıyor olsa da. Bu arada, herhangi bir gözden geçirme kullanmayan bir sürüm oluşturabilir miyim, göreceğim.
Hactar

Bunun Befunge'de mümkün olabileceğini biliyordum, ama nasıl olduğu hakkında hiçbir fikrim yoktu. Bana gösterdiğin için teşekkürler. +1
ETHProductions

10

> <> , sonsuz sıra, 178 bayt

Programda takip eden bir satır çekimi var.

^
.
*
&
:
&
+
*
2
b
*
*
6
9
$
0
)
*
4
8
:
~
.
*
&
:
&
+
*
2
b
*
*
2
b
$
0
)
i
:
-
1
o
a
&
:
&
o
~
.
*
&
:
&
+
*
7
7
*
*
4
6
$
0
)
0
:
-
1
$
o
:
$
&
:
&
&
,
*
8
b
-
1
l
}
*
3
d
'

Çevrimiçi deneyin: 1 , 2 , 3 , 10 (Sonuncunun çalışması biraz zaman alır.)

Retina script lineer programdan kaynak üretmek için.

açıklama

Ana fikir, dikine dikey çevirmektir, böylece gerçek kontrol akışı tekrarlamadan etkilenmez. Örneğin ikinci hiper quine şöyle başlar:

^^

..

**

Sadece ilk sütuna girdiğimizden, tekrarlanan karakterler için endişelenmemize gerek yok. Ayrıca, kodun çoğunluğunu bir dize olarak ittiğimizde ', bu her boş satır için bir boşluk iter ve bu da tekrar sayısını belirlememize olanak sağlar. Bu, bu boş satırlardan dolayı bazı sınırlamalar olduğunu söyledi:

  • "Büyük sayıları, sıranın ana bölümünde karakter kodları olarak itmek için kullanamayız , çünkü bu, 32istemediğimiz ekleri zorlar .
  • Kullanamayız ?veya !çünkü bu durumda yalnızca boşluk olacak bir sonraki karakteri atlıyorlar (bu yüzden aslında bir sonraki komutu atlamazlar).

Bu nedenle, tüm kontrol akışları, açık atlamalar (temelde 2D goto, temelde) ile gerçekleştirilir, bu da gerçek ofsetleri tekrar sayısını temel alarak hesaplamamız gerekir.

Öyleyse gerçek koda bakalım. ^Kodun baştan aşağı yürütülmesi için başlıyoruz. Daha kolay okumak için asıl kodu yürütme sırasına göre yazalım (ve bir ^daha asla çalıştırılmadığından düşeni bırakalım ):

'd3*}l1-b8*,&&:&$:o$1-:0)0$64**77*+&:&*.~o&:&ao1-:i)0$b2**b2*+&:&*.~:84*)0$96**b2*+&:&*.

'> <> (Ve Befunge, sanırım) için standart quining tekniğidir. Dize moduna geçer, bu, karşılaşılan karakterlerin bir sonraki 'ile karşılaşılana kadar yığına itildiği anlamına gelir . Boş çizgiler dolaylı olarak boşluklarla doldurulur, bu yüzden aradaki tüm boşlukları alırız. Programın sonunda boş satırlar yoksayılır. Böylece IP etrafına sarılıp 'tekrar çarptıktan sonra, programın 'kendisi dışında programın ilk sütununu hazırladık .

Bunu tüm programı yazdırmak için nasıl kullandığımıza bakalım.

d3*}    Put a 36 (the ') at the bottom of the stack. Now the stack holds
        a representation of the entire first column.
l1-     Push the depth of the stack, minus (so minus to ').
b8*,    Divide by 88. The original program has 89 lines. If we divide the 
        depth of the stack (minus 1) by 88, we get the order of the current
        hyperquine (due to all the spaces we've pushed).
&       Store the order of the hyperquine in the register.
        Begin of main loop:
&:&       Push a copy of the register onto the stack. Call that N.
          Begin of line-printing loop:
$:o$        Print a copy of the top character on the stack.
1-          Decrement N.
:0)         Check whether it's still positive (gives 0 or 1).
0$          Put a 0 underneath. This will be the x-coordinate of a jump.
64**        Multiply the conditional by 24. This is the number of commands
            in this inner loop.
77*+        Add this to 49, the offset of the end of the loop.
            The result is line we want to jump to in the order-1 hyperquine.
&:&*        Multiply by the order of the quine (so that we jump further on
            higher quine orders).
.         Jump. If N isn't zero yet, this repeats the inner loop. Otherwise
          we continue right here.
~         Discard N (now 0).
o         Output one last copy of the top character on the stack.
&:&       Push a copy of the register onto the stack. Call that N.
          Begin of linefeed-printing loop:
ao          Print a linefeed.
1-          Decrement N.
:i)         Check whether it's still non-negative (gives 0 or 1).
            The next bit is essentially the same loop structure as above,
            but with loop length 22 and offset 22:
0$
b2**
b2*+
&:&*
.         Jump. If N isn't -1 yet, this repeats the inner loop. Otherwise
          we continue right here.
          Begin of space-clearing loop:
~           Discard the top of the stack. On the first iteration this is the
            -1 from the previous loop. Afterwards, it's one of the spaces
            representing an empty line.
:84*)       Check if the top of the stack is a space.
            And another loop conditional. This one works the other way round:
            the difference is 54, which is the distance between the beginning
            of this loop and the main loop. The offset is the beginning
            of this loop, at 22 as above.
0$
96**
b2*+
&:&*
.         Jump. If the top of the stack is still a space this repeats the 
          inner loop. Otherwise we continue from the top of the main loop.

Yığın boş olduğunda program sonlanır ve ilk iç döngü başka bir karakter yazdıramadığında.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.