Napisz najkrótszy samoidentyfikujący się program (wariant quine)


57

Napisz program, który wygeneruje „prawdziwe” wyjście, jeśli dane wejściowe są zgodne z kodem źródłowym programu, i które wygeneruje „fałszywe” dane wyjściowe, jeśli dane wejściowe nie będą zgodne z kodem źródłowym programu.

Problem ten można opisać jako związany z quinesami, ponieważ program musi być w stanie w jakiś sposób obliczyć własny kod źródłowy w tym procesie.

To jest kod golfowy: obowiązują standardowe zasady. Twój program nie może uzyskiwać dostępu do żadnych plików specjalnych, takich jak plik własnego kodu źródłowego.

Edycja: Jeśli tak wybierzesz, wartość prawda / fałsz może zostać zastąpiona wartością prawda / fałsz lub 1/0.

Przykład

Jeśli kod źródłowy twojego programu to bhiofvewoibh46948732));:/)4, to oto co twój program musi zrobić:

Wejście (standardowe wejście)

bhiofvewoibh46948732));:/)4

Wyjście (standardowe wyjście)

true

Wejście

(Anything other than your source code)

Wynik

false

7
Czy wyjście true/ falsejest silnym wymogiem, czy też dopuszczalne są odmiany ( True/ False, 1/ 0)?
Cristian Lupascu,

Czy to problem, jeśli program wypisuje coś więcej niż prawda / fałsz (jeśli nadal jest jednoznaczny i kończy się na prawda / fałsz)?
Denys Séguret,


5
Masz na myśli program narcystyczny?
PyRulez

Odpowiedzi:



19

JavaScript ES6, 9 znaków

Jest to jedyny (golfowy) sposób na zrobienie tego w JS. ES6 sprawia, że ​​zajmuje mniej znaków

Uruchom to w najnowszej konsoli internetowej Firefox:

f=x=>f==x

Przykładowe użycie:

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

1
@phinotpi - Czy moje zgłoszenie nadal kwalifikuje się do wybrania jako odpowiedź?
Optymalizator

6
Można jednak argumentować, że źródłem w tym przypadku jest f=x=>f==xi nie x=>f==x, podczas gdy wersja Denys Séguret rzeczywiście sprawdza całe źródło.
Hankrecords

