Write the shortest self-identifying program (a quine variant)

59

12

Write a program that will generate a "true" output iff the input matches the source code of the program, and which generates a "false" output iff the input does not match the source code of the program.

This problem can be described as being related to quines, as the program must be able to somehow compute its own source code in the process.

This is code golf: standard rules apply. Your program must not access any special files, such as the file of its own source code.

Edit: If you so choose, true/false can be replaced with True/False or 1/0.

Example

If the source code of your program is bhiofvewoibh46948732));:/)4, then here is what your program must do:

Input (Stdin)

bhiofvewoibh46948732));:/)4

Output (Stdout)

true

Input

(Anything other than your source code)

Output

false

PhiNotPi

Posted 2013-04-17T14:29:36.033

Reputation: 26 739

7Is the true/false output a strong requirement, or are variations (True/False, 1/0) acceptable as well? – Cristian Lupascu – 2013-04-17T14:54:32.463

Is it a problem if the program outputs a little more than true/false (if it keeps being unambiguous and ends with true/false) ? – Denys Séguret – 2013-04-19T11:31:01.993

5So you mean a Narcissist program? – PyRulez – 2017-07-15T05:57:22.700

1

Related: Interpret your lang, but not yourself?

– Ilmari Karonen – 2014-01-11T05:28:09.953

Very much related – Deadcode – 2020-01-20T07:37:59.573

Answers

34

JavaScript : 26

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

I don't know if a JavaScript file really qualifies as a "program".

Denys Séguret

Posted 2013-04-17T14:29:36.033

Reputation: 780

7

+1 This works because all objects have a .toString() method in JavaScript.

– Andrew Larsson – 2013-12-19T01:33:25.370

This can be shortened using an arrow function f=s=>s=='f='+f – Jonathan – 2018-10-03T16:03:20.710

4@Jonathan yes. But in 2013 it couldn't... – Denys Séguret – 2018-10-03T16:21:12.260

19

JavaScript ES6, 9 characters

This is the only (golfy) way to do it in JS. ES6 just makes it take super less characters

Run this in latest Firefox's Web Console:

f=x=>f==x

Example usage:

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

Optimizer

Posted 2013-04-17T14:29:36.033

Reputation: 25 836

6It could be argued though that the source in this case is f=x=>f==x and not x=>f==x, while Denys Séguret's version does indeed check the whole source. – Hankrecords – 2017-06-08T12:35:43.557

