Karşılıklı Negatif Quines


22

Bu, Kodunuzun Negatifini Yazdır ve karşılıklı bir inine Golf'den ilham almıştır .


Aşağıdaki kısıtlamaları karşılayan bir karakter dikdörtgeni göz önünde bulundurun :

  1. Yalnızca yazdırılabilir ASCII karakterlerinden oluşur
  2. 1'den büyük boyutlar
  3. Her satır ve her sütun en az bir boşluk içerir.
  4. Her satır ve her sütun en az bir boşluksuz karakter içeriyor.

Örneğin, aşağıdaki geçerli bir 6x4 dikdörtgendir:

%n 2e 
1  g 3
 &* __
 3  

Bir negatif tüm alanlarda boşluk olmayan karakterleri ile ikame ile dikdörtgen için, eşit boyutlarda bir dikdörtgen olarak tanımlanır ve olmayan tüm uzay karakterler boşluk ile yer değiştirir. Yukarıdaki dikdörtgenin bir negatif olabilir:

  f  ^
 33 > 
9  $  
^ }|Q'

Boşluk için yazdırılabilir herhangi bir ASCII karakteri, boşluğu değiştirmek için kullanılabilir.

Görev

Göreviniz, kendisine geçerli bir negatif çıktı veren dikdörtgen kaynak kodlu bir program yazmaktır. Çıktılan negatif, orijinal ile aynı dilde geçerli bir program olmalı ve orijinalin kaynağını vermelidir.

Her iki çıktının sonunda, isteğe bağlı tek bir izleyen yeni satır dışında hiçbir iz boşluğu eklenemez veya kaldırılamaz.

Her iki programın da kaynak kodunu okumasına izin verilmez; REPL ortamları da kabul edilemez.

puanlama

Puanınız, kodunuzun boyutlarının ürünüdür (yani kaynak kodunuz 12 x 25 dikdörtgen ise, puanınız 12 * 15 = 180'dir). Ek olarak, bir yorumda kullanılan her karakter için, puanınız 2 artar ( /* .. */Kodunuzda bir kez kullanırsanız ve kodunuz 10'a 10'luk bir dikdörtgen ise, puanınız 10 * 10 + 8 * 2 = 116 olur).

En düşük puan kazanır.

Bir beraberlik varsa, programda en az sayıda boşluk bulunan gönderme (orijinal veya negatif olan hangisi daha az alana sahipse) kazanır.

Hala bir kravat kalırsa, önceki cevap kazanacaktır.

Orijinal ile negatifin bir araya getirilmesi normal bir kın üreterse, % -52'lik bir bonus vardır . Örneğin:

Original   Negative   Combined
 A A       B B        BABA
A A         B B       ABAB

@Optimizer Bu bonusu zorunlu hale getirmememin nedeni bu.
es1024

1
Sadece olumsuz karşılıklı bölümden bahsediyorum;)
Doktor

@ MartinBüttner Ah, benim hatam. Garip terimlerle düşünüyordum.
Doktor

1
Bunu kimse c olarak yapabilir mi? İlk kim yapacaksa +1!
MegaTom

Yanıtlar:


15

CJam, ( 51 49 47 46 45 42 x 2) *% 48 = 40.32

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

Yukarıdaki kodu çalıştırmak bu çıktıyı verir:

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

hangi çalışan, orijinal kaynağı geri yazdırır.

Kaynak ve çıktı basitçe değiştirilmiş çizgilerdir.

Şimdi sihir geliyor.

Kaynak ve çıktının üst üste binmesi aşağıdaki koda yol açar:

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

Bu mükemmel bir quine!

Onları burada çevrimiçi deneyin


Nasıl çalışır

Tüm yazdırma mantığı, daha sonra açıklanacak olan her üç vakanın da üstesinden gelen ilk satırdadır.

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~
{                                     }_~   "Copy this code block and execute the copy";
 ]                                          "Wrap everything before it in array";
  )                                         "Pop the last element out of it";
   "_~"+                                    "Append string '_~' to the copied code block";
        S41*                                "Create a string of 41 spaces";
            'R+                             "Append character R to it";
               @,                           "Rotate the array to top and get its length";
                 [{   }{   }{     }]=~      "Get the corresponding element from this"
                                            "array and execute it";

Yukarıdaki son satırdaki dizi, üç durumun hepsine karşılık gelen kod bloklarını içeren dizidir.

Dava 1

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

