Saling Negatif yang Timbul

22

Ini terinspirasi oleh Mencetak Negatif Kode Anda dan Golf bersama .


Pertimbangkan segi empat karakter, yang memenuhi batasan berikut:

  1. Hanya terdiri dari karakter ASCII yang dapat dicetak
  2. Dimensi keduanya lebih besar dari 1
  3. Setiap baris dan setiap kolom mengandung setidaknya satu spasi.
  4. Setiap baris dan setiap kolom mengandung setidaknya satu karakter non-spasi.

Misalnya, berikut ini adalah persegi panjang 6x4 yang valid:

%n 2e 
1  g 3
 &* __
 3  

Sebuah negatif untuk persegi panjang ini didefinisikan menjadi persegi panjang dengan ukuran yang sama, dengan semua ruang diganti dengan karakter non-ruang, dan semua karakter non-ruang diganti dengan spasi. Negatif dari persegi panjang di atas adalah:

  f  ^
 33 > 
9  $  
^ }|Q'

Karakter ASCII yang dapat dicetak tanpa spasi dapat digunakan untuk mengganti spasi.

Tugas

Tugas Anda adalah menulis program dengan kode sumber persegi panjang, yang menampilkan negatif yang valid untuk dirinya sendiri. Output negatif juga harus merupakan program yang valid, dalam bahasa yang sama dengan yang asli, dan itu harus menampilkan sumber yang asli.

Tidak ada spasi spasi tambahan dapat ditambahkan atau dihapus, kecuali untuk baris tambahan tunggal di akhir dari salah satu output, yang merupakan opsional.

Tidak ada program yang diizinkan membaca kode sumber dari keduanya; lingkungan REPL juga tidak dapat diasumsikan.

Mencetak gol

Skor Anda adalah produk dari dimensi kode Anda (yaitu jika kode sumber Anda dalam persegi panjang 12 dengan 25, skor Anda adalah 12 * 15 = 180). Selain itu, untuk setiap karakter yang digunakan dalam komentar, skor Anda meningkat 2 (Jika Anda menggunakan /* .. */satu kali dalam kode Anda, dan kode Anda dalam persegi panjang 10 kali 10, skor Anda akan menjadi 10 * 10 + 8 * 2 = 116).

Skor terendah menang.

Jika ada dasi, pengajuan dengan jumlah ruang paling sedikit dalam program (baik yang asli atau negatif, yang memiliki ruang lebih sedikit) menang.

Jika masih ada seri, jawaban sebelumnya akan menang.

Ada bonus -52% , jika menggabungkan yang asli dan negatif bersama-sama menghasilkan quine normal. Sebagai contoh:

Original   Negative   Combined
 A A       B B        BABA
A A         B B       ABAB
es1024
sumber
@Optimizer Itulah alasan saya tidak membuat bonus wajib.
es1024
1
Saya hanya berbicara tentang bagian rujukan negatif yang negatif;)
Pengoptimal
@ MartinBüttner Ah, salahku. Saya berpikir secara aneh.
Pengoptimal
1
Adakah yang bisa melakukan ini di c? Beri +1 kepada siapa pun yang pertama kali!
MegaTom

Jawaban:

15

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

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

Menjalankan kode di atas memberikan output ini:

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

menjalankan yang, mencetak kembali sumber aslinya.

Sumber dan output hanya bertukar baris.

Sekarang tiba keajaiban.

Tumpang tindih sumber dan hasil keluaran ke dalam kode berikut:

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

yang merupakan quine sempurna!

Cobalah secara online di sini


Bagaimana itu bekerja

Semua logika pencetakan berada di baris pertama itu sendiri yang menangani ketiga kasus yang dijelaskan kemudian.

{])"_~"+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";

Array pada baris terakhir di atas adalah array yang memiliki blok kode yang sesuai dengan ketiga case.

Kasus 1

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

