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

57

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

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

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

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

пример

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

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

bhiofvewoibh46948732));:/)4

Выход (Stdout)

true

вход

(Anything other than your source code)

Выход

false
PhiNotPi
источник
7
Является ли true/ falseoutput сильным требованием или приемлемы также варианты ( True/ False, 1/ 0)?
Кристиан Лупаску
Это проблема, если программа выводит немного больше, чем истина / ложь (если она продолжает быть однозначной и заканчивается истиной / ложью)?
Денис Сегюре
1
Связанный: интерпретировать свой язык, но не себя?
Ильмари Каронен
5
То есть вы имеете в виду нарциссическую программу?
PyRulez

Ответы:

33

JavaScript: 26

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

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

Денис Сегюре
источник
7
+1 Это работает, потому что все объекты имеют .toString()метод в 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

flornquake
источник
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)"
aka.nice
источник
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

D (133 символа)

enum c=q{import std.stdio;import std.algorithm;void main(){auto i=readln();writeln(equal("auto c=q{"~c~"};mixin(c);",i));}};mixin(c);
чокнутый урод
источник
3

JavaScript (V8), 35

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

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

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

Python 2, 47 байт

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

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

Rɪᴋᴇʀ
источник
Это не работает 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

Tcl, 111 символов

set c {set c {$c};puts [expr {[read stdin] eq [subst -noc \$c]}]};puts [expr {[read stdin] eq [subst -noc $c]}]
Йоханнес Кун
источник
2

Perl, 52 символа

$_='$/=$\;$_="\$_=\47$_\47;eval";print<>eq$_|0';eval
чернь
источник
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

> <> , 24 байта

'1rd3*i={*}50l3-?.~i)*n;

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

Обтекание строкового литерала с последующей проверкой идентичности ввода стеку с окончательной проверкой отсутствия ввода.

Джо Кинг
источник
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?
dylnan
источник
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

Thaufeki
источник
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
Draco18s
источник
1
10 байтов
Джо Кинг
@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, и не могут быть преобразованы в тип символов, насколько я могу судить. Пожалуйста, не спрашивайте меня, для чего предназначен тип языка ...

Робин Райдер
источник