2 кошки в лебеде


30

Вызов

Создайте две программы, A и B, которые являются программами cat на одном языке. При объединении AB (также на том же языке) должен быть квине.

Например, предположим , что helloи worldявляются программы кошачьи на языке XYZ. Если helloworldэто квин на указанном языке, то ваше решение действительно.

Для тех из вас, кто не знаком с кошками и квин, программа cat - это программа, которая печатает именно то, что было ей дано через stdin, а quine - это программа, которая печатает свой собственный исходный код.

Подсчет очков и правила

  • Общее количество байтов объединенной программы AB - это ваш счет. Поскольку это кодовый гольф, выигрывает самая низкая оценка.
  • Стандартные лазейки запрещены
  • Входные данные должны быть взяты из стандартного ввода, а выходные данные должны идти в стандартный вывод.
  • Программы cat не должны принимать аргументы; им нужно только скопировать стандартный ввод в стандартный вывод.
  • Quine должен работать, когда программе не дается никаких входных данных, но он не должен работать правильно (но может работать) для других входных данных.
  • Quine не нужно завершать, при условии, что он печатает точно свой исходный код один раз, и ничего более.
  • Quine должен иметь длину не менее одного байта.
  • A и B могут быть одной и той же программой.
  • BA не должен быть квинем или даже действительной программой.

Я не думаю, что у вас должны быть одинаковые правила программы A и B
Мухаммед Салман

2
@MuhammadSalman Моя оригинальная идея состояла в том, чтобы программа для кошек была удвоена, чтобы превратиться в квин. Я просто хотел открыть дверь для более простых решений, потому что я не был полностью уверен, что это возможно. Похоже, я был неправ по обоим пунктам, но я в порядке с этим.
Beefster

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

9
@DJMcMayhem 0-байтовая квинета не будет действительной квиной.
Nissa

4
Что такое программа для кошек?
Педро А

Ответы:


32

V , 2 + 2 == 4 байта

2i2i

Попробуйте квайн!

Попробуйте кошку!

А это2i

B также2i

Как это работает?

Прежде всего, некоторые объяснения того, как работает V. Одна заметная вещь, которая делает этот ответ возможным, состоит в том, что в V пустая программа является программой cat. Это не особый случай, это присуще тому, как работает V. При запуске все входные данные загружаются в «буфер», каждая команда каким-то образом модифицирует буфер, а затем, когда программа завершается, буфер неявно печатается. Это означает, что любая строка NOP также является программой cat.

Команда iозначает войти в режим вставки , что означает, что каждый следующий за ним символ iбудет добавлен в буфер. С предшествующим ему номером этот текст будет продублирован n раз.

Это означает, что для программы cat ничего не будет добавлено в буфер, и оно будет напечатано так, как оно было прочитано. Другими словами:

        " (Implicitly) Load all input
2       " 2 times,
 i      " Insert the following text into the buffer...
        " (nothing)
        " (Implicitly) Print the buffer

Но для Quine есть текст после i:

2       " 2 times,
 i      " Insert the following text into the buffer...
  2i    "   "2i"
        " (Implicitly) Print the buffer

Нахальный не ответ

V , 0 байтов

Попробуйте онлайн!

А это пустая программа.

B также пустая программа.


21
Любой другой язык: Ой, мы зашли в тупик! , V: * сообщения стандартного Quine * .
Эрик Outgolfer

13

Рубин, 71 байт

2;puts (<<2*2+?2)[/.+2/m]||$<.read
2;puts (<<2*2+?2)[/.+2/m]||$<.read
2

Можно разбить на кошек следующим образом:

2;puts (<<2*2+?2)[/.+2/m]||$<.read
2

а также

;puts (<<2*2+?2)[/.+2/m]||$<.read
2

Эти две кошки идентичны, за исключением ведущей 2, которая является запретной во всех трех программах. <<2Является herestring, а это означает , что все , начиная со следующей строкой , пока нагрузочный 2 на своей собственной линии является строкой, которую мы сцепить к себе ( *2) и добавить косую 2. В кошках herestring хорошо образованные , но пустые, поэтому регулярное выражение не будет соответствовать ему, и мы перейдем к $<.readвыражению и выведем STDOUT. Однако после того, как мы объединяем кошек, строка не будет заканчиваться до третьей строки, поэтому регулярное выражение совпадает, и мы закорачиваем и выводим квинну.


11

Pyth, 29 байтов (5 + 24) 27 байтов (5 + 22)

pz=T0?TzjN*2]"pz=T0?TzjN*2]     # Quine
pz=T0                           # Cat A
     ?TzjN*2]"pz=T0?TzjN*2]     # Cat B

Это было весело.
Попробуйте здесь Quine.
Попробуйте здесь первый кот. Попробуйте здесь
второй кот.

Пояснения