@Hankrecords Niech JavaScript zdecyduje o tym. f=x=>f==x function f() f.toSource() "x=>f==x"(w zasadzie oceń kod w konsoli, a następnie oceń f.toSource()w przeglądarce obsługującej tę metodę.
Optimizer

Niedozwolone są funkcje anonimowe (skróć kod x=>f==x) EDYCJA: nevermind, f odwołuje się wewnątrz funkcji
MilkyWay90

9

Haskell, 72 znaki

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

Uwaga: na końcu skryptu nie ma znaku końca linii.

$ runhaskell Self.hs < Self.hs
True

8

GolfScript, 11 znaków

{`".~"+=}.~

Bez =tego kod ten byłby quine, która generuje własny kod źródłowy jako ciąg znaków. =Czyni go porównać ten ciąg do jego wejścia i wyjścia 1, jeśli mecz, a 0jeśli oni nie. Zauważ, że porównanie jest dokładne - w szczególności końcowy znak nowej linii na końcu danych wejściowych spowoduje, że się nie powiedzie.

Wyjaśnienie:

  • { } jest dosłowny blok kodu w GolfScript;
  • .duplikuje ten blok kodu i ~wykonuje drugą kopię (pozostawiając pierwszą na stosie);
  • `uszeregowuje blok kodu i ".~"dodaje .~do niego znak + ;
  • na koniec =porównuje powstały ciąg z danymi wejściowymi (które są wypychane na stos jako ciąg przez interpreter GolfScript przed uruchomieniem programu) i zwraca, 1jeśli pasują, a 0jeśli nie.

7

Perl, nieskończoność 41 38 znaków

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

Aktualizacja: program nie kończy się na nowej linii, co oznacza, że ​​będzie działał poprawnie na plikach wieloliniowych. Musisz wprowadzić dane wejściowe ze STDIN bez naciskania Enter. W systemie Windows mogłem to zrobić tylko czytając z pliku.

Oryginalne rozwiązanie:

print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(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
Ładnie wykonane! . . .
motłoch

Nie można uzyskać pliku rozpoczynającego się od kodu, np.(cat id.pl; echo foo)|perl id.pl
Geoff Reedy,

@GeoffReedy, dzięki; program wcześniej nie obsługiwał wprowadzania wieloliniowego. Zostało to teraz poprawione.

Cholera, czy ten kod jest kręgle?
Matthew Roh,

7

> <> , 68 bajtów

Ryby uwielbiają kupować ryby. Teraz wiemy, że mogą odróżnić swoje od swoich przyjaciół ”.

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

Możesz spróbować online !


1
Daje to również wynik 1dla dowolnego prefiksu kodu
Jo King

@JoKing, ponieważ było to gorsze niż tylko prefiksy skryptu, zaakceptował również obcięte linie! Naprawiłem to, ale jestem rozczarowany, że nie jest tak ogólny, jak chciałem, musiałem sprawdzić osiągniętą komórkę na końcu skryptu, aby upewnić się, że cały kod jest dopasowany. Z pewnością można to poprawić, ale nie jestem pewien, czy będę się tym przejmować.
Aaron

6

Python 2, 55

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

Przetestowany:

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

(anything else) -> False


3
Nie działa na dowolnym pliku, który zaczyna się od pierwszego wiersza równego a='a=%r;print a%%a==raw_input()';print a%a==raw_input().
stoisko 17.04.13

To prawda, że ​​wprowadzanie wielu wierszy nie jest obsługiwane.
trzęsienie ziemi

Trywialny fix byłoby wymienić raw_input()z __import__('sys').stdin.read().
feersum

Jestem zdezorientowany sformułowaniem wyzwania (ponieważ nie jestem dobry w gramatyce angielskiej). Czy to jest dozwolone? print raw_input()==open(__file__).read()? Ma tylko 40 bajtów, wykorzystuje twoje raw_input()podejście, ale czyta swój kod.
Simon

1
@ Simon To niedozwolone, jest to jedna ze standardowych luk w takich wyzwaniach. I tak, to właśnie oznaczaYour program must not access any special files, such as the file of its own source code.
PunPun1000,

6

JavaScript ES6, 16 14 bajtów

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

Minus dwa bajty dzięki Neilowi.

31 bajtów, jeśli musimy wprowadzić dane przez monit.

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

38 bajtów, jeśli musimy generować przez alert.

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

Jest to właściwy sposób, aby to zrobić, ponieważ odpowiedź Optymalizatora nie akceptuje całego kodu źródłowego.


1
Fajnie, choć po prostu bym napisał '$='+$.
Neil

Och, prawda @Neil
Conor O'Brien

1
Jestem pewien, że potrzebujesz zakończenia, ;$()ponieważ wywołanie funkcji jest częścią quine. Oznacza to również, że musisz przełączyć się promptna konto, aby uzyskać dane wejściowe.
Mama Fun Roll

1
To nie jest problem. Wywołanie funkcji jest konieczne, ponieważ jest częścią quine. Zezwolenie użytkownikowi na wywołanie go jako funkcji zrujnowałoby quine.
Mama Fun Roll

1
spróbuj$=_=>prompt()==`$=${$};$()`;$()
Mama Fun Roll

5

Node.js: 54

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

Testujesz go, zapisując go w pliku f.js(dokładna nazwa nie ma znaczenia) i używając

node f.js "test"

(który zwraca false) lub

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

(które wyjścia prawda)

Stworzyłem też inną wersję opartą na eval:

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

Teraz ma 72 znaki, postaram się to skrócić, kiedy będę miał czas.


1
@ dan1111 Dlaczego? Nie ma dostępu do żadnego pliku. Właśnie wskazałem, jak uruchomić program osobom, które nie były przyzwyczajone do node.js. Nie czyta pliku.
Denys Séguret,

1
Wszystkie rozwiązania JavaScript korzystają z faktu, że możesz uzyskać dostęp do własnego kodu źródłowego w JS. To technicznie może nie „uzyskać dostępu do pliku własnego kodu źródłowego”, ale osiąga dokładnie to samo. Sądzę jednak, że twoja odpowiedź jest zgodna z prawem, ponieważ pytanie specjalnie tego nie zabraniało.

Cóż, masz dostęp do źródła funkcji (a dokładniej tylko ciała), który jest częścią programu. To jest jak użycie mixin () w D. Ale nie sądzę, że dwie inne odpowiedzi JS, w tym jedna ode mnie, naprawdę kwalifikują się jako „programy”.
Denys Séguret,

@dystroy faktycznie mixin w D przypomina bardziej korzystanie z eval niż czytanie źródła
maniak ratchet

@ratchetfreak tak, masz rację. Ale myślę, że twój program używa pewnego rodzaju toString wartości wyliczeniowej, prawda? A każdy kod używający eval / mixin jest mniej więcej taki sam, jak użycie źródła funkcji.
Denys Séguret,

5

Smalltalk (dialekt Pharo 2.0)

Zaimplementuj tę metodę 41 znaków w String (brzydkie formatowanie dla golfa kodowego):

isItMe^self=thisContext method sourceCode

Następnie oceń to w obszarze roboczym (printIt tradycyjnym sposobem Smalltalk)
Dane wejściowe nie są odczytywane ze standardowego wejścia, to tylko ciąg znaków, na który wysyłamy komunikat (co jeszcze program może być w języku Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

Ale oszukujemy, sourceCode czyta jakiś plik źródłowy ...
Oto wariant z 51 znakami, który nie:

isItMe
    ^ self = thisContext method decompileString

I przetestuj za pomocą:

'isItMe
    ^ self = thisContext method decompileString' isItMe

Jeśli ciąg znaków w obszarze roboczym nie jest uważany za prawidłowe dane wejściowe, zobaczmy, jak używać niektórych okien dialogowych w 116 znakach.
Po prostu oceń to zdanie:

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

Ponieważ format dekompilacji obejmuje CR i TAB, zmieniamy to za pomocąSeparatorsCompacted.
Następnie pomijamy pierwsze 7 znaków: „doIt ^”

Wreszcie wariant 105 znaków przy użyciu stdin, po prostu zinterpretuj to zdanie z wiersza poleceń, aby poczuć się bardziej popularny:

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

4

flex - 312 znaków

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');

Prawdopodobnie można go skrócić, ale działa z wejściem wieloliniowym (konieczne, ponieważ kod źródłowy składa się z wielu linii), a nawet dla danych wejściowych zawierających program jako podłańcuch. Wydaje się, że wiele odpowiedzi jak dotąd zawodzi na jednym lub obu z nich.

Kompiluj polecenie: flex id.l && gcc -lfl lex.yy.c


3

D (133 znaki)

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+[])}

zadzwoni i()i poprosi o wprowadzenie danych


+[]Powinno być dobrowolne jak JS będzie auto-go typu cast
Downgoat


3

Python 2, 47 bajtów

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

Prosty quine z dodanym czekiem.


To nie działa printjest funkcją Python 3. Trzeba to zrobić print(_%%_==input())';print(_%_==input())lub zmienić na Python 2.
Mego

3

CJam , 12 bajtów

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

Wypróbuj online!

Wyjaśnienie

To po prostu używa standardowej ramy quine CJam.

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

Co robi blok:

 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.

To jest dokładnie rozwiązanie, które miałem ._.
Esolanging Fruit

2

Tcl, 111 znaków

set c {set c {$c};puts [expr {[read stdin] eq [subst -noc \$c]}]};puts [expr {[read stdin] eq [subst -noc $c]}]

2

Perl, 52 znaki

$_='$/=$\;$_="\$_=\47$_\47;eval";print<>eq$_|0';eval

2

Python, 187 bajtów

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))

