Напишіть найкоротшу програму самоідентифікації (варіант quine)


57

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

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

Це кодовий гольф: застосовуються стандартні правила. Ваша програма не має доступу до спеціальних файлів, наприклад, до власного вихідного коду.

Редагувати: Якщо ви вирішите, true / false може бути замінено на True / False або 1/0.

Приклад

Якщо вихідний код вашої програми є bhiofvewoibh46948732));:/)4, то ось що має зробити ваша програма:

Введення (Stdin)

bhiofvewoibh46948732));:/)4

Вихід (Stdout)

true

Вхідні дані

(Anything other than your source code)

Вихід

false

7
Чи true/ falseвимога є високою вимогою, або варіації ( True/ False, 1/ 0) також прийнятні?
Крістіан Лупаску

Це проблема, якщо програма виводить трохи більше, ніж true / false (якщо вона продовжує бути однозначною і закінчується true / false)?
Denys Séguret


5
Отже, ви маєте на увазі програму нарцисистів?
PyRulez

Відповіді:


33

JavaScript: 26

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

Я не знаю, чи дійсно файл JavaScript кваліфікується як "програма".



Це можна скоротити за допомогою функції стрілкиf=s=>s=='f='+f
Джонатан

2
@Jonathan так. Але в 2013 році це не могло ...
Denys Séguret

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, тоді як версія Дениса Сегурета справді перевіряє все джерело.
Hankrecords

@Hankrecords Нехай JavaScript вирішує це. f=x=>f==x function f() f.toSource() "x=>f==x"(в основному оцініть код у консолі, а потім оцініть f.toSource()у браузері, який підтримує цей метод.
Optimizer

Не дозволяються анонімні функції (скорочуйте код до x=>f==x) EDIT: nevermind, 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 символів

{`".~"+=}.~

Без =цього коду було б квине, яке генерує власний вихідний код у вигляді рядка. =Робить його порівняти цей рядок введення і виведення , 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і будь-який префікс коду
Jo King

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

6

Пітон 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().
кабінка

Правда, багаторядковий вхід не підтримується.
flornquake

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

Мене бентежить виклик формулювання (тому що мені не добре з англійською граматикою). Це дозволено? print raw_input()==open(__file__).read()? Він усього 40 байт, використовує ваш raw_input()підхід, але читає його код.
Симон

1
@Simon Це заборонено, це одна із стандартних лазівки для подібних проблем. І так, це те, що означає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
Conor O'Brien

1
Я впевнений, що вам потрібно закінчення, ;$()оскільки виклик функції є частиною quine. Це також означає, що вам потрібно буде перейти promptна рахунок для введення даних.
Mama Fun Roll

1
Це не проблема. Виклик функції необхідний, тому що це частина quine. Дозволити користувачеві називати його функцією, це зіпсує quine.
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"

(яка видає помилкові) або

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

(що виводить правду)

Я також створив іншу версію на основі eval:

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

Зараз це 72 символи, я спробую це скоротити, коли встигну.


1
@ dan1111 Чому? Він не має доступу до жодного файлу. Я просто вказував, як запустити програму людям, які не звикли node.js. Він не читає файл.
Denys Séguret

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

Ну, ви отримуєте доступ до джерела функції (тільки тіло, якщо бути точним), що є частиною програми. Це як використовувати mixin () в D. Але я не думаю, що два інші відповіді JS, в тому числі один від мене, насправді кваліфікуються як "програми".
Denys Séguret

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

@ratchetfreak так, ти маєш рацію. Але я думаю, що у вашій програмі використовується своєрідне toString значення enum, правда? І будь-який код, що використовує eval / mixin, - це приблизно та сама хитрість, ніж використання джерела функції.
Denys Séguret

5

Маленька розмова (діалект Pharo 2.0)

Реалізуйте цей метод 41 символу в String (некрасиве форматування для коду-гольфу):

isItMe^self=thisContext method sourceCode

Потім оцініть це в робочій області (printIt традиційним способом 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

флекс - 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()

Проста квітка з доданим чеком.


Це не працює. printце функція Python 3. Вам потрібно буде зробити print(_%%_==input())';print(_%_==input())або змінити її на Python 2.
Mego

3

CJam , 12 байт

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

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

Пояснення

Для цього просто використовується стандартний фреймворк CJam quine.

{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

Пітон, 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!
Ерік Аутгольфер

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

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-байтового рішення), але у мене ще не було своєї кафе . Я вчора вже розробив, що "ліворуч - це єдине місце, куди він може дійсно поїхати, тому що наявність його в іншому місці ускладнює речі. (Але тільки що мені довелося запустити його в налагоджувальній
машині,

1

R , 54 байти

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

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

bodyотримує тіло функції (розбиваючи її трохи, так що body(f)[3]це все paste0далі). Цікаво, що bodyпереформатує код, додаючи пробіли після коми та ін. Це, таким чином, рідкісний випадок відповіді на R-гольф з пробілом після коми.

Це працює тому, що body(f)є об'єктом типу language, і існує as.characterметод для цього типу. З іншого боку, fі args(f)мають тип closure, і не можуть бути перетворені в символьний тип, наскільки я можу судити. Будь ласка, не запитуйте мене, що таке тип мови…


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