Interquine - дві програми, які виводять один одного в циклі


29

Програма A видає код програми B під час запуску, а B видає джерело A.

Вимоги:

  • Лише одна мова в обох програмах
  • Програми різні. Одна програма, яка виводить себе, не кваліфікується.
  • Обидві програми не пусті або мають принаймні 1 байт. Затримка нових рядків як у вихідному, так і у вихідному даних ігнорується
  • stdin закритий. Нічого не читайте (щоб ви не могли прочитати джерело і не маніпулювати ним). Вихід йде на stdout.
    Редагувати: stdin підключено до /dev/null. Ви можете замовити його закрити, якщо уточнено.
  • Не використовуйте randomфункції.

Додатково:

  • Дайте пояснення, якщо це можливо

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



5
"Не використовувати випадкові функції." Що ви маєте на увазі? Функції, що виводять випадкове число?
Містер Xcoder


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

Відповіді:


18

CJam , 13 + 13 = 26 байт

{sYZe\"_~"}_~

Спробуйте в Інтернеті!

Виходи

{sZYe\"_~"}_~

Пояснення

{       e# Standard quine framework, leaves a copy of the block on the stack
        e# for the block itself to process.
  s     e# Stringify the block.
  YZe\  e# Swap the characters at indices 2 and 3, which are Y and Z themselves.
  "_~"  e# Push the "_~" to complete the quine.
}_~

Оскільки e\є комутативним у своєму другому та третьому операндах, інша програма робить точно так само, змінюючи Zта Yповертаючись у свій початковий порядок.


17

CJam ,11 + 13 = 24 11 + 12 = 23 байти

"N^_p"
N^_p

Спробуйте в Інтернеті!

Виходи:

"N^_p
"
N^_p

Вихід має 13 байт, але:

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

Тому я змінив простір на новий рядок, щоб скористатися цим.

Він заснований на найкоротшій власній кінці CJam:

"_p"
_p

І N^полягає в тому, щоб зв'язати рядок новим рядком, який додає новий рядок, якщо немає нового рядка, і видалити його, якщо є, для рядка, що кожен символ є унікальним.

Я думаю, що я бачив цю квінку у питанні про ангіну, але не зміг її знайти.


+1 за наявність двох програм різного розміру, на відміну від усіх інших відповідей поки що. Редагувати: як тільки я можу знову проголосувати .. досяг граничної межі останнього голосування>.>
Кевін Круїйсен

Добре, що відрізняється довжиною.
iBug

"Я думаю, що я бачив цю квінку у питанні про квіточку, але не зміг її знайти". Це згадується лише у відповіді GolfScript.
Мартін Ендер

12

RProgN 2 , 3 + 3 = 6 байт

Перша програма:

0
1

Спробуйте в Інтернеті!

Друга програма:

1
0

Спробуйте в Інтернеті!

-2 завдяки Мартіну Ендеру .


7
Ви можете зберегти два байти, змінивши мови: tio.run/##Kyooyk/P0zX6/9@Ay/D/fwA
Мартін Ендер

@MartinEnder Так, я забув, що RProgN 2 демонструє таку поведінку ... btw Я не знаю, якщо це все-таки баггі.
Erik the Outgolfer

11
Я нічого не знаю про RProgN, крім того, що така поведінка існує.
Мартін Ендер

@MartinEnder Автор RProgN тут, просто запитайте, чи потрібно вам щось уточнено!
Атако

@ATaco Ну, я б попросив вас уточнити протилежний результат, але я не думаю, що ви зможете ...
Ерік Атголфер

6

C, 95 + 95 = 190 байт

Дякуємо @immibis за економію 16 * 2 байтів!

char*s="char*s=%c%s%c;main(i){i=%d^1;printf(s,34,s,34,i);}";main(i){i=1^1;printf(s,34,s,34,i);}

Спробуйте в Інтернеті!

Виходи:

char*s="char*s=%c%s%c;main(i){i=%d^1;printf(s,34,s,34,i);}";main(i){i=0^1;printf(s,34,s,34,i);}

Спробуйте в Інтернеті!

Які виходи:

char*s="char*s=%c%s%c;main(i){i=%d^1;printf(s,34,s,34,i);}";main(i){i=1^1;printf(s,34,s,34,i);}

1
Чому б просто не називати це С завжди, а покладатися на те, що я змінююсь, щоб програма стала іншою? C коротше, ніж% c
користувач253751

@immibis Так, ви праві, цього достатньо.
Steadybox

5

Javascript, 67 + 67 = 134 байт

1-а програма:

alert(eval(c="`alert(eval(c=${JSON.stringify(c)},n=${+!n}))`",n=0))