Cat A
pz=T0
pz       Print the input.
  =T0    (Irrelevant for cat)

Cat B
?TzjN*2]"pz=T0?TzjN*2]
?Tz                      If T (10) is truthy, output the input.
   jN*2]"pz=T0?TzjN*2]   (Irrelevant for cat)

Quine
pz=T0?TzjN*2]"pz=T0?TzjN*2]
pz                            Print the (empty) input (without a newline).
  =T0                         Set T to 0.
     ?Tz                      If T (0) is truthy, output the input.
             "pz=T0?TzjN*2]   Otherwise, get this string...
          *2]                 ... take two copies...
        jN                    ... and join them with a quote.

11

C # (компилятор Visual C #) , 551 байт

A: 95 байт

class A{public static int i=2;static void Main(string[]args){System.Console.Write(args[0]);}}//

Попробуйте онлайн!

B: 438 + 18 байт.

class A{public static int i=0;}
class B{static void Main(string[]args){if(A.i<1){System.Console.Write(args[0]);return;}var a=@"class A{{public static int i=2;static void Main(string[]args){{System.Console.Write(args[0]);}}}}//class A{{public static int i=0;}}
class B{{static void Main(string[]args){{if(A.i<1){{System.Console.Write(args[0]);return;}}var a=@{0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}}

Попробуйте онлайн!

A + B: 533 + 18 байт

class A{public static int i=2;static void Main(string[]args){System.Console.Write(args[0]);}}//class A{public static int i=0;}
class B{static void Main(string[]args){if(A.i<1){System.Console.Write(args[0]);return;}var a=@"class A{{public static int i=2;static void Main(string[]args){{System.Console.Write(args[0]);}}}}//class A{{public static int i=0;}}
class B{{static void Main(string[]args){{if(A.i<1){{System.Console.Write(args[0]);return;}}var a=@{0}{1}{0};System.Console.Write(a,'{0}',a);}}}}";System.Console.Write(a,'"',a);}}

Попробуйте онлайн!

A и B принимают ввод в качестве аргумента командной строки. A + B игнорирует любой ввод. 18 байтов на B и A + B добавляются для /p:StartupObject=Bопции, отправляемой в MSBuild. Это только строго необходимо для A + B, но казалось обманом, чтобы не иметь его в B. Таким образом, флаги компилятора для A + B - это флаги компилятора для A (нет) плюс флаги компилятора для B.

объяснение

Программа А проста. Класс A содержит (неиспользованную) статическую переменную, iинициализированную 2и выдает первый аргумент при запуске. Значение //в конце важно для кода A + B, но ничего не делает в самом A.

Программа B странная в изоляции, но по сути то же самое. Он создает класс A, содержащий статическую переменную, iинициализированную для 0, и затем запускает метод Main класса B, который делает то же самое, что и программа A, потому что A.iон меньше 1, и возвращается перед любыми странными вещами. Новые строки здесь не нужны, но они важны для A + B.

При объединении программа //из программы A комментирует объявление класса A из программы B, но из-за новой строки класс B вполне подойдет, позволяя вместо этого A.iссылаться на 2значение из программы A. Флаг компилятора заставляет Программу запускать B.Main (), так как A.Main () также существует. В результате программа A + B не выводит свой аргумент, а вместо этого переходит к следующему сегменту B.Main (), который в основном представляет собой стандартную C # quine .


1
"Программы кота ... нужно скопировать стандартный ввод в стандартный вывод"
Якоб

9

Haskell , 116 + 20 = 187 175 174 136 байт

С тех пор, как Эрджан Йохансен показал мне, сохранено несколько байтов interact

Кот 1

g=";main|idmain<-(++\"g=\"++show g++g)=interact idmain|1>0=interact id";main|idmain<-(++"g="++show g++g)=interact id

Попробуйте онлайн!

Кот 2

main|1>0=interact id

Попробуйте онлайн!

Куайн

g=";main|idmain<-(++\"g=\"++show g++g)=interact idmain|1>0=interact id";main|idmain<-(++"g="++show g++g)=interact idmain|1>0=interact id

Попробуйте онлайн!


Основной принцип работы здесь заключается в том, что когда мы добавляем второго кота к первому, мы меняем имя функции, с которой мы взаимодействуем, с aна idmain. Так interact idкак это кот, мы хотим, idmainчтобы мне была функция, которая возвращает квин. Очевидным решением будет использование const, однако, так как мы можем предположить, что ввод также пустой (++). Отсюда мы находим исходный код довольно стандартным способом, у нас есть переменная, gкоторая кодирует исходный код, и мы используем специальную оболочку для печати его в строковой форме и форме кода. Есть небольшое исключение, что нам нужно поместить наш кодер вперед, потому что нам уже нужно заканчивать interact id. Это означает, что дополнительныйg=не кодируется и должен обрабатываться вручную. Наша следующая кошка довольно стандартна, за исключением того, что нам нужно сделать ее действительным кодом, когда она прикреплена к концу другой кошки, поэтому нам нужно, чтобы обе кошки были экземплярами охранников шаблонов.

Альтернативная стратегия, 43 + 105 = 186 148

Кот 1

g="";main|idmain<-(++g++show g)=interact id

Попробуйте онлайн!

Кот 2

main|1>0=interact id where g="g=\"\";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="

Попробуйте онлайн!

Куайн

g="";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="g=\"\";main|idmain<-(++g++show g)=interact idmain|1>0=interact id where g="

Попробуйте онлайн!


1
Вы можете немного сократить это, заменив getContents+ putStrна interact id. Попробуйте онлайн! (Quine больше не работает с непустым вводом, что позволяет использовать (++ ...)раздел для idmain.)
Ørjan Johansen

@ ØrjanJohansen Спасибо! Я не знал об этом interact, я думаю, это потому, что я редко занимаюсь IO с Haskell. Я отредактировал пост.
Пшеничный волшебник

8

Python 3, 286 байт

Мой первый Python Golf и мой первый Quine! Не очень элегантно, но это работает.

Программа А (238 байт)

from atexit import*;s="from atexit import*;s=%r;register(lambda:print(end='b'in globals()and s%%s or open(0).read()));b=0\nif's'not in vars():print(end=open(0).read())";register(lambda:print(end='b'in globals()and s%s or open(0).read()));

(без завершающей строки)

Программа B (48 байт)

b=0
if's'not in vars():print(end=open(0).read())

(без завершающей строки)

Попробуйте онлайн

Подтверждения