@Hankrecords Let JavaScript decide that. f=x=>f==x function f() f.toSource() "x=>f==x" (basically evaluate the code in console and then evaluate f.toSource() in a browser that supports that method. – Optimizer – 2017-07-15T07:22:07.553

Aren't anonymous functions allowed (shorten your code to x=>f==x) EDIT: nevermind, f is referenced inside of the function – MilkyWay90 – 2019-03-16T22:07:35.267

1@phinotpi - Is my entry still eligible to be picked as an answer ? – Optimizer – 2014-09-13T22:51:10.883

9

Haskell, 72 characters

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

Note: there is no end-of-line character at the end of the script.

$ runhaskell Self.hs < Self.hs
True

hammar

Posted 2013-04-17T14:29:36.033

Reputation: 4 011

8

GolfScript, 11 chars

{`".~"+=}.~

Without the =, this code would be a quine that generates its own source code as a string. The = makes it compare this string to its input and output 1 if they match and 0 if they don't. Note that the comparison is exact — in particular, a trailing newline at the end of the input will cause it to fail.

Explanation:

  • { } is a code block literal in GolfScript;
  • . duplicates this code block, and ~ executes the second copy (leaving the first on the stack);
  • ` stringifies the code block, and ".~"+ appends .~ to it;
  • finally, = compares the resulting string with the input (which is pushed on the stack as a string by the GolfScript interpreter before the program starts) and returns 1 if they match and 0 if they don't.

Ilmari Karonen

Posted 2013-04-17T14:29:36.033

Reputation: 19 513

8

><>, 68 bytes

Fishes love eating fish poop. Now we know they can distinguish theirs from their friends'.

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

You can try it online !

Aaron

Posted 2013-04-17T14:29:36.033

Reputation: 3 689

1This outputs 1 for any prefix of the code as well – Jo King – 2018-09-30T03:12:47.407

@JoKing it was worst than just prefixes of the script, it accepted truncated lines too ! I've fixed it, but I'm disappointed it's not as generic as I wanted it to be, I had to check the reached cell at the end of the script to make sure the whole code was matched. It can certainly be improved, but I'm not sure I will bother. – Aaron – 2018-10-03T15:09:04.023

7

Perl, Infinity 41 38 Characters

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

Update: The program no longer ends with a newline, which means it will work correctly on multi-line files. You have to enter input from STDIN without hitting enter. On Windows I was only able to do this by reading from a file.

Original solution:

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

user7486

Posted 2013-04-17T14:29:36.033

Reputation:

1Nicely done! . . . – mob – 2013-04-19T16:19:46.650

Fails for a file that begins with the code, e.g. (cat id.pl; echo foo)|perl id.pl – Geoff Reedy – 2013-04-20T05:27:19.130

@GeoffReedy, thanks; the program did not handle multi-line input before. It is corrected now. – None – 2013-04-20T07:56:25.580

Darn, is this code bowling? – Matthew Roh – 2017-07-26T14:08:42.520

6

Python 2, 55

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

Tested:

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

(anything else) -> False

flornquake

Posted 2013-04-17T14:29:36.033

Reputation: 1 467

A trivial fix would be to replace raw_input() with __import__('sys').stdin.read(). – feersum – 2015-02-05T22:53:26.240

3Fails on any file that begins with the first line equal to a='a=%r;print a%%a==raw_input()';print a%a==raw_input(). – boothby – 2013-04-17T18:56:02.087

True, multi-line input is not supported. – flornquake – 2013-04-17T20:06:06.150

I am confused by the challenge wording ('cause I am not good with english grammar). Is this allowed? print raw_input()==open(__file__).read() ? It is only 40 bytes, uses your raw_input() approach, but reads it's code. – Simon – 2018-01-29T14:12:24.020

1@Simon That is not allowed, it is one of the standard loopholes for challenges like this. And yes, this is what it means by Your program must not access any special files, such as the file of its own source code. – PunPun1000 – 2018-02-23T18:28:29.730

6

JavaScript ES6, 16 14 bytes

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

Minus two bytes thanks to Neil.

31 bytes if we must take input via prompt.

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

38 bytes if we must output via alert.

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

This is the proper way to do it, as Optimizer's answer does not accept the entire source code.

Conor O'Brien

Posted 2013-04-17T14:29:36.033

Reputation: 36 228

1Nice, although I would just write '$='+$. – Neil – 2016-04-04T22:53:57.600

Oh, true. @Neil – Conor O'Brien – 2016-04-04T22:55:16.703

1I'm pretty sure you need the ending ;$() because the function call is part of the quine. This also means that you'll need to switch to prompt to account for input. – Mama Fun Roll – 2016-04-05T05:14:16.160

@MamaFunRoll I don't think so. The OP allowed functions in other submissions. – Conor O'Brien – 2016-04-05T11:15:39.140

1That's not the problem. The function call is necessary because it's a part of the quine. Allowing the user to call it as a function would ruin the quine. – Mama Fun Roll – 2016-04-05T13:32:41.187

@MamaFunRoll Then how might I incorporate input? – Conor O'Brien – 2016-04-05T14:58:28.517

1try $=_=>prompt()==\$=${$};$()`;$()` – Mama Fun Roll – 2016-04-05T16:28:57.117

5

Node.js : 54

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

You test it by saving it into a file f.js (the exact name has no importance) and using

node f.js "test"

(which outputs false) or

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

(which outputs true)

I also made a different version based on eval :

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

It's now at 72 chars, I'll try to shorten that when I have time.

Denys Séguret

Posted 2013-04-17T14:29:36.033

Reputation: 780

1@dan1111 Why ? It doesn't access any file. I was just pointing how to launch the program to people not used to node.js. It doesn't read the file. – Denys Séguret – 2013-04-18T06:49:11.180

1All of the Javascript solutions take advantage of the fact that you can access your own source code in JS. That may not be technically "accessing the file of its own source code", but it accomplishes the exact same thing. I suppose your answer is legal, though, as the question didn't specifically forbid this. – None – 2013-04-19T09:32:56.977

Well, you access the source of a function (only the body to be precise) which is part of the program. That's like using mixin() in D. But I don't think the two other JS answers, including one from me, really qualify as "programs", though. – Denys Séguret – 2013-04-19T09:36:51.490

@dystroy actually mixin in D is more like using eval than reading source – ratchet freak – 2013-04-19T09:51:44.120

@ratchetfreak yes, you're right. But I think your program uses a kind of toString of the enum value, right ? And any code using eval/mixin is about the same trick than using the source of the function. – Denys Séguret – 2013-04-19T09:54:18.800

@dystroy eval/mixin requires more setup before you can access the source (like saving into a var and escaping), reading the source directly doesn't and can work on all programs in a modular fashion – ratchet freak – 2013-04-19T09:58:37.317

5

Smalltalk (Pharo 2.0 dialect), 41 bytes

Implement this 41 chars method in String (ugly formatting for code-golf):

isItMe^self=thisContext method sourceCode

Then evaluate this in a Workspace (printIt the traditional Smalltalk way)
The input is not read from stdin, it's just a String to which we send the message (what else a program could be in Smalltalk?):

'isItMe^self=thisContext method sourceCode' isItMe.

But we are cheating, sourceCode reads some source file...
Here is a variant with 51 chars which does not:

isItMe
    ^ self = thisContext method decompileString

And test with:

'isItMe
    ^ self = thisContext method decompileString' isItMe

If a String in a Workspace is not considered a valid input, then let's see how to use some Dialog Box in 116 chars
Just evaluate this sentence:

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

Since decompile format includes CR and TAB, we change that withSeparatorsCompacted.
Then we skip the first 7 chars are 'doIt ^ '

Finally a 105 chars variant using stdin, just interpret this sentence from command line, just to feel more mainstream:

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

aka.nice

Posted 2013-04-17T14:29:36.033

Reputation: 411

4

flex - 312 chars

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

Can probably be made shorter, but it works with multi-line input (necessary since the source code is multiple lines) and even for inputs that contain the program as a substring. It seems many of the answers so far fail on one or both of these.

Compile command: flex id.l && gcc -lfl lex.yy.c

Geoff Reedy

Posted 2013-04-17T14:29:36.033

Reputation: 2 828

3

D (133 chars)

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

ratchet freak

Posted 2013-04-17T14:29:36.033

Reputation: 1 334

3

JavaScript (V8), 35

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

call i() and it will prompt for input

Griffin

Posted 2013-04-17T14:29:36.033

Reputation: 4 349

The +[] should be optional as JS will auto-type-cast it – Downgoat – 2016-01-18T18:10:38.120

3

CJam, 12 bytes

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

Try it online!

Explanation

This just uses the standard CJam quine framework.

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

What the block does:

 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.

Business Cat

Posted 2013-04-17T14:29:36.033

Reputation: 8 927

This is exactly the solution I had ._. – Esolanging Fruit – 2018-03-27T07:45:39.490

3

GolfScript - 26

":@;[34]@+2*=":@;[34]@+2*=

Inspired from http://esolangs.org/wiki/GolfScript#Examples

Another version:

"[34].@@;+2*="[34].@@;+2*=

Too bad that \ is both swap and escape...

aditsu quit because SE is EVIL

Posted 2013-04-17T14:29:36.033

Reputation: 22 326

3

Python 2, 47 bytes

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

A simple quine with the added check.

Rɪᴋᴇʀ

Posted 2013-04-17T14:29:36.033

Reputation: 7 410

This doesn't work. print is a function is Python 3. You'd need to do print(_%%_==input())';print(_%_==input()) or change it to Python 2. – Mego – 2016-07-22T05:52:34.127

2

Tcl, 111 chars

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

Johannes Kuhn

Posted 2013-04-17T14:29:36.033

Reputation: 7 122

2

Perl, 52 char

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

mob

Posted 2013-04-17T14:29:36.033

Reputation: 2 506

2

Husk, 11 bytes

=hS+s"=hS+s

Try it online!

Explanation

The explanation uses ¨ to delimit strings (to avoid unreadable escaping):

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

By removing the function = you can verify that it will indeed only match the source itself.

ბიმო

Posted 2013-04-17T14:29:36.033

Reputation: 15 345

2

Python 2, 40 bytes

s="print's=%r;exec s'%s==input()";exec s

Try it online!

totallyhuman

Posted 2013-04-17T14:29:36.033

Reputation: 15 378

2

><>, 24 bytes

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

Try it online!

Wrapping string literal followed by checking whether the input is identical to the stack, with a final check that there is no more input.

Jo King

Posted 2013-04-17T14:29:36.033

Reputation: 38 234

2

Jelly, 10 bytes

“Ṿ;$⁼”Ṿ;$⁼

Try it online!

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

dylnan

Posted 2013-04-17T14:29:36.033

Reputation: 4 993

2

05AB1E, 15 bytes

0"D34çýQ"D34çýQ

Modifies the default 0"D34çý"D34çý by adding Q (check for equality with the implicit input)

Try it online.

Explanation:

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)

Cool 15 bytes alternative provided by @Grimy:

187745012D27BJQ

Try it online.

Explanation:

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)

Kevin Cruijssen

Posted 2013-04-17T14:29:36.033

Reputation: 67 575

3187745012D27BJQ is a tie. – Grimmy – 2019-06-13T12:21:57.397

2

Python, 187 bytes

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

Careful not to add newline at the end. Someone with better Python-fu might be able to shorten it.

Emilio

Posted 2013-04-17T14:29:36.033

Reputation: 121

2You can use C=chr to drop several bytes. Also, shorten the variable name code. – Zach Gates – 2015-09-19T03:06:41.323

2Since nobody said it for over a year, Welcome to PPCG! – Erik the Outgolfer – 2016-10-16T14:41:11.743

1

Stax, 26 bytes

"34bLN26)s:f="34bLN26)s:f=