Bu durumda, kalan yığının uzunluğu, blok yürütüldüğü haliyle 0 idi, yalnızca ilk olarak yukarıdaki üçüncü adımda çıkarılan bloğun bir kopyası vardı. Böylece dizini 0son diziden çıkarır ve çalıştırırız:

 {N@S}          "Note that at this point, the stack is something like:"
                "[[<code block that was copied> '_ '~ ] <41 spaces and R string>]";
  N             "Add newline to stack";
   @            "Rotate the code block to top of stack";
    S           "Put a trailing space which negates the original R";

Bu durumda, ikinci satır, çıktının yazdırılması ile ilgili olarak no-op'tur.

Durum 2

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

Bu durumda, yığın zaten boş bir dize içeriyordu, bu nedenle kopyalanan kod bloğu yürütüldüğünde 2 öğeye sahipti - boş bir dize ve kod bloğunun kendisi. Böylece dizini 1son diziden çıkarır ve çalıştırırız:

{SN@}            "Note at this point, the stack is same as in case 1";
 SN              "Push space and newline to stack";
   @             "Rotate last three elements to bring the 41 spaces and R string to top";

3. Durum

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

Bu durumda, yığında 6 element vardır. Son kod bloğunu açtıktan sonra, kalan dizi uzunluğu 5'tir. Dizini 5diziden çıkarır ve çalıştırırız. (Bir 3eleman dizisinde , indeksin indeks 5olduğuna dikkat edin 5%3 = 2)

{W=N]_}          "Note at this point, the stack is same as in case 1";
 W=              "Take the last character out of the 41 spaces and R string, i.e. R";
   N]            "Add a new line to stack and wrap the stack in an array";
     _           "Copy the array to get back the source of Case 3 itself";

27

Python, 97x2 + 2 = 196

Başlamak için harika bir çözüm değil, ama en azından işe yarıyor (bence).

c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%1) 
                                                                                                #

Çıktı:

                                                                                                #
c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%0) 

8
Şimdiye kadar gerçek bir dil kullanmak için yapılan başvuru için +1
WinnieNicklaus

İkramiyeden de çok uzak gözükmüyor.
mbomb007

23

CJam, ( 58 56 54 48 46 x 2) *% 48 = 44.16