Dalam hal ini, panjang tumpukan yang tersisa adalah 0 karena ketika blok dieksekusi, ia hanya memiliki salinan blok itu sendiri, yang awalnya muncul pada langkah ketiga di atas. Jadi kami mengambil indeks 0dari array terakhir dan menjalankannya:

 {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";

Dalam hal ini, baris kedua adalah no-op sejauh mencetak output yang bersangkutan.

Kasus 2

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

Dalam kasus ini, tumpukan sudah berisi string kosong, jadi ketika blok kode yang disalin dieksekusi, ia memiliki 2 elemen - string kosong dan blok kode itu sendiri. Jadi kami mengambil indeks 1dari array terakhir dan menjalankannya:

{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";

Kasus 3

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

Dalam hal ini, tumpukan memiliki 6 elemen. Jadi setelah memunculkan blok kode terakhir, panjang array tersisa adalah 5. Kami mengeluarkan indeks 5dari array dan menjalankannya. (Perhatikan bahwa dalam array 3elemen, indeks 5adalah indeks 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";
Pengoptimal
sumber
27

Python, 97x2 + 2 = 196

Bukan solusi yang bagus untuk memulai, tetapi setidaknya itu berhasil (saya pikir).

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

Keluaran:

                                                                                                #
c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%0) 
grc
sumber
8
+1 untuk pengajuan satu-satunya sejauh ini untuk menggunakan bahasa nyata
WinnieNicklaus
Sepertinya tidak terlalu jauh dari bonus juga.
mbomb007
23

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

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

yang mencetak

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

Karakter non-spasi di setiap baris tetap sama di antara kedua quine yang sama.

Tetapi sekarang bagian yang sangat manis:

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

adalah quine! :)

Uji di sini.

Bagaimana itu bekerja

Saya sarankan Anda membaca penjelasan pada kiriman saya yang lain terlebih dahulu, karena menjelaskan dasar-dasar quining di CJam secara umum.

Yang ini agak rumit. Untuk quine timbal balik, seperti dalam kasus lain, saya memodifikasi representasi string dari blok dengan menambahkan spasi sebelum atau setelah setiap baris, dan menukar 0 dengan 2, sehingga program yang dihasilkan menempatkan spasi di ujung yang berlawanan.

Perhatikan bahwa spasi sama sekali tidak memengaruhi quesi bersama. Yang pertama, mereka berada di blok, yang tidak benar-benar digunakan, dan yang kedua mereka berada di seluruh kode.

Untuk mendapatkan quine reguler ketika menggabungkan keduanya, kita perlu menemukan cara untuk menghindari melakukan semua modifikasi itu. Perhatikan bahwa struktur spasi dan kode berarti bahwa dengan menggabungkan keduanya, kami memasukkan keseluruhan satu quine ke yang lainnya. Jadi, jika kita menempatkan seluruh kode modifikasi dalam satu blok, kita dapat menjalankan blok itu tergantung pada isi sebenarnya.

Jadi sekarang saya punya blok ini ... untuk quines mutual, hanya berisi kode yang sebenarnya ingin saya jalankan. Untuk gabungan quine, ini juga berisi seluruh quine lagi, dalam posisi acak, yang tidak masuk akal ... tetapi karena ini adalah sebuah blok, itu tidak berjalan secara otomatis. Jadi kita dapat menentukan apakah akan memodifikasi string berdasarkan pada isi blok itu. Itu untuk apa _`'"#)!. Ini menduplikasi blok, mengonversinya menjadi string, mencari karakter "(yang, dalam quines mutual, hanya muncul di luar blok) - pencarian kembali -1jika karakter tidak ditemukan dan bilangan bulat positif sebaliknya -, menambah hasilnya dan meniadakannya secara logis. Jadi jika "ditemukan ini menghasilkan, 0jika tidak maka akan menghasilkan 1. Sekarang kita lakukan saja*, yang mengeksekusi blok sekali, jika hasilnya 1 dan tidak sama sekali sebaliknya.

Akhirnya, ini adalah cara kerja kode modifikasi:

_,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.";

Mengklaim Bounty, (12 x 10) * 48% = 57,6

Ternyata kode ini dapat dibagi lebih banyak baris dengan sangat mudah dengan beberapa modifikasi. Kami menambahkan 2 karakter, untuk mendapatkan 48 berturut-turut, yang kemudian dapat dengan mudah kita bagi dengan 8, sehingga kita memiliki 8 baris dengan 6 karakter kode dan 6 spasi. Untuk melakukan itu kita juga perlu mengubah beberapa angka, dan mengatur ulang satu atau dua operator, sehingga tidak terpecah di kedua saluran. Itu memberi kita versi yang berfungsi dengan ukuran 12 x 8 ... satu dari persyaratan. Jadi kami hanya menambahkan dua baris yang tidak melakukan apa-apa (tekan 1, pop 1, push 1, pop 1), jadi dapatkan 12 x 10 :

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

Seperti yang sebelumnya ini menghasilkan

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

(Catatan: tidak perlu untuk tetap berganti-ganti kiri dan kanan pada garis tengah, hanya posisi baris pertama dan terakhir yang penting. Kiri dan kanan dapat dipilih secara sewenang-wenang untuk semua jalur lainnya.)

Dan melalui kebetulan murni, quine lengkap juga masih berfungsi:

{`"_~"{`"_~"
+{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*
}_`'"#}_`'"#      
)!*}_~)!*}_~