Run and debug it

Weijun Zhou

Posted 2013-04-17T14:29:36.033

Reputation: 3 396

1

q, 8 bytes

{x~.z.s}

Return boolean on input matching the self-referential .z.s

Thaufeki

Posted 2013-04-17T14:29:36.033

Reputation: 421

1

Runic, 11 bytes

"3X4+kSqi=@

Try it online!

TIO got updated and there's no longer an issue reading input (and no longer requires a trailing whitespace).

Explanation

>                 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's solution:

"'<~qi=@|

Explanation

  <              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 no longer trusts SE

Posted 2013-04-17T14:29:36.033

Reputation: 3 053

110 bytes – Jo King – 2018-09-30T06:37:41.517

@JoKing Very clever. – Draco18s no longer trusts SE – 2018-09-30T15:00:26.110

Actually, 9 bytes avoids the reverse

– Jo King – 2018-09-30T15:24:24.377

@JoKing I probably should've been able to arrive at that (from the 10 byte solution) myself, but I haven't had my cawfee yet. I'd already worked out yesterday that having the " on the left is the only place it can really go, because having it elsewhere complicates things. (But just now I had to run it in my debugger to see what it was doing...)

– Draco18s no longer trusts SE – 2018-09-30T15:40:24.597

1

C - 186 176 characters

