Взаємні негативні лайки


22

Це було натхнене друком негативу коду та гольфу взаємною королевою .


Розглянемо прямокутник символів, який відповідає наступним обмеженням:

  1. Складається виключно з символів для друку ASCII
  2. Розміри обидва більше 1
  3. Кожен рядок і кожен стовпець містять щонайменше один пробіл.
  4. Кожен рядок і кожен стовпець містять щонайменше один непробільний символ.

Наприклад, дійсний прямокутник 6x4:

%n 2e 
1  g 3
 &* __
 3  

Негативний для цього прямокутника визначаються як прямокутник рівних розмірів, причому всі простори замінюються некосмічних символами, і все без пробілу замінені пробілами. Негативом вищевказаного прямокутника може бути:

  f  ^
 33 > 
9  $  
^ }|Q'

Будь-який символ ASCII, який можна друкувати, не може бути використаний для заміни пробілу.

Завдання

Ваше завдання - написати програму з прямокутним вихідним кодом, яка виводить на себе дійсний мінус. Виведений мінус також повинен бути дійсною програмою на тій же мові, що й оригінал, і він повинен виводити джерело оригіналу.

Жодне пробільне пробіл не може бути додане чи видалене, за винятком одного останнього нового рядка в кінці будь-якого виводу, що є необов'язковим.

Жодна програма не може читати вихідний код будь-якого; також не можна припускати середовищ REPL.

Оцінка балів

Ваш бал - це добуток розмірів вашого коду (тобто, якщо ваш вихідний код знаходиться у прямокутнику 12 на 25, ваш результат дорівнює 12 * 15 = 180). Крім того, для кожного символу, який використовується в коментарі, ваш бал збільшується на 2 (Якщо ви використовуєте /* .. */один раз у своєму коді, а ваш код у прямокутнику 10 на 10, ваш результат буде 10 * 10 + 8 * 2 = 116).

Виграє найнижчий бал.

Якщо є нітка, виграє подання з найменшою кількістю пробілів у програмі (оригіналом чи мінусом), залежно від того, що має менше пробілів).

Якщо все-таки залишається нічия, попередня відповідь виграє.

Бонус становить -52% , якщо поєднання оригіналу та негативу разом дає нормальну квітку. Наприклад:

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

@Optimizer Ось чому я не зробив бонус обов'язковим.
es1024

1
Я говорю про лише негативну взаємну частину квіна;)
Оптимізатор

@ MartinBüttner Ах, моє погано. Я думав дивними словами.
Оптимізатор

1
Хтось може це зробити в c? +1 тому, хто буде першим!
MegaTom

Відповіді:


15

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

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

Запуск вищевказаного коду дає такий вихід:

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

запускаючи який, виводить назад початкове джерело.

Джерело та вихід є просто заміненими лініями.

Тепер настає магія.

Перекриття вихідного та вихідного результатів у наступний код:

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~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";

Масив в останньому рядку вище - це масив, який містить кодові блоки, що відповідають усім трьом випадкам.

Випадок 1

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

У цьому випадку довжина стека, що залишилася, становила 0, як тоді, коли блок був виконаний, він мав лише копію самого блоку, яка спочатку вискакувала на третьому кроці вище. Отже, ми виймаємо індекс 0з останнього масиву і виконуємо його:

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

У цьому випадку другий рядок є неоперативним, що стосується друку вихідних даних.

Випадок 2

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

У цьому випадку стек вже містив порожній рядок, тому коли виконувався скопійований блок коду, він мав 2 елементи - порожній рядок і сам блок коду. Отже, ми виймаємо індекс 1з останнього масиву і виконуємо його:

{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

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

У цьому випадку стек має 6 елементів. Отже, після вискакування останнього кодового блоку, залишилася довжина масиву дорівнює 5. Ми виймаємо індекс 5з масиву і виконуємо його. (Зверніть увагу, що в масиві 3елементів індекс 5- це індекс 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

Пітон, 97х2 + 2 = 196

Не чудове рішення починати, але принаймні це працює (я думаю).

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

Вихід:

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

8
+1 за єдине досі подання, яке використовує справжню мову
WinnieNicklaus

Це також не здається занадто далеко від бонусу.
mbomb007

23

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

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

який друкує

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

Непробільні символи в кожному рядку залишаються однаковими між двома взаємними ладами.

Але тепер справді мила частина:

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

це королева! :)

Перевірте це тут.

Як це працює

Рекомендую спочатку ознайомитись з поясненнями щодо мого іншого подання, оскільки це загалом пояснює основи квінінгу в CJam.

Цей трохи складніше. Для взаємного quine, як і в іншому випадку, я змінюю представлення рядка блоку, додаючи пробіли перед або після кожного рядка і замінюючи 0 на 2, так що отримана програма ставить пробіли в протилежний кінець.

Зауважте, що пробіли взагалі не впливають на взаємні лайки. У першому вони знаходяться в блоці, який насправді не використовується, а в другому - навколо всього коду.

Щоб отримати звичайну квітку при поєднанні обох, нам потрібно знайти спосіб уникнути внесення всіх цих модифікацій. Зауважте, що структура білого простору та коду означає, що, поєднуючи обидва, ми вставляємо цілість однієї квітки в іншу. Отже, якщо ми помістимо весь код модифікації в блок, ми можемо запустити цей блок залежно від його фактичного вмісту.

Отже, тепер у мене є цей блок ... для взаємних лайків він містить лише код, який я насправді хочу запустити. Для комбінованої квінти вона також містить всю квінку знову, у випадковому положенні, що не має сенсу ... але оскільки це блок, він не запускається автоматично. Таким чином, ми можемо визначити, чи слід змінювати рядок на основі вмісту цього блоку. Ось для чого _`'"#)!. Він дублює блок, перетворює його в рядок, шукає символу "(який у взаємних лавах з’являється лише поза блоком) - пошук повертається, -1якщо символ не знайдено, а додатне ціле число в іншому випадку - збільшує результат і логічно заперечує це. Отже, якщо "знайдено a, це дає результат, 0інакше він дає результат 1. Тепер ми просто робимо*, який виконує блок один раз, якщо результат був 1, а зовсім не інакше.

Нарешті, ось як працює модифікуючий код:

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

Претензія на винагороду, (12 х 10) * 48% = 57,6

Виявляється, цей код можна легко розділити на кілька рядків за допомогою деяких модифікацій. Додаємо 2 символи, щоб отримати 48 підряд, які потім можна зручно розділити на 8, щоб у нас було 8 рядків із 6 символами коду та 6 пробілами. Для цього нам також потрібно змінити кілька чисел і переставити оператора або двох, щоб вони не розділилися на обидва рядки. Це дає нам працюючу версію розміром 12 х 8 ... одна вимога. Таким чином, ми просто додаємо два рядки, які нічого не роблять (push 1, pop a 1, push 1, pop a 1 ...), тож переходимо до 12 x 10 :

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

Як і попередній, це виробляє

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

(Бічна примітка: немає необхідності тримати чергування лівого і правого на проміжних лініях, важливі лише положення першого та останнього рядків. Лівий і правий можна обирати довільно для всіх інших рядків.)

І за чистим збігом обставин повна quine також все ще працює:

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

(Я кажу збіг обставин, тому що частина, яка піклується про невиконання внутрішнього коду, зараз дивно перемежовується з іншою лайкою, але все одно виходить добре.)

Коли це було сказано, я міг би лише додати 44 рядки 1;до мого оригінального подання, щоб виконати вимогу щедрості, але 12 x 10виглядає набагато акуратніше. ;)

Редагувати: Ха-ха, коли я сказав "чистий збіг", я не міг бути більше на місці. Я роздивився, як працює насправді фінальна квітка, і це абсолютно смішно. Є три вкладені блоки (насправді 4, але внутрішній не має значення). Єдина важлива частина найпотаємнішого з цих 3 блоків - це те, що він містить "(і не той, який був зроблений в оригінальному поданні, а той самий, '"який використовується в кінці для перевірки наявності цього самого символу). Отже, основна структура квінки така:

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

Розберемо, що:

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

Таким чином, це дійсно робить деякі кумедні магії, але оскільки внутрішній блок залишає одну стежку на стеку, )!*трапляється перетворювати це в порожній рядок. Єдина умова - це те, що матеріал у внутрішньому блоці після +цього не робить нічого іншого до стека, тому давайте подивимось на це:

             {___'"___}                  "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;)
Оптимізатор

Чи не повинно бути Y/2в комбінованій квінці?
шнадер

"І за чистим збігом обставин" нах;)
Timtech

@Timtech Дивіться мою редакцію. Чистий збіг не був заниженням. ^^
Мартін Ендер

10

CJam, 42 37 33 x 2 = 66

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

який друкує

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

(Рядки міняються місцями, а 1перетворення на а 0.)

Перевірте це тут.

Як це працює

По-перше, ви повинні зрозуміти основні CJam quine:

{"_~"}_~

Дужки просто визначають блок коду, як функцію, яка не виконується відразу. Якщо невиконаний блок залишається в стеці, його друкується вихідний код (включаючи дужки). _дублює блок і ~виконує другу копію. Сам блок просто висуває рядок, що містить _~. Отже цей код залишає стек у наступному стані:

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

Блок і рядок просто надрукуються спиною до спини в кінці програми, що робить це королевою.

Краса цього полягає в тому, що ми можемо робити все, що завгодно, в блоці, і це залишається лайкою, тому що кожен фрагмент коду автоматично буде надрукований у вмісті блоку. Ми також можемо модифікувати блок, отримавши його рядкове представлення `(що є лише рядком блоку з дужками).

Тепер розглянемо це рішення. Зауважте, що будь-яка частина взаємної квінки містить хиноподобный блок з _~і L. LШтовхає порожній рядок в стек, який не сприяє виходу. Отже, ось що робить блок:

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

Таким чином, це зробить частину quine, але обміняє 1 на 0, а також додасть ще один рядок з an L, де в коді вище є пробіл. Суть полягає в тому, що порядок цих двох ліній визначається заміною всередині { }*. А оскільки зовнішня частина взаємної квінки має 0передню частину заміненою на a 1, вона ніколи не виконує цю заміну, а значить, знову виробляє початковий порядок.


5

CJam, 27 × 2 = 54

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

Вихід:

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

'A'B>порівнює символи A і B. ' '\n >повертає 1, тому що 32> 10 і ' \n' >повертає 0, оскільки два пробіли рівні.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.