Напишите самую короткую самоидентифицирующуюся программу (вариант quine)


57

Напишите программу, которая будет генерировать «истинный» вывод, если ввод соответствует исходному коду программы, и который генерирует «ложный» вывод, если ввод не соответствует исходному коду программы.

Эта проблема может быть описана как связанная с quines, так как программа должна быть способной каким-то образом вычислять собственный исходный код в процессе.

Это код гольф: применяются стандартные правила. Ваша программа не должна иметь доступа к каким-либо специальным файлам, таким как файл собственного исходного кода.

Изменить: Если вы выберете, true / false можно заменить на True / False или 1/0.

пример

Если исходный код вашей программы bhiofvewoibh46948732));:/)4, то вот что ваша программа должна делать:

Ввод (стандартный)

bhiofvewoibh46948732));:/)4

Выход (Stdout)

true

вход

(Anything other than your source code)

Выход

false

7
Является ли true/ falseoutput сильным требованием или приемлемы также варианты ( True/ False, 1/ 0)?
Кристиан Лупаску

Это проблема, если программа выводит немного больше, чем истина / ложь (если она продолжает быть однозначной и заканчивается истиной / ложью)?
Денис Сегюре


5
То есть вы имеете в виду нарциссическую программу?
PyRulez

Ответы:


33

JavaScript: 26

function f(s){return s==f}

Я не знаю, действительно ли файл JavaScript квалифицируется как «программа».



Это можно сократить с помощью функции стрелкиf=s=>s=='f='+f
Джонатан

2
@ Джонатан да. Но в 2013 году он не мог ...
Денис Сегюре

19

JavaScript ES6, 9 символов

Это единственный (гольфовый) способ сделать это в JS. ES6 просто заставляет брать супер меньше персонажей

Запустите это в последней веб-консоли Firefox:

f=x=>f==x

Пример использования:

f("check") // returns false
f("x=>f==x") // returns true

1
@phinotpi - Моя заявка все еще может быть выбрана в качестве ответа?
Оптимизатор

6
Можно утверждать , однако , что источник в данном случае f=x=>f==xи не x=>f==x, в то время как версия DENYS Séguret в действительно проверить весь источник.
Hankrecords