Uważaj, aby nie dodać nowego wiersza na końcu. Ktoś z lepszym Python-fu może go skrócić.


2
Możesz użyć, C=chraby usunąć kilka bajtów. Skróć także nazwę zmiennej code.
Zach Gates,

2
Ponieważ nikt nie powiedział tego od ponad roku, witamy w PPCG!
Erik the Outgolfer

2

Łuska , 11 bajtów

=hS+s"=hS+s

Wypróbuj online!

Wyjaśnienie

Wyjaśnienie używa ¨do rozgraniczenia ciągów (aby uniknąć nieczytelnego ucieczki):

     "=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?

Usuwając funkcję =, możesz sprawdzić , czy rzeczywiście będzie pasować tylko do samego źródła.


2

> <> , 24 bajty

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

Wypróbuj online!

Zawijanie literału ciągu znaków, a następnie sprawdzanie, czy dane wejściowe są identyczne ze stosem, z ostatecznym sprawdzeniem, czy nie ma już danych wejściowych.


2

Galaretka , 10 bajtów

“Ṿ;$⁼”Ṿ;$⁼

Wypróbuj online!

“Ṿ;$⁼”Ṿ;$⁼
“Ṿ;$⁼”      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 bajtów

0"D34çýQ"D34çýQ

Zmienia domyślny 0"D34çý"D34çý przez dodanie Q(sprawdź równość z niejawnym wejściem)