(Saya katakan kebetulan, karena bagian yang mengurus tidak mengeksekusi kode batin sekarang anehnya diselingi dengan quine yang lain, tetapi masih terjadi dengan baik.)

Yang sedang berkata, saya bisa saja menambahkan 44 baris 1;ke kiriman asli saya untuk memenuhi persyaratan karunia, tetapi 12 x 10terlihat jauh lebih rapi. ;)

Sunting: Haha, ketika saya mengatakan "kebetulan murni" saya tidak bisa lebih tepat. Saya melihat bagaimana quine terakhir sekarang benar-benar berfungsi, dan ini benar-benar menggelikan. Ada tiga blok bersarang (sebenarnya 4, tetapi yang paling dalam tidak relevan). Satu-satunya bagian penting dari terdalam dari 3 blok itu adalah bahwa ia berisi "(dan bukan yang ia lakukan dalam penyerahan asli, tetapi '"yang digunakan pada akhirnya untuk memeriksa karakter yang sama). Jadi struktur dasar quine adalah:

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

Mari kita membedah itu:

{`"_~"                               }_~ "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.";

Jadi ini memang melakukan sihir lucu, tetapi karena blok bagian dalam meninggalkan string tunggal di tumpukan, )!*kebetulan mengubahnya menjadi string kosong. Satu-satunya syarat adalah bahwa hal-hal di blok dalam setelah +tidak melakukan hal lain ke stack, jadi mari kita lihat itu:

             {___'"___}                  "Push a block which happens to contain 
                                          quotes.";
                       _`'"#)!*          "This is from the original code and just 
                                          removes the block if it does contain 
                                          quotes.";
Martin Ender
sumber
4
TLDR; upvote;)
Pengoptimal
Bukankah seharusnya Y/2di quine gabungan?
schnaader
"Dan melalui kebetulan murni" nah;)
Timtech
@Timtech Lihat hasil edit saya. Kebetulan murni bukanlah pernyataan yang meremehkan. ^^
Martin Ender
10

CJam, 42 37 33 x 2 = 66

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

yang mencetak

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

(Garis ditukar, dan 1berubah menjadi 0.)

Uji di sini.

Bagaimana itu bekerja

Pertama, Anda harus memahami quine CJam dasar:

{"_~"}_~

Kawat gigi hanya mendefinisikan blok kode, seperti fungsi, yang tidak segera dieksekusi. Jika blok yang tidak dieksekusi tetap ada di stack, kode sumbernya (termasuk kawat gigi) dicetak. _menduplikasi blok, dan ~mengeksekusi salinan kedua. Blok itu sendiri hanya mendorong string yang berisi _~. Jadi kode ini, meninggalkan tumpukan dalam status berikut:

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

Blok dan string hanya dicetak kembali-ke-belakang di akhir program, yang menjadikan ini quine.

Keindahan ini adalah bahwa kita dapat melakukan apa pun yang kita inginkan di blok, dan itu tetap menjadi quine, karena setiap bagian dari kode secara otomatis akan dicetak dalam isi blok. Kita juga dapat memodifikasi blok, dengan memperoleh representasi string dengan `(yang hanya string blok dengan kawat gigi).

Sekarang mari kita lihat solusi ini. Perhatikan bahwa salah satu bagian dari quine mutual berisi blok mirip quine dengan _~, dan a L. The Lmendorong string kosong ke dalam stack, yang tidak memberikan kontribusi output. Jadi inilah yang dilakukan oleh blok:

`                             "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.";

Jadi ini akan melakukan bagian quine, tetapi menukar 1 untuk 0, dan juga akan menambahkan baris lain dengan L, di mana kode di atas memiliki spasi. Tangkapannya adalah bahwa urutan kedua garis ditentukan oleh pertukaran di dalam { }*. Dan karena bagian terluar dari quine mutual 0di depannya diganti dengan a 1, ia tidak pernah melakukan swap ini, dan karenanya menghasilkan orde asli lagi.

Martin Ender
sumber
5

CJam, 27 × 2 = 54

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

Keluaran:

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

'A'B>membandingkan karakter A dan B. ' '\n >mengembalikan 1 karena 32> 10 dan ' \n' >mengembalikan 0 karena kedua spasi sama.

jimmy23013
sumber
2

CJam, 30 29 x 2 = 58

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

Output:

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

yang menampilkan sumber aslinya.

Ini didasarkan pada prinsipal yang sama dengan solusi saya yang lain.

Cobalah online di sini

Pengoptimal
sumber