@Hankrecords Пусть JavaScript решит это. f=x=>f==x function f() f.toSource() "x=>f==x"(в основном оценивают код в консоли, а затем оценивают f.toSource()в браузере, который поддерживает этот метод.
Оптимизатор

Не разрешены анонимные функции (сократите код до x=>f==x) РЕДАКТИРОВАТЬ: не имеет значения, ссылка на f внутри функции
MilkyWay90

9

Хаскель, 72 персонажа

main=interact$show.(==s++show s);s="main=interact$show.(==s++show s);s="

Примечание: в конце скрипта нет символа конца строки.

$ runhaskell Self.hs < Self.hs
True

8

GolfScript, 11 символов

{`".~"+=}.~

Без этого =этот код был бы quine, который генерирует свой собственный исходный код в виде строки. =Позволяет сравнить эту строку ввода и вывода , 1если они совпадают и0 если они этого не делают. Обратите внимание, что сравнение является точным - в частности, завершающий символ новой строки в конце ввода приведет к сбою.

Объяснение:

  • { } является литералом блока кода в GolfScript;
  • .дублирует этот блок кода и ~выполняет вторую копию (оставляя первую в стеке);
  • `строковый блок кода, и к нему ".~"добавляется + .~;
  • наконец, =сравнивает полученную строку с входными данными (которые помещаются в стек в виде строки интерпретатором GolfScript до запуска программы) и возвращает результат, 1если они совпадают, а 0если нет.

7

Perl, Infinity 41 38 персонажей

$_=q(print<>eq"\$_=q($_);eval"|0);eval

Обновление: программа больше не заканчивается новой строкой, что означает, что она будет правильно работать с многострочными файлами. Вы должны ввести ввод из STDIN, не нажимая Enter. В Windows я мог сделать это только путем чтения из файла.

Оригинальное решение:

print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(...

1
Красиво сделано! , , ,
моб

Сбой для файла, который начинается с кода, например(cat id.pl; echo foo)|perl id.pl
Джефф Риди

@GeoffReedy, спасибо; программа не обрабатывала многострочный ввод раньше. Это исправлено сейчас.

Черт, это кодовый боулинг?
Мэтью Ро

7

> <> , 68 байт

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

00v      0+1~$^?)0~\;n0\
  >:@@:@gi:0(?\:a=?/=?!/$1+
  0n;n*=f$=2~~/

Вы можете попробовать это онлайн !


1
Это выводит также 1для любого префикса кода
Джо Кинг

@JoKing это было хуже, чем просто префиксы сценария, он также принимал усеченные строки! Я исправил это, но я разочарован, что он не настолько универсален, как мне хотелось бы, я должен был проверить достигнутую ячейку в конце скрипта, чтобы убедиться, что весь код совпадает. Конечно, это можно улучшить, но я не уверен, что буду беспокоиться.
Аарон

6

Python 2, 55

a='a=%r;print a%%a==raw_input()';print a%a==raw_input()

Проверено:

a='a=%r;print a%%a==raw_input()';print a%a==raw_input() -> True

(anything else) -> False


3
Сбой любого файла, который начинается с первой строки, равной a='a=%r;print a%%a==raw_input()';print a%a==raw_input().
Boothby

Правда, многострочный ввод не поддерживается.
землетрясение

Тривиальное исправление было бы заменить raw_input()на __import__('sys').stdin.read().
feersum

Я смущен формулировкой вызова (потому что я не очень хорош с грамматикой английского языка). Это разрешено? print raw_input()==open(__file__).read()? Это всего 40 байт, использует ваш raw_input()подход, но читает его код.
Симон

1
@ Симон Это недопустимо, это одна из стандартных лазеек для подобных задач. И да, это то, что это значитYour program must not access any special files, such as the file of its own source code.
PunPun1000

6

JavaScript ES6, 16 14 байт

$=_=>_==`$=`+$

Минус два байта благодаря Нейлу.

31 байт, если мы должны принять ввод через приглашение.

$=_=>prompt()==`$=${$};$()`;$()

38 байт, если мы должны вывести через оповещение.

$=_=>alert(prompt()==`$=${$};$()`);$()

Это правильный способ сделать это, так как ответ Оптимизатора не принимает весь исходный код.


1
Хорошо, хотя я бы просто написал '$='+$.
Нейл

О, правда. @Neil
Конор О'Брайен

1
Я уверен, что вам нужен конец, ;$()потому что вызов функции является частью квин. Это также означает, что вам нужно переключиться promptна учетную запись для ввода.
Mama Fun Roll

1
Это не проблема. Вызов функции необходим, потому что это часть квин. Разрешение пользователю вызывать его как функцию разрушит квин.
Mama Fun Roll

1
попробуй$=_=>prompt()==`$=${$};$()`;$()
Mama Fun Roll

5

Node.js: 54

function f(){console.log(f+'f()'==process.argv[2])}f()

Вы проверяете это, сохраняя его в файл f.js(точное имя не имеет значения) и используя

node f.js "test"

(который выводит false) или

node f.js "$(< f.js)"

(который выводит true)

Я также сделал другую версию на основе eval:

eval(f="console.log('eval(f='+JSON.stringify(f)+')'==process.argv[2])")

Сейчас у него 72 символа, я постараюсь сократить это, когда у меня будет время.


1
@ dan1111 Почему? Он не имеет доступа к любому файлу. Я просто указывал, как запустить программу людям, которые не привыкли к node.js. Он не читает файл.
Денис Сегюре

1
Все решения Javascript используют тот факт, что вы можете получить доступ к своему исходному коду в JS. С технической точки зрения это может не означать «доступ к файлу из собственного исходного кода», но он выполняет то же самое. Я полагаю, что ваш ответ правомерен, поскольку этот вопрос не запрещает этого.

Итак, вы получаете доступ к источнику функции (точнее, к телу), которая является частью программы. Это похоже на использование mixin () в D. Но я не думаю, что два других ответа JS, включая один от меня, действительно квалифицируются как «программы».
Денис Сегюре

@dystroy на самом деле mixin в D больше похож на использование eval, чем на чтение исходного
трещотка урод

@ratchetfreak да, ты прав. Но я думаю, что ваша программа использует своего рода toString значения enum, верно? И любой код, использующий eval / mixin, примерно такой же трюк, как и использование источника функции.
Денис Сегюре

5

Smalltalk (диалект Pharo 2.0)

Реализуйте этот метод с 41 символом в String (безобразное форматирование для code-golf):

isItMe^self=thisContext method sourceCode

Затем оцените это в рабочей области (напишите традиционным способом Smalltalk)
Ввод не читается из stdin, это просто строка, в которую мы отправляем сообщение (что еще может быть программа в Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

Но мы обманываем, sourceCode читает некоторый исходный файл ...
Вот вариант с 51 символом, который не делает:

isItMe
    ^ self = thisContext method decompileString

И проверить с:

'isItMe
    ^ self = thisContext method decompileString' isItMe

Если строка в рабочей области не считается допустимым вводом, то давайте посмотрим, как использовать какое-либо диалоговое окно в 116 символов.
Просто оцените это предложение:

(UIManager default request: 'type me') = (thisContext method decompileString withSeparatorsCompacted allButFirst: 7)

Поскольку формат декомпиляции включает CR и TAB, мы изменяем это с помощью SeparatorsCompacted.
Затем мы пропускаем первые 7 символов 'doIt ^'

Наконец, вариант с 105 символами, использующий stdin, просто интерпретируйте это предложение из командной строки, чтобы почувствовать себя более распространенным:

Pharo -headless Pharo-2.0.image eval "FileStream stdin nextLine = (thisContext method decompileString withSeparatorsCompacted allButFirst: 7)"

4

flex - 312 символов

Q \"
N \n
S " "
B \\
P "Q{S}{B}{Q}{N}N{S}{B}n{N}S{S}{Q}{S}{Q}{N}B{S}{B}{B}{N}P{S}{Q}{P}{Q}{N}M{S}{Q}{M}{Q}{N}%%{N}{P}{N}{M}{N} putchar('1');"
M "(.|{N})* putchar('0');"
%%
Q{S}{B}{Q}{N}N{S}{B}n{N}S{S}{Q}{S}{Q}{N}B{S}{B}{B}{N}P{S}{Q}{P}{Q}{N}M{S}{Q}{M}{Q}{N}%%{N}{P}{N}{M}{N} putchar('1');
(.|{N})* putchar('0');

Возможно, его можно сделать короче, но он работает с многострочным вводом (необходимо, так как исходный код состоит из нескольких строк) и даже для входов, которые содержат программу в качестве подстроки. Кажется, что многие ответы до сих пор не отвечают ни одному, ни обоим из них.

Команда компиляции: flex id.l && gcc -lfl lex.yy.c



3

JavaScript (V8), 35

function i(){alert(prompt()==i+[])}

позвоните i()и он подскажет для ввода


Значение +[]должно быть необязательным, так как JS автоматически приведёт его к типу
Downgoat


3

Python 2, 47 байт

_='_=%r;print _%%_==input()';print _%_==input()

Простой Quine с добавленной проверкой.


Это не работает printэто функция Python 3. Вам нужно было бы сделать print(_%%_==input())';print(_%_==input())или изменить ее на Python 2.
Mego

3

CJam , 12 байтов

{s"_~"+q=}_~

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

объяснение

Это просто использует стандартную CJam Quine Framework.

{s"_~"+q=}    e# Push this block (function literal).
          _~  e# Copy and run it.

Что делает блок:

 s            e# Stringify the top element (this block itself).
  "_~"+       e# Append "_~". Now the source code is on the stack.
       q      e# Read the input.
        =     e# Check if it equals the source code.

Это именно то решение, которое у меня было ._.
Esolanging Fruit



2

Python, 187 байт

import sys;code="import sys;code=!X!;print(sys.stdin.read()==code.replace(chr(33),chr(34)).replace(!X!,code,1))";print(sys.stdin.read()==code.replace(chr(33),chr(34)).replace("X",code,1))

Осторожно, чтобы не добавлять новую строку в конце. Кто-то с лучшим Python-fu может сократить его.


2
Вы можете использовать, C=chrчтобы сбросить несколько байтов. Кроме того, сократить имя переменной code.
Зак Гейтс

2
Так как никто не говорил это больше года, добро пожаловать в PPCG!
Эрик Outgolfer

2

Шелуха , 11 байт

=hS+s"=hS+s

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

объяснение

Объяснение используется ¨для разделения строк (чтобы избежать нечитаемого экранирования):

     "=hS+s  -- string literal: ¨=hS+s¨
  S+         -- join itself with
    s        -- | itself "showed": ¨"=hS+s"¨
             -- : ¨=hS+s"=hS+s"¨
 h           -- init: ¨=hS+s"=hS+s¨
=            -- is the input equal?

Удалив функцию, =вы можете убедиться, что она действительно будет соответствовать только самому источнику.



2

Желе , 10 байт

“Ṿ;$⁼”Ṿ;$⁼

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

“Ṿ;$⁼”Ṿ;$⁼
“Ṿ;$⁼”      String literal: 'Ṿ;$⁼'
        $   Next two links act on the string literal
      Ṿ     Uneval: '“Ṿ;$⁼”'
       ;    Append string: '“Ṿ;$⁼”Ṿ;$⁼' (source code)
         ⁼  Is the string above equal to the input?

2

05AB1E , 15 байтов

0"D34çýQ"D34çýQ

Изменяет 0"D34çý"D34çý по умолчанию , добавляяQ (проверка на равенство с неявным входом)

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

Объяснение:

0                # Push 0 to the stack
                 #  STACK: [0]
 "D34çýQ"        # Push the string 'D34çýQ' to the stack
                 #  STACK: [0, 'D34çýIå']
         D       # Duplicate this string
                 #  STACK: [0, 'D34çýIå', 'D34çýIå']
          34ç    # Push '"' to the stack
                 #  STACK: [0, 'D34çýIå', 'D34çýIå', '"']
             ý   # Join the stack by this '"' delimiter
                 #  STACK: ['0"D34çýIå"D34çýIå']
              Q  # Check if it's equal to the (implicit) input
                 # (and output the top of the stack implicitly as result)

Охладить 15 байт альтернатива обеспечивается @Grimy :

187745012D27BJQ

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

Объяснение:

187745012        # Push integer 187745012 
                 #  STACK: [187745012]
         D       # Duplicate it
                 #  STACK: [187745012, 187745012]
          27     # Push integer 27
                 #  STACK: [187745012, 187745012, 27]
            B    # Convert 187745012 to base-27
                 #  STACK: [187745012, "D27BJQ"]
             J   # Join the values on the stack together
                 #  STACK: ["187745012D27BJQ"]
              Q  # Check if it's equal to the (implicit) input
                 # (and output the top of the stack implicitly as result)

3
187745012D27BJQгалстук
Grimmy

1

C - 186 176 знаков

Один лайнер:

 *a="*a=%c%s%c,b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}",b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}

С пробелами (обратите внимание, что это нарушает программу):

*a="*a=%c%s%c,b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}",b[999],c[999];
main() {
  sprintf(b,a,34,a,34);
  gets(c);
  putchar(strcmp(b,c)?'0':'1');
}



1

q, 8 байтов

{x~.z.s}

Возвращает логическое значение при вводе, соответствующем самореференциальному .zs


1

Рунический , 11 байт

"3X4+kSqi=@

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

TIO обновлен, и больше нет проблем с чтением входных данных (и больше не требуется конечный пробел).

объяснение

>                 Implicit entry
 "                Begin reading as string
  3X4+kSqi=@      Pushed to the stack as a string, loop around
 "                End reading as string
  3X4+            Push 3*10 and 4 to the stack, add them together
      k           Convert to character (")
       S          Swap the top two items on the stack
        q         Concatenate. This leaves only "3X4+kSqi=@ on the stack
         i        Read input
          =       Compare using .Equals, push 1 if equal, else 0
           @      Print and terminate

Решение JoKing:

"'<~qi=@|

объяснение

  <              Entry
 '               Read character (loop around)
"                Push "
         |       Mirror
"                Begin reading string (loop around)
 '<~ri=@|        Push the string '<~qi=@| (loop around)
"                End reading string
 '<~             Push the character < and then discard it
    q            Concatenate, stack contains only "'<~qi=@|
      i          Read input
       =         Compare
        @        Print and terminate


@JoKing Очень умно.
Draco18s

На самом деле, 9 байтов избегают rобратного хода
Джо Кинг,

@ JoKing Я, наверное, должен был бы прийти к этому (из 10-байтового решения) сам, но у меня еще не было моего cawfee . Вчера я уже понял, что наличие "слева - единственное место, куда он может пойти, потому что наличие его в другом месте усложняет ситуацию. (Но только сейчас мне пришлось запустить его в моем отладчике, чтобы посмотреть, что он делает ...)
Draco18s

1

R , 54 байта

f=function(s)s==paste0("f=function(s)s==", body(f)[3])

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

bodyполучает тело функции (немного ее разбивая, так что body(f)[3]это все , что нужно paste0). Интересно, что bodyформатирует код, добавляя пробелы после запятой и т. Д. Таким образом, это редкий случай ответа R golf с пробелом после запятой.

Это работает, потому что body(f)это объект типа language, и as.characterдля этого типа существует метод. С другой стороны, fи args(f)имеют тип closure, и не могут быть преобразованы в тип символов, насколько я могу судить. Пожалуйста, не спрашивайте меня, для чего предназначен тип языка ...


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