One liner:

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

With whitespace (note that this breaks the program):

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

Josh

Posted 2013-04-17T14:29:36.033

Reputation: 2 783

1

R, 54 bytes

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

Try it online!

body gets the body of the function (splitting it a bit, so that body(f)[3] is everything from paste0 onwards). Interestingly, body reformats the code, adding spaces after commas, etc. This is thus a rare case of an R golf answer with a space after a comma.

This works because body(f) is an object of type language, and there exists an as.character method for this type. On the other hand, f and args(f) are of type closure, and cannot be converted to character type as far as I can tell. Please don't ask me what the language type is for…

Robin Ryder

Posted 2013-04-17T14:29:36.033

Reputation: 6 625

1

Keg, 36 28 26 bytes

`:&\`ⁿ^\`ⁿ&⅀=`:&\`ⁿ^\`ⁿ&⅀=

Try it online!

Same concept as before, but shorter.

Answer History

`:&\`ⁿ⅍^\`ⁿ⅍++&+¿=`:&\`ⁿ⅍^\`ⁿ⅍++&+¿=

Try it online!

Who knew generating a program that knows itself would be so unreadable!

Explained

The very first step here is to generate the string that will be checked against. At this point, we don't particularly know what the checking part will look like, but we do know that there will be a string that looks like so:

`\`ⁿ⅍^\`ⁿ⅍++`