{`"_~"+{_,94\m2/S*a_+\*                       
                       N/23f/Wf%N*}_`'"#)!*}_~

hangi yazdırır

                       {`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~                       

Her satırdaki boşluk olmayan karakterler iki karşılıklı kuyruk arasında aynı kalır.

Ama şimdi gerçekten tatlı kısım:

{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~

bir sırtı var! :)

Burada test et.

Nasıl çalışır

Genel olarak CJam'da sorgulamanın temellerini açıkladığı gibi, ilk önce diğer gönderim hakkındaki açıklamayı okumanızı tavsiye ederim.

Bu biraz daha zor. Karşılıklı quine için, diğer durumda olduğu gibi, her satırdan önce veya sonra boşluk ekleyerek ve 2 ile 0 değiştirerek bloğun dize gösterimini değiştiririm, böylece ortaya çıkan program boşlukları zıt uca koyar.

Boşlukların karşılıklı kuyrukları hiç etkilemediğini unutmayın. İlki, gerçekten kullanılmayan bir blokta, ikincisi ise tüm kodun etrafında.

Her ikisini de birleştirirken düzenli bir kın elde etmek için, tüm bu değişiklikleri yapmaktan kaçınmanın bir yolunu bulmamız gerekir. Boşluk ve kodun yapısının her ikisini birleştirerek bir quinin tamamını diğerine eklediğimiz anlamına geldiğine dikkat edin. Bu yüzden, tüm modifikasyon kodunu bir bloğa koyarsak, o bloğu gerçek içeriğine bağlı olarak çalıştırabiliriz.

Şimdi bu bloku aldım ... karşılıklı sorgulamalar için, sadece gerçekten çalıştırmak istediğim kodu içeriyor. Kombine quine için, aynı zamanda tüm quine'i de içerir, rastgele bir pozisyonda, hiçbir anlamı yoktur ... ama bir blok olduğundan, otomatik olarak çalışmaz. Böylece dizenin o bloğun içeriğine göre değiştirilip değiştirilmeyeceğini belirleyebiliriz. Bunun _`'"#)!için var. Bloğu çoğaltır, dizgeye dönüştürür, karakter arar "(karşılıklı sorgularda, yalnızca bloğun dışında görünür ) - -1karakter bulunmazsa arama döner ve aksi takdirde pozitif bir tamsayı - sonucu artırır ve mantıksal olarak olumsuzlar. Yani eğer bir a "bulundu ise bu verim 0aksi takdirde verim 1. Şimdi sadece yapıyoruz*, eğer sonuç 1 değilse ve hiç değilse bloğu bir kez çalıştırır.

Son olarak, değişiklik kodu şu şekilde çalışır:

_,94\m2/S*a_+\*N/23f/Wf%N*
_,                         "Duplicate the quine string and get its length.";
  94\m                     "Subtract from 94.";
      2/                   "Divide by two.";
        S*                 "Create a string with that many spaces. This will be
                            an empty string for the first mutual quine, and contain
                            23 spaces for the second mutual quine.";
          a_+              "Create an array that contains this string twice.";
             \*            "Join the two copies together with the quine string.";
               N/          "Split into lines.";
                 23f/      "Split each line into halves (23 bytes each).";
                     Wf%   "Reverse the two halves of each line.";
                        N* "Join with a newline.";

Ödül talep etmek, (12 x 10) *% 48 = 57,6

Bazı değişikliklerle bu kodun daha fazla satıra kolayca bölünebileceği anlaşılıyor. 48'i üst üste almak için 2 karakter ekliyoruz, bu sayede 8'e bölebiliyoruz, böylece 6 karakterlik kodlu ve 6 boşluklu 8 satır var. Bunu yapmak için birkaç rakamı değiştirmemiz ve bir veya iki operatörü yeniden düzenlememiz gerekir, bu yüzden her iki satıra da bölünmezler. Bu bize 12 x 8 boyutunda ... çalışma şartı veriyor . Yani sadece hiçbir şey yapmayan iki satır ekleriz (1'e bas, 1'e bas, 1'e bas, 1'e bas ...), 12 x 10'a :

{`"_~"      
      +{129X
$,m2/S      
      *a_+\*
N/6f/1      
      ;1;1;1
;1;1;1      
      ;Wf%N*
}_`'"#      
      )!*}_~

Bir öncekinin ürettiği gibi

      {`"_~"
+{129X      
      $,m2/S
*a_+\*      
      N/6f/1
;1;1;1      
      ;1;1;1
;Wf%N*      
      }_`'"#
)!*}_~      

(Yan not: ara satırlarda sağa ve sola dönüşümlü olarak kalmaya gerek yoktur, sadece ilk ve son satırın konumu önemlidir. Sol ve sağ diğer tüm satırlar için keyfi olarak seçilebilir.)

Ve saf tesadüf sayesinde, tam bir de hala çalışır:

{`"_~"{`"_~"
+{129X+{129X
$,m2/S$,m2/S
*a_+\**a_+\*
N/6f/1N/6f/1
;1;1;1;1;1;1
;1;1;1;1;1;1
;Wf%N*;Wf%N*
}_`'"#}_`'"#      
)!*}_~)!*}_~

(Tesadüf derim, çünkü iç kodun uygulanmamasına özen gösteren kısım şimdi diğer quine ile garip bir şekilde serpiştirildi, ancak yine de iyi sonuç veriyor.)

Olduğu gibi 1;, lütuf ihtiyacını yerine getirmek için orijinal sunumuma 44 satır ekleyebilirdim, ama 12 x 10çok daha düzgün görünüyor. ;)

Düzenleme: Haha, "saf tesadüf" dediğimde daha fazla yer alamazdım. Son sıranın gerçekten nasıl çalıştığını araştırdım ve kesinlikle saçma. Üç iç içe blok (4 aslında, ancak en içteki önemsiz) vardır. Bu 3 bloğun en iç kısımlarının tek önemli kısmı, içerdiği "(orijinal gönderimde yaptıkları değil '", sonunda aynı olanı kontrol etmek için kullanılanlar) içermesidir . Yani, sıranın temel yapısı:

{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~

Bunu parçalayalım:

{`"_~"                               }_~ "The standard CJam quine.";
      {`"_~"+                  }_~       "Another CJam quine. Provided it doesn't do 
                                          anything in the rest of that block, this 
                                          will leave this inner block as a string on 
                                          the stack.";
                                  )      "Slice the last character off the string.";
                                   !     "Negate... this yields 0.";
                                    *    "Repeat the string zero times.";