  • -24 байта благодаря Джо Кингу
  • -82 байта благодаря Джо Кингу

Вы можете делать end=open...и использовать %rвместо того, %sчтобы не делать новые строки и цитаты
Джо Кинг

Круто, я перешел на %r. Не уверен, что вы имеете в виду о новой строке, хотя.
Якоб

1
Вместо того, %sчтобы форматировать новую строку в, вы можете просто сделать литерал \n. Вы также можете использовать ;для разделения операторов вместо \n(за исключением ifнеобходимости быть в отдельной строке). %можно экранировать в строке, выполнив %%. Единственный аргумент, необходимый для форматирования строки, - это сама строка, все остальное можно чередовать
Джо Кинг,

1
Программа B (и текст для нее) может использовать locals()для сохранения 2 байта.
Джонатан Аллан

6

C ++ (лязг) , 313 + 102 = 415 байт

Программа А (заканчивается новой строкой):

#include<cstdio>
#define Q(x,y)#x,B=#y;x
int c;auto I="#include<cstdio>",A=Q(int main(){if(c)printf("%s\n#define Q(x,y)#x\",\"#y;x\nint c;auto I=\"%s\",A=Q(%s,)\n#ifdef Q\nint n=++c;\n#else\n%s\n%s\n#endif",I,I,A,I,B);else while((c=getchar())>=0)putchar(c);},int c;int main(){while((c=getchar())>=0)putchar(c);})

Программа B (не заканчивается новой строкой):

#ifdef Q
int n=++c;
#else
#include<cstdio>
int c;int main(){while((c=getchar())>=0)putchar(c);}
#endif

Не очень подлый, и, как обычно, C ++ не так уж и хорош для quining. Я не удивлюсь, если есть способы побрить байты здесь и там от той же самой идеи. Один маленький улов - изменение поведения чего-либо после того, как оно было определено, и инициализатор динамической переменной с побочным эффектом делает свое дело. (Может ли это быть даже сделано в C без расширений компилятора?)

Попробуйте онлайн: A , B , AB

(Единственная проблема с переносимостью, о которой я знаю, заключается в том, что программа предполагает размещение <cstdio>имен как в глобальном пространстве имен, так и в нем std.)


5

Befunge-98 (FBBI) , 8 + 15 = 23 байта

A + B: (работает только без ввода)

+9*5~,#@#@~,9j>:#,_:@#"

Попробуйте онлайн!

A:

+9*5~,#@

Попробуйте онлайн!

B:

#@~,9j>:#,_:@#"

Попробуйте онлайн!


Мне было интересно, сможет ли кто-нибудь найти ответ.
Жаль, что

@ Бифстер, да. Проблема в том, что довольно сложно сделать 2d Куайн. Может быть, я буду работать над чем-то, хотя
MildlyMilquetoast

5

Python 3 , 100 + 37 = 137 байт

Программа А:

s='s=%r;print(end=open(0).read())#print(end=open(0).read())\nprint(s%%s)';print(end=open(0).read())#

Попробуйте онлайн!

Программа Б:

print(end=open(0).read())
print(s%s)

Попробуйте онлайн!

Make Quine AB

s='s=%r;print(end=open(0).read())#print(end=open(0).read())\nprint(s%%s)';print(end=open(0).read())#print(end=open(0).read())
print(s%s)

Попробуйте онлайн!

Работает только тогда, когда ввод пуст, в противном случае он добавляет ввод к выводу.


Двойные кавычки должны быть одинарными.
Джонатан Аллан

Разбить разрешено?
Якоб

@Jakob Вопрос не говорит о том, что сбой не разрешен, и обычно вывод в STDERR игнорируется
Джо Кинг

Хорошо, достаточно справедливо. Умные ярлыки!
Якоб

4

Атташе , 15 + 126 = 141 байт

A:

AllInput[]|Echo

Попробуйте онлайн!

B:

@{If[_,s.="AllInput[]|Echo@{If[_,s.=%s;;Printf[s,Repr!s],AllInput[]|Echo]es}|Call";;Printf[s,Repr!s],AllInput[]|Echo]es}|Call

Попробуйте онлайн!

A + B:

AllInput[]|Echo@{If[_,s.="AllInput[]|Echo@{If[_,s.=%s;;Printf[s,Repr!s],AllInput[]|Echo]es}|Call";;Printf[s,Repr!s],AllInput[]|Echo]es}|Call

Попробуйте онлайн!

объяснение

Каждая из программ cat кодирует AllInput[]|Echo, что является простой программой cat. B - основная фаза хины; в одиночку, это векторизованная функция (через унарный @), вызываемая без входов (называемая|Call ) Таким образом, первые условные If[_,A,B]исполняет B, который простоAllInput[]|Echo .

Когда A + B выполняется, унарный @становится двоичным@ из-за Echoслияния с лямбда-выражением:

AllInput[]|Echo@{If[_, ...

Теперь это означает, что лямбда выполняется раньше, чем Echoесть. Возвращаясь к условию, эта функция теперь имеет все STDIN в качестве аргумента. Итак, If[_,A,B]выполняется A, что является стандартным фреймворком quine.


3

Stax , 16 + 12 = 28 байт

Кот 1:

"yi|d|ca34b4lr"y

Запустите и отладьте его

"yi|d|ca34b4lr"y Full program, implicit input
"yi|d|ca34b4lr"  Push the string
               y Push raw input
                 Implicit output of top item

Кот 2:

i|d|ca34b4lr

Запустите и отладьте его

i|d|ca34b4lr Full program, implicit input
i            Don't parse input (prefix directive)
 |d          Push main stack depth, always zero
   |c        Cancel because top item is falsy, and implicitly print
     a34b4lr Never executed

Куайн:

"yi|d|ca34b4lr"yi|d|ca34b4lr

Запустите и отладьте его

"yi|d|ca34b4lr"yi|d|ca34b4lr Full program
"yi|d|ca34b4lr"              Push the string
               y             Push input
                i            No-op
                 |d          Push main stack depth, i.e. 2
                   |c        Do nothing because top is truthy
                     a       Get the string to the top
                      34     Push 34 (charcode of ")
                        b    Copy both
                         4l  Listify top 4
                           r Reverse
                             Implicit output

3

Кот 1:

Луа , 41 байт

a=io.read;while a(0)do io.write(a(1))end;

Попробуйте онлайн!


Кот 2:

Луа , 70 байт

if a then io.input(arg[0])end;a=io.read;while a(0)do io.write(a(1))end

Попробуйте онлайн!


Куайн:

Луа , 111 байт

a=io.read;while a(0)do io.write(a(1))end
if a then io.input(arg[0])end;a=io.read;while a(0)do io.write(a(1))end

Попробуйте онлайн!

io.input(arg[0]) в Cat 2 устанавливает текущий файл в качестве стандартного ввода, и в результате кошка печатает исходный код


1
Добро пожаловать в PPCG
Мухаммед Салман

Вы можете сохранить один байт в cat 1, удалив последнюю точку с запятой?
Мухаммед Салман

1
К сожалению, чтение текущего файла является стандартной лазейкой. Но все равно приятно попробовать.
Бифстер


0

JavaScript (Node.js) , 199 байт


a=()=>console.log(require('fs').readFileSync(0)+'');a();var a=a||0;b=()=>console.log(require('fs').readFileSync(0)+'');!a?b():c=()=>console.log(`a=${a};a();var a=a||0;b=${b};!a?b():c=${c},c()`),c()

Попробуйте онлайн!

Кот А, 57 байт


a=()=>console.log(require('fs').readFileSync(0)+'');a();

Попробуйте онлайн!

Cat B, 142 байта

var a=a||0;b=()=>console.log(require('fs').readFileSync(0)+'');!a?b():c=()=>console.log(`a=${a};a();var a=a||0;b=${b};!a?b():c=${c},c()`),c()

Попробуйте онлайн!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.