Which would consequently be followed by:

 \`ⁿ⅍^\`ⁿ⅍++

This creates a string which contains itself quoted... Something needed for when input is taken, as the quotes are going to be present.

From here, string equality is quite easy, coming in at a trivial 2 bytes:

¿=

Incorporating this into the string gives:

`\`ⁿ⅍^\`ⁿ⅍++¿=`\`ⁿ⅍^\`ⁿ⅍++¿=

At this stage, one might think the quine is complete... It has the string part and it has the equality part... What else could be needed? Well. Let me tell you we ain't done yet.

Y'see, we have a quoted string on the stack, but we don't have it's unquoted equivalent present, meaning we need to account for that. The register works well here:

`:&\`ⁿ⅍^\`ⁿ⅍++&+¿=`:&\`ⁿ⅍^\`ⁿ⅍++&+¿=

And there you have it: a self identifying program written completely on a phone keyboard.

Lyxal

Posted 2013-04-17T14:29:36.033

Reputation: 5 253

It still outputs 1 if the input is followed by a newline and then anything else – Jo King – 2020-01-19T23:32:43.527

Well of course it would, because Keg only reads one line at a time. I'll have to clarify input methods with Keg, because otherwise multi line input isn't possible. – Lyxal – 2020-01-19T23:38:27.397

1

Perl 6, 33 bytes

<dd "<$_>~~.EVAL"eq slurp>~~.EVAL

Try it online!

Outputs either Bool::True or Bool::False to STDERR. This is the basic quine format, with an added check against input (eq slurp).

Jo King

Posted 2013-04-17T14:29:36.033

Reputation: 38 234

0

V, 19 bytes

ñOÑ~"qpxØ¥^¨©î±¥$

Try it online!

Prints 1 or 0. Here is a hexdump:

00000000: f14f d11b 7e22 7170 78d8 a55e a881 a9ee  .O..~"qpx..^....
00000010: b1a5 24                                  ..$

James

Posted 2013-04-17T14:29:36.033

Reputation: 54 537

0

Java 8, 288 bytes (Full Program with STDIN)

interface M{static void main(String[]a){String s="interface M{static void main(String[]a){String s=%c%s%1$c;System.out.print(s.format(s,34,s).equals(new java.util.Scanner(System.in).nextLine()));}}";System.out.print(s.format(s,34,s).equals(new java.util.Scanner(System.in).nextLine()));}}

Try it online.

Java 8, 210 bytes (Full Program with Console Arguments)

interface M{static void main(String[]a){String s="interface M{static void main(String[]a){String s=%c%s%1$c;System.out.print(s.format(s,34,s).equals(a[0]));}}";System.out.print(s.format(s,34,s).equals(a[0]));}}

Try it online.

Java 8, 108 bytes (Function)

i->{String s="i->{String s=%c%s%1$c;return s.format(s,34,s).equals(i);}";return s.format(s,34,s).equals(i);}

Try it online.

Explanation:

-part:

  • The String s contains the unformatted source code.
  • %s is used to input this String into itself with the s.format(...).
  • %c, %1$c and the 34 are used to format the double-quotes.
  • s.format(s,34,s) puts it all together

Challenge-part:

  • .equals(...) checks if this formatted source code equals the input.
    • java.util.Scanner(System.in).nextLine() is used as this input for STDIN
    • a[0] is used as this input for Console arguments
    • i is used as this input for the lambda function

Kevin Cruijssen

Posted 2013-04-17T14:29:36.033

Reputation: 67 575

0

JavaScript ES6, 14 bytes

Like the other javascript answer but includes it's entire source code and not just the function

a=q=>'a='+a==q

Example usage:

a("q=>'a='+a==q") // returns false
a("a=q=>'a='+a==q") // returns true

pfg

Posted 2013-04-17T14:29:36.033

Reputation: 735

0

Pascal (FPC), 167 157 bytes

const b=#39';var s:string;begin read(s);write(s=a+b+#39#59#97#61#39+a+b)end.';a='const b=#39';var s:string;begin read(s);write(s=a+b+#39#59#97#61#39+a+b)end.

Try it online!

While substring can be easily extracted, like in my regular quine, unfortunately, they cannot be concatenated because FPC thinks it is an array in these circumstances. In a and b are characters before and after constant definitions. #39#59#97#61#39 is a replacement for ';a=' as this is not represented in the constants. #39 represents ' and is at the start of b, glued together to the rest of b, to shorten the comparison expression as much as possible.

AlexRacer

Posted 2013-04-17T14:29:36.033

Reputation: 979

0

Zsh, 33 bytes

f () {
	[ "`type -f f`" = $1 ]
}

Try it online!

The extra spaces, tab, and newlines are required. type -f f does not print the original source, but the function formatted in a particular way, with indentation and a trailing newline.

GammaFunction

Posted 2013-04-17T14:29:36.033

Reputation: 2 838

0

TeX, 55 bytes

The file has to be saved as a.tex and should be run using pdftex a.tex. The script doesn't terminate after returning 1 or 0, if that should be necessary append it by \end (+4 bytes). If it should work for arbitrary file names replace \openin0a with \openin0\jobname (+7 bytes).

\openin0=a\read0to\0\read1to~\message{\ifx\0~1\else0\fi}

Skillmon

Posted 2013-04-17T14:29:36.033

Reputation: 431

0

Python 3.8 (pre-release), 42 bytes

exec(s:="print('exec(s:=%r)'%s==input())")

Try it online!

Mukundan

Posted 2013-04-17T14:29:36.033

Reputation: 1 188

0

PowerShell, 28 bytes

Very similar to this JavaScript answer, uses function provider.

filter f{"$Function:f"-eq$_}

Example

PS > '"$Function:f"-eq$_' | f
True

PS > 'xxx' | f
False

beatcracker

Posted 2013-04-17T14:29:36.033

Reputation: 379