Yani bu gerçekten komik bir sihir yapar, ama iç blok yığında tek bir dize bıraktığı için, )!*bunu boş bir dize dönüştürür. Tek koşul, iç bloktaki öğelerin +yığında başka bir şey yapmamasıdır, o yüzden şuna bakalım:

             {___'"___}                  "Push a block which happens to contain 
                                          quotes.";
                       _`'"#)!*          "This is from the original code and just 
                                          removes the block if it does contain 
                                          quotes.";

4
TLDR; upvote;)
Doktor

Y/2Kombine sırada mı olmamalı ?
schnaader

"Ve saf tesadüf yoluyla" nah;)
Timtech

@Timtech Düzenlememe bakın. Saf tesadüf bir understatement değildi. ^^
Martin Ender

10

CJam, 42 37 33 x 2 = 66

{`As_W%er"_~"+S 33*F'Lt1{\}*N\}_~
               L                 

hangi yazdırır

               L                 
{`As_W%er"_~"+S 33*F'Lt0{\}*N\}_~

(Satırlar değiştirilir ve a ile 1döner 0.)

Burada test et.

Nasıl çalışır

İlk önce, temel CJam quine'i anlamalısınız:

{"_~"}_~

Parantezler, hemen çalıştırılmayan bir fonksiyon bloğu gibi sadece bir kod bloğunu tanımlar. Beklenmeyen bir blok yığında kalırsa, kaynak kodu (kaşlı ayraçlar dahil) yazdırılır. _bloğu çoğaltır ve ~ikinci kopyayı yürütür. Bloğun kendisi basitçe içeren dizeyi iter _~. Yani bu kod, yığını aşağıdaki durumda bırakır:

Stack: [{"_~"} "_~"]

Blok ve dize, programın sonunda basitçe arka arkaya yazdırılır;

Bunun güzelliği, blokta ne istersek yapabileceğimiz ve bunun bir parçası olarak kalmamızdır, çünkü her kod parçası otomatik olarak blok içeriğinde basılacaktır. Ayrıca bloğu değiştirebiliriz, bununla dizge gösterimini elde ederiz `(bu sadece parantezli bloğun bir dizisidir).

Şimdi bu çözüme bakalım. Karşılıklı kuyruğun herhangi bir bölümünün _~, ve ile bir sorgu benzeri blok içerdiğini unutmayın L. LÇıkışına katkıda bulunmayan yığını üzerine boş bir dize iter. İşte bloğun yaptığı şey:

`                             "Convert block to its string representation.";
 As                           "Push 10 and convert to string.";
   _W%                        "Duplicate and reverse, to get another string 01.";
      er                      "Swap 0s and 1s in the block string.";
        "_~"+                 "Append _~.";
             S 33*            "Push a string with 33 spaces.";
                  F'Lt        "Set the character at index 15 to L.";
                      1{ }*   "Repeat this block once.";
                        \     "Swap the code string and the space string.";
                           N\ "Push a newline and move it between the two lines.";

Böylece bu, kısmi kısmı yapacak, ancak 0 için 1 değiş tokuş yapacak ve Lyukarıdaki kodun bir boşluğa sahip olduğu bir ile bir başka satır daha hazırlayacaktır . Yakalama, bu iki çizginin sırasının, içerdeki yer değiştirmeyle belirlenmesidir { }*. Karşılıklı kıskacın dış kısmı 0önündeki a ile değiştirildiği için 1, bu takas işlemini asla gerçekleştirmez ve bu nedenle orijinal düzeni tekrar üretir.


5

CJam, 27 × 2 = 54

{ ` " _ ~ " + N - ) 2 * ' '
 > @ t s G B + / N * } _ ~ 

Çıktı:

 { ` " _ ~ " + N - ) 2 * ' 
' > @ t s G B + / N * } _ ~

'A'B>A ve B karakterlerini karşılaştırır, ' '\n >çünkü 1> 32 ' \n' >döndürür, 10 ve iki boşluk olduğundan eşit 0 döndürür.


2

CJam, 30 29 x 2 = 58

{"_~"SN]_,4=S28*'R+\{N@}*}_~ 
                            R

Çıktılar:

                            R
{"_~"SN]_,4=S28*'R+\{N@}*}_~ 

Bu, orijinal kaynağı veren çıktı.

Bu, benim diğer çözümümle aynı prensibe dayanıyor.

Burada çevrimiçi deneyin

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.