Wypróbuj online.

Wyjaśnienie:

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)

Fajna 15 bajtów alternatywa dostarczona przez @Grimy :

187745012D27BJQ

Wypróbuj online.

Wyjaśnienie:

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
187745012D27BJQjest remis.
Grimmy

1

C - 186 176 znaków

Jedna wkładka:

 *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');}

Z białymi znakami (pamiętaj, że powoduje to uszkodzenie programu):

*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

Runiczny , 11 bajtów

"3X4+kSqi=@

Wypróbuj online!

TIO zostało zaktualizowane i nie ma już problemu z odczytem danych wejściowych (i nie wymaga już spacji końcowych).

Wyjaśnienie

>                 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

Rozwiązanie JoKing:

"'<~qi=@|

Wyjaśnienie

  <              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 Bardzo sprytny.
Draco18s

W rzeczywistości 9 bajtów unika rewersu
Jo King

@JoKing Prawdopodobnie powinienem był do tego dojść (z rozwiązania 10-bajtowego) osobiście, ale jeszcze nie miałem mojej cawfee . Wczoraj doszedłem do wniosku, że posiadanie "po lewej stronie jest jedynym miejscem, do którego naprawdę może się udać, ponieważ posiadanie go gdzie indziej komplikuje sprawy. (Ale teraz musiałem uruchomić go w moim debuggerze, aby zobaczyć, co robi ...)
Draco18s

1

R , 54 bajty

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

Wypróbuj online!

bodypobiera treść funkcji (trochę ją dzieli, więc body(f)[3]to wszystko od paste0początku). Co ciekawe, ponownie bodyformatuje kod, dodając spacje po przecinkach itp. Jest to zatem rzadki przypadek odpowiedzi R golfa ze spacją po przecinku.

Działa body(f)to, ponieważ jest obiektem typu languagei istnieje as.charactermetoda dla tego typu. Z drugiej strony, fi args(f)są typu closure, i nie mogę być konwertowany na typ postaci, o ile wiem. Nie pytaj mnie, jaki jest typ języka…


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.