2-а програма:

alert(eval(c="`alert(eval(c=${JSON.stringify(c)},n=${+!n}))`",n=1))

Це ґрунтується на відповіді Германа Лауенштейна на Три-переписку

Javascript (недійсний читання вихідного коду), 75 + 75 = 150 61 + 61 = 122 58 + 58 = 116 50 + 50 = 100 байт

врятувало 20 байт завдяки Тушару, 6 байтів завдяки Крейгу Айре та 16 байтів завдяки kamoroso94

1-а програма:

f=_=>alert(("f="+f).replace(0,a=>+!+a)+";f()");f()

2-а програма:

f=_=>alert(("f="+f).replace(1,a=>+!+a)+";f()");f()

Міняє місцями 1 на 0 і навпаки. Вони обидва роблять те саме, просто виробляючи різний вихід через свій вихідний код.


1
Збережемо кілька байт. f.toString()=> (''+f), (0|1)=> 0|1, (a,b)=> в aрезультатіf=()=>("f="+(''+f).replace(/0|1/g,a=>a==0?1:0)+";f()");f()
Тушар

Ви можете використовувати невикористаний параметр, щоб зберегти пару байтів f=_=>і видалити паролі з зворотного виклику заміни, як @Tushar запропонував:a=>+!+a
Craig Ayre

Замінити "f="+(f+"")з ("f="+f)для -3 байт.
kamoroso94

Замінити /0|1/gі /1|0/gз , 0і , 1відповідно , для -5 байт.
kamoroso94

Ти це запустив? Це працює так f=_=>alert(("f="+f).replace(0,a=>+!+a)+";f()");f().
kamoroso94

4

Python 2, 63 + 63 = 126 байт

Спробуйте в Інтернеті

Перша програма:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[23:29]

Виходи:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[29:35]

Друга програма:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[29:35]

Виходи:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[23:29]

4

JavaScript ( JsShell ), 35 + 34 = 69 байт

1:

(f=x=>print(`(f=${f})(${-x})`))(-1)

2:

(f=x=>print(`(f=${f})(${-x})`))(1)

3

Математика, 43 + 44 = 87 байт

(Print[#1[#0[#1, -#2]]] & )[HoldForm, -1 1]

і

(Print[#1[#0[#1, -#2]]] & )[HoldForm, -(-1)]

Випробував його на моєму комп’ютері, а вихід другого має лише -1наприкінці, а не -1 1.
numbermaniac

@numbermaniac Я написав ці коди в текстовому інтерфейсі. Здається, вони не працюють у зошитах.
алефальфа

3

asmutils sh, 16 + 16 байт, зловживаючи правилом "stdin is closed".

#!/bin/sh
tr x y

Оскільки stdin закритий і sh відкриє свій скрипт на першу доступну ручку (замість того, щоб перенести його на велику нумеровану ручку, як це роблять сучасні оболонки), tr закінчує читання з копії сценарію, не відкриваючи його ніколи.

Ця переписка здатна до корисного навантаження, але вставити корисний вантаж складно.

Крім того, ця оригінальна версія зловживає деякою шаленою помилкою в древньому ядрі, яку я використовував у ті часи. (Я не знаю, що з цим ядром - я пізніше дізнався, що у нього були різні основні та незначні номери для пристроїв.) Якщо ви виправите зміни ABI, які зламали функції, переписка все одно не працюватиме. Я забуваю, чи має asmutils sh exec чи ні, але якщо це так, це сучасна версія:

exec dd skip=0 | tr x y

Це зловживає навмисною помилкою в asmutils dd; вона має оптимізацію продуктивності, якщо вона може, вона викликає llseek для пропуску, але для збереження байту вона передає SEEK_SET, а не SEEK_CUR. Це призводить до сміття на stderr, але interquine на stdout. Asmutils dd не має можливості придушити більш жорсткий спам.


Чи буде це працювати, якщо /dev/nullзамість цього буде підключено stdin ? У всякому разі, хороша робота!
iBug

@iBug: Ні. Цілком залежить від закритості stdin і від того, що asmutils sh не пов'язаний з libc, і тому не успадковує код авторемонту в libc.
Джошуа

Вам потрібна #!/bin/sh?
CalculatorFeline

@CalculatorFeline: це залежить від точності вашого визначення чогось іншого.
Джошуа

Як правило, шебанги не рахуються, тому це було б 6 байт.
CalculatorFeline


1

Лист звичайний, 58 символів

#1=(let((*print-circle* t))(print'(write '#1# :circle t)))

... або 24 символи, якщо ви не заперечуєте, якщо *print-circle*глобально встановлено T:

#1=(print '(write '#1#))

Надруковане представлення коду читається як циклічна структура, де #1#вказується на клітинку, що йде проти #1=. Ми цитуємо програми так, щоб вони не виконувалися. Оскільки *print-circle*це T, REPL піклується про випромінення таких змінних читачів під час друку; ось що друкує вищезгаданий код і повертає:

#1=(write '(print '#1#)) 

Коли ми оцінюємо наведений вище код, він друкує:

#1=(print '(write '#1#))

Якщо ви хочете дотримуватися значення за замовчуванням для *print-circle*, яке NIL у відповідній реалізації, вам доведеться тимчасово відновлювати змінну:

#1=(let((*print-circle* t))(print'(write '#1# :circle t)))

Всередині тіла LET ми друкуємо речі з *print-circle*буквою T. Отже, ми отримуємо:

#1=(write
    '(let ((*print-circle* t))
       (print '#1#))
    :circle t) 

Як бачите, нова програма не відновлює *print-circle*, але оскільки ми використовуємо write, що викликається функцією низького рівня print, ми можемо передавати додаткові аргументи, такі як :circle. Потім код працює, як очікувалося:

#1=(let ((*print-circle* t))
     (print '(write '#1# :circle t)))

Однак вам потрібно виконати вищезазначені програми як сценарій, а не всередині REPL, оскільки, хоч ви друкуєте речі, піклуючись про кругові структури, і те, writeі printтакож повертає значення, що друкується; і в REPL за замовчуванням значення також друкується, але поза динамічним контекстом, де *print-circle*T.


1

> <> , 16 + 16 = 32 байти

":1-}80.r   !#o#

і

#o#!   r.08}-1:"

Спробуйте в Інтернеті!

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

Цей код закінчиться помилкою.


1

RProgN 2 , 7 + 7 = 14 байт

Я хотів спробувати показати краще використання RProgN, а не просто зловживати замовленнями на друк ...

1
«\1\-

і ...

0
«\1\-

Пояснив

1   # Push the constant, 1. (Or 0, depending on the program)

«\1\-
«       # Define a function from this to the matching », in this case there isn't any, so define it from this to the end of the program, then continue processing.
 \      # Flip the defined function under the constant.
  1\-   # Get 1 - Constant.

Оскільки це друкує стек догори дном, спочатку друкується нова константа, потім друкується строфікована версія функції.

Спробуйте в Інтернеті!



1

Python 3, 74 + 74 = 148 байт

a='a=%r;b=%r;print(b%%(b,a))';b='b=%r;a=%r;print(a%%(a,b))';print(b%(b,a))

і

b='b=%r;a=%r;print(a%%(a,b))';a='a=%r;b=%r;print(b%%(b,a))';print(a%(a,b))

я теж цього не розумію


1

> <> , 12 + 12 = 24 байти

'3d*!|o|!-c:

і

':c-!|o|!*d3

Спробуйте в Інтернеті!

Обидві програми використовують обтікаючий рядковий літерал, щоб додати код до стеку, а потім виробляти 'команду за допомогою різних методів. Під час друку стопки він відсуває код назад, однак 'залишається спереду. Існує кілька варіацій, які призводять до появи '; 3d*, d3*, 00g, :c-Коли в парі з 3d*і :9-коли в парі з 00g.

Занадто подібне рішення для публікації в Befunge-98 на 13 * 2 байти

"2+ck, @,kc+2


0

Javascript (ES6), 36 + 36 = 72 байти

Програма 1:

f=n=>('f='+f).replace(/4|5/g,n=>n^1)

Програма 2:

f=n=>('f='+f).replace(/5|4/g,n=>n^1)

Ці програми працюють шляхом клонування себе і заміни 5на 4і 4на5

console.log((
    f=n=>('f='+f).replace(/4|5/g,n=>n^1)
)())
console.log((
    f=n=>('f='+f).replace(/5|4/g,n=>n^1)
)())


2
Оскільки це позначено quine , це саме те, що зазвичай вважатиметься "quine quine", оскільки воно читає власне джерело. Не впевнені, що таке рішення ОП, але вони, як правило, не допускаються.
Стівен

0

Кляйн , 26 24 байти

<:3+@+3<:"

Спробуйте в Інтернеті!

Пояснення

Це працює так само, як і в мого Кляйна Квіна , де воно друкує джерело назад, за яким слідує a ", останнє відійшло від цього, будучи паліндромним, тому все, що нам потрібно зробити, це зробити його непаліндромним, не пошкоджуючи його функціональність. Перемикаючи <і :ми були в змозі зробити це , не порушуючи функціональність.


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