64
\$\begingroup\$

Long-time lurker, first-time poster. So here goes.

In the Wikipedia page for quine, it says that "a quine is considered to be 'cheating' if it looks at its own source code." Your task is to make one of these "cheating quines" that reads its own source code.

This is , so the shortest code in bytes - in each language - wins. This means that a 5-byte Pyth script would not beat a 21-byte Python script - but a 15-byte Python script would.

You must use file I/O to read the source code, so the following JavaScript code, taken from the official Wikipedia page, is invalid:

function a() {
    document.write(a, "a()");
}
a()

It must access the source code of the file on disk.

You are not allowed to specify the file name. You must make it detect the filename itself.

Everyone clear? Go!

\$\endgroup\$
15
  • 1
    \$\begingroup\$ Is a trailing newlines not present in the original file allowed? \$\endgroup\$
    – isaacg
    Commented Oct 29, 2015 at 22:04
  • 3
    \$\begingroup\$ @isaacg IMHO That's not a quine, since it is not the source code. \$\endgroup\$
    – user42643
    Commented Oct 29, 2015 at 22:05
  • 3
    \$\begingroup\$ You should state a requirement that it determine the actual filename instead of assuming a hard-coded string for the source location. \$\endgroup\$
    – feersum
    Commented Oct 29, 2015 at 22:26
  • 3
    \$\begingroup\$ I agree with @feersum though, that requiring a specific file name makes this challenge way to trivial. \$\endgroup\$
    – user42643
    Commented Oct 29, 2015 at 22:33
  • 2
    \$\begingroup\$ Can we assume that (for compiled languages) the source code is in the same folder (i.e. we can just add ".cpp" or ".hs" to arg[0] to get the source). \$\endgroup\$
    – HEGX64
    Commented Nov 1, 2015 at 9:15

83 Answers 83

3
\$\begingroup\$

F#, 54 Bytes

printf"%s"(System.IO.File.ReadAllText __SOURCE_FILE__)

Usage:

fsi --exec a.fsx
\$\endgroup\$
3
\$\begingroup\$

Perl 5, 15 13 bytes

Credit to the Bash solution for inspiring this:

print`cat $0`

EDIT: Don't need the semi-colon or first space.

\$\endgroup\$
1
  • \$\begingroup\$ Not pure perl, it needs some other executable, namely cat, present and findable in the $PATH. But if it is present, it can be assumed as just a command available to perl, so why not. \$\endgroup\$ Commented May 12, 2017 at 20:16
3
\$\begingroup\$

Scala(2.10), 101 bytes

import scala.reflect.io.File;object A extends App{print(File(getClass.getName.head+".scala").slurp)}

Similar to the Java and C# answers. The only "interesting" parts here are the .head to drop the $ from the class name and the slurp method (which I'd never seen before) to read the file in as a String.

\$\endgroup\$
2
  • \$\begingroup\$ Cool, I didn't know that method existed in scala. Mine is slightly longer using groovy. \$\endgroup\$
    – J Atkin
    Commented Nov 3, 2015 at 14:12
  • \$\begingroup\$ You are not allowed to assume the file extension is .scala. \$\endgroup\$
    – Makonede
    Commented Jul 9, 2021 at 20:42
3
\$\begingroup\$

Python 2, 27 bytes

print next(open(__file__))

Python 3, 28 bytes

print(next(open(__file__)))

Byte count includes new line.

\$\endgroup\$
2
  • \$\begingroup\$ My first contribution: harsh criticism welcomed. \$\endgroup\$ Commented Nov 3, 2015 at 13:48
  • \$\begingroup\$ Sad to see this one this far down while worse-scoring Python attempts are higher. As a historical note, this requires Python 2.6 and up; even 2.6 was past EOL at the time, but still. \$\endgroup\$ Commented Jul 27, 2023 at 19:53
3
\$\begingroup\$

Raku, 17 bytes

$?LANG.orig.print

Try it online!

This relies on some compiler internals.

\$\endgroup\$
2
\$\begingroup\$

Java - 214 194

import java.io.*;class Q{Q(){try{System.out.print(new BufferedReader(new FileReader(getClass().getName()+".java")).readLine());}catch(Exception e){}}public static void main(String[]a){new Q();}}

Reduced a lot with using @VoteToClose method of finding the filename for java.

Readable version:

import java.io.*;

class Q {
        Q() {
                try {
                        System.out.print(new BufferedReader(new FileReader(getClass().getName()+".java")).readLine());
                } catch(Exception e) {}
        }
        public static void main(String[] a) {
                new Q();
        }
}

NOTE: The readable version doesn't actually work, it just reads the first line. Just to show what the code is doing

\$\endgroup\$
4
  • \$\begingroup\$ I posted a Java answer as one of the first answers. :P But, just in case you want to narrow this down more, you can remove public from the class declaration. Also, I might steal your method of getting a class name for my answer. ;) \$\endgroup\$ Commented Oct 30, 2015 at 17:19
  • \$\begingroup\$ You are not allowed to assume the file extension is .java. \$\endgroup\$
    – Makonede
    Commented Jul 9, 2021 at 20:47
  • \$\begingroup\$ @Makonede Are you sure? I get an error trying to compile anything that isn't .java \$\endgroup\$
    – Cruncher
    Commented Jul 9, 2021 at 20:56
  • \$\begingroup\$ @Cruncher It doesn't matter, it's still specifying part of the file name. \$\endgroup\$
    – Makonede
    Commented Jul 9, 2021 at 21:36
2
\$\begingroup\$

JavaScript (node.js), 65

with(process)require('fs').createReadStream(argv[1]).pipe(stdout)
\$\endgroup\$
2
\$\begingroup\$

C#, 153 bytes

class A{static void Main(){new A();}A([System.Runtime.CompilerServices.CallerFilePath]string s=""){System.Console.Write(System.IO.File.ReadAllText(s));}}

Readable version:

class A
{
    static void Main()
    {
        new A();
    }

    A([System.Runtime.CompilerServices.CallerFilePath] string s = "")
    {
        System.Console.Write(System.IO.File.ReadAllText(s));
    }
}

Thanks to @Johnbot for the idea to use CallerFilePathAttribute, which avoids any kind of name hardcoding!

\$\endgroup\$
7
  • \$\begingroup\$ I do smell elements of my answer in this! Well done! +1 And welcome to the community! \$\endgroup\$ Commented Oct 30, 2015 at 19:01
  • 1
    \$\begingroup\$ It's possible to get the source file name using the CallerFilePathAttribute. \$\endgroup\$
    – Johnbot
    Commented Nov 2, 2015 at 14:18
  • 1
    \$\begingroup\$ You save 26 characters with string s instead of string sourceFilePath. \$\endgroup\$
    – Comintern
    Commented Nov 2, 2015 at 23:49
  • \$\begingroup\$ I think you can save another 8 bytes if you add using System; at the top and omit System. in all namespace qualifiers (at least I think it worked that way, it's been some years since I've worked with C#) \$\endgroup\$
    – hoffmale
    Commented Nov 3, 2015 at 8:58
  • 2
    \$\begingroup\$ @hoffmale - that doesn't actually work. The using clause doesn't import sub-namespaces, just classes. So it would let me replace System.Console with just Console, but not System.IO with just IO. I could use an alias, using S = System; and shorten the uses of it, but that ends up being a wash. \$\endgroup\$ Commented Nov 3, 2015 at 14:43
2
\$\begingroup\$

Perl, 9 bytes

#!/bin/dd

Perl allows you to change the parser while the file's being read. One thing you can do is to change the program that parses the file entirely via the use of #! on the first line; this feature was intended to allow the use of Perl to fix a system on which shebangs didn't work correctly. dd with no parameters copies standard input to standard output (followed by some statistics on standard error which shouldn't matter), thus is a suitable program to use for a cheating-quine (because Perl reloads the file from disk to give to dd.)

\$\endgroup\$
2
  • 2
    \$\begingroup\$ That is not perl. The kernel reads the first two bytes and interprets them, finds #!' and thus continues to read the line, finds /bin/dd` and thus launches /bin/dd, given the file as argument to dd. NO PERL INVOLVED AT ALL. \$\endgroup\$ Commented May 12, 2017 at 20:23
  • 1
    \$\begingroup\$ @GolarRamblar: It is Perl. You can run perl followed by the filename, and perl itself will do the #! translation. It uses slightly different rules from the kernel for interpreting #! lines, in fact. (Perl originally added this feature so that if you were using an operating system, like Windows or DOS, that does not support #! lines, you could nonetheless use #! scripts by setting Perl as the interpreter for their file type.) \$\endgroup\$
    – user62131
    Commented May 12, 2017 at 20:31
2
\$\begingroup\$

Python 3, 28 35 32 29 21 bytes

lambda:open(__file__)

Try it online! File objects are iterable, and output in a singleton iterable is allowed.

lambda:open(__file__)  # full program
lambda:                # define function taking no arguments which returns...
       open(        )  # file at path...
            __file__   # current script path
\$\endgroup\$
5
  • \$\begingroup\$ This doesn't work unfortunately as print will output a trailing newline not present in the original code. \$\endgroup\$
    – Sisyphus
    Commented Sep 28, 2020 at 22:58
  • \$\begingroup\$ You can suppress the newline by passing end='' parameter to print: Try it online! \$\endgroup\$
    – Bubbler
    Commented Sep 28, 2020 at 23:07
  • \$\begingroup\$ Oh, I actually knew that but didn't know trailing newlines weren't allowed. I'll fix that. \$\endgroup\$
    – Makonede
    Commented Sep 29, 2020 at 15:45
  • \$\begingroup\$ This doesn't work. In order for the file I/O to be meaningful, the code has to be run from a file; while a function could be run at the interpreter prompt and its output would be displayed, a) it would display as a string representation and not formatted output; b) __file__ would not be defined at the REPL and even if it were it couldn't name a file that doesn't exist. \$\endgroup\$ Commented Jul 27, 2023 at 19:58
  • \$\begingroup\$ The previous version, print(*open(__file__),end='') works fine and, unlike the competitors, doesn't require a trailing newline. However, that still doesn't beat Oddthinking's 28-byte (27 in 2.x) solution. \$\endgroup\$ Commented Jul 27, 2023 at 20:13
2
\$\begingroup\$

Javascript (Babel Node), 74 72 bytes

Thanks to Kyle Slattery for posting his answer about __filename.

Also, thanks to Makonede for saving 2 bytes and making my answer correct.

require('fs').readFile(__filename,'utf8',(e,d)=>process.stdout.write(d))
\$\endgroup\$
5
  • 3
    \$\begingroup\$ Welcome to CG&CC! As noted previously, we require solutions to attempt to optimize for a challenge's scoring criterion; this is a code-golf challenge so your code should be as short as you can make it. Some steps you could take might be to remove unnecessary whitespace (and semicolons? I do not actually know JS) and use shorter variable names. Also consider posting the score of your solution, and a link to an online interpreter (such as Try It Online). \$\endgroup\$ Commented Jul 7, 2021 at 23:57
  • 1
    \$\begingroup\$ You should also check out our Welcome Page to get a better idea of what we recommend and expect for answers. \$\endgroup\$ Commented Jul 8, 2021 at 15:27
  • \$\begingroup\$ thats what im going to do thank you \$\endgroup\$
    – moum bou
    Commented Jul 8, 2021 at 21:20
  • 1
    \$\begingroup\$ -2 by removing whitespace, removing braces, and renaming variables: require('fs').readfile(__filename,'utf8',(e,d)=>process.stdout.write(d)). Also, your answer is currently invalid, as it prints a trailing newline. \$\endgroup\$
    – Makonede
    Commented Jul 8, 2021 at 23:04
  • \$\begingroup\$ i missed that point, also thanks for your help man \$\endgroup\$
    – moum bou
    Commented Jul 9, 2021 at 2:19
2
\$\begingroup\$

Python, 22 bytes

input(*open(__file__))

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ This requires the user to terminate the program (by hitting Enter and having the output discarded, or otherwise aborting it), but I tried it with shell redirection and it does get the right output, without adding an extra newline or anything. \$\endgroup\$ Commented Jul 27, 2023 at 20:20
2
\$\begingroup\$

Shell + xargs, 27 bytes

xargs -0a/proc/self/cmdline

Attempt This Online!

On Linux, the file /proc/self/cmdline contains the arguments provided to the current command, including the command's name itself, separated by null bytes. In this case, the command is xargs, and the argument is -0a/proc/self/cmdline.

xargs -0 splits its input on null bytes, and passes them to another command. When a second command isn't specified, it defaults to echo. The -a option makes xargs read from a file instead of STDIN.

I'm not 100% sure if this is valid, because strictly speaking the source code of the shell script itself isn't in /proc/self/cmdline, but it certainly isn't a proper quine, so I think it morally ought to be allowed.

\$\endgroup\$
2
\$\begingroup\$

*nix interpreter directive, 10 bytes

#!/bin/cat

Shebang (#!) abuse. The shebang causes the "code" to be "interpreted" using cat, which prints out the content of the file.

EDIT: Someone else came up with it before me.

\$\endgroup\$
1
  • \$\begingroup\$ Some systems require a line terminator, eg. OpenBSD. \$\endgroup\$
    – Oskar Skog
    Commented Aug 23, 2022 at 13:51
2
\$\begingroup\$

JavaScript (Node.js), 56 bytes

with(require('fs'))writeSync(1,readFileSync(__filename))

Try it online!

\$\endgroup\$
1
\$\begingroup\$

VBScript, 67 bytes

CreateObject("WScript.Shell").Run "cmd /K type "&Wscript.ScriptName
\$\endgroup\$
1
\$\begingroup\$

C (Win32), 36 bytes

main(){CopyFileA(__FILE__,"CON",0);}

CopyFile makes the challenge easier in Win32 than in POSIX or ISO C, that's for sure. You however need to call the compiler with stdcall as its default calling convention.

\$\endgroup\$
1
\$\begingroup\$

Aubergine, 22 bytes, noncompeting

The tab character at the end signals end of file, and the interpreters all crash without it. It's cool that this challenge showed up on my radar this week since I just finished golfing this for the wiki.

-a1+a1=oA=Bi-BA:bB=ia   

I'll explain how it works later. It does not use file I/O but it very much does read its listing, and it is definitely cheating.

\$\endgroup\$
1
\$\begingroup\$

Groovy 92 bytes

Shorter than the other groovy answer, in addition to being filename agnostic.

print new Error().stackTrace*.fileName.collect{it?new File(it):null}.find{it?.exists()}.text

No newline at end of file.

\$\endgroup\$
1
\$\begingroup\$

Vitsy, 4 bytes

This language feature is newer than this question, but not made for this question.

iG`Z

i     Grab input. Since there is no input, it pushes -1 to the stack.
 G    Get the class name of the referenced class. -1 refers to the current class.
  `   Read the file under the name of the stack's contents and push all of it to the stack.
   Z  Output everything in the stack.

As of November 24, class commands allow for referencing other programs accessible by disk, or 'classes'. Normally, it'd be used something like this:

00k

;u someothervitsyfile

Where I execute the 0th line (the first line) of the 0th index of the uses list ('someothervitsyfile'). I can get its name with G like so:

0GZ

;u someothervitsyfile

And, if I have the name, I can get its contents like so:

0G`Z

;u someothervitsyfile

But the special cases of this are -2 and -1, where -2 references the superclass (as defined by ;e) and -1 references the current class.

So, to get the name of the current class, I use -1, get its name, and, with its name being the only thing in the stack, I pull its contents with `.

Very fancy.

You cannot try this online, as it has been disabled to prevent reading server files.

\$\endgroup\$
1
\$\begingroup\$

Mouse-2002, 8 bytes

Expects to be put in a file called MOUSE.001. (Files with the names MOUSE.nnn are the only files Mouse knows how to perform I/O on. I didn't write the interpreter.)

If the EOF char at the end of the file, which is printed to the terminal, crashes your terminal, it's not my fault and I consider this a feature, not a bug.

(1 &F!')

Additionally, technically this is undefined behaviour (though most of Mouse is undefined except in practice) because it promises that the file's length is at least as long as the while(true). If this hangs your system because it's a loop, save your work, run git commit && git push, and don't say I didn't warn you.

\$\endgroup\$
1
\$\begingroup\$

Lua, 31 Bytes

print(io.open(arg[1]):read'*a')

The Arg table contains the following in lua.

{Filename, Command Line Argument1, Command Line Argument 2, ...}

\$\endgroup\$
1
  • \$\begingroup\$ That seems to be more like {[-1]="Interpreter", [0]="Filename", [1]="Command Line Argument1, [2]="Command Line Argument 2"}. So you should read arg[0] instead. \$\endgroup\$
    – manatwork
    Commented Sep 24, 2018 at 20:18
1
\$\begingroup\$

SmileBASIC, 69 68 bytes

LOAD"PRG1:"+PRGNAME$(0),FALSE
PRGEDIT 1
FOR I=0 TO 3?PRGGET$();
NEXT

Load the program into slot 0 (the default slot), and run!

Explanation

LOAD"PRG1:"+PRGNAME$(0),FALSE  load the source code into program slot 1
PRGEDIT 1                      open program slot 1 for editing
FOR I=0 TO 3                   loop 3 times { (no newline here)
?PRGGET$();                      print line, supressing extra newline
NEXT                           }

The ,FALSE on LOAD is required to supress a confirmation dialogue. I wasn't sure if this was required so I threw it in anyways (seems like it should be).

The extra setup of loading the source code into the neighbouring slot is required as SmileBASIC can't read or write from the currently loaded source code for some reason (it clearly reads it to load it into the other slot, but whatever).

As the output format isn't specified, you might be able to get away with just using the first line and claiming the output is found on slot one (which is one tap away) for 29 bytes.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ FALSE in SB just means 0, because SB doesn't have a boolean type. Conditionals (== != < > <= >= || &&) evaluate to 0 when false and 1 when true (with the exception of || and && which evaluate to 3 when the left term is a string; nobody knows why.) Any nonzero number is truthy, as well as all strings, even empty ones. NaN is always falsy and never equals itself. Arrays can't be compared though. Anyway, my point is, turn FALSE into 0 and save 4 characters. You could probably get away with allowing the loading screen but idk. \$\endgroup\$
    – snail_
    Commented Jan 9, 2017 at 14:06
  • \$\begingroup\$ Thanks @snail'! That's exactly the kind of information I needed to get assimilated in golfing with SmileBASIC! I'll update my answer soon. \$\endgroup\$ Commented Jan 9, 2017 at 17:10
1
\$\begingroup\$

SmileBASIC, 26 bytes (newline at end)

Saw @redstarcoder 's answer and wanted to out-golf it. I'm not sorry.

?LOAD("TXT:"+PRGNAME$());

This exploits the fact that PRG is just a resource subtype of TXT (it's literally the same file format with a different icon) and loads the source file into a string. It's then simply printed.

I removed unneeded whitespace wherever the parser would let me, and put it all on one line for show. ? is just a shorthand for PRINT. The ; at the end ensures the PRINT doesn't add an extra newline. This one also doesn't disable the load dialog popup, but whatever.

If you remove the newline using a program that deletes the last character (since SB automatically adds a LF whenever you save through the editor) you can also remove the semicolon, bringing the answer down to 24 bytes. I didn't do this though, because I consider it kinda underhanded.

\$\endgroup\$
1
  • \$\begingroup\$ Being "kinda underhanded" is probably ok in a challenge called "A 'cheating' quine" \$\endgroup\$
    – 12Me21
    Commented Jan 24, 2017 at 6:45
1
\$\begingroup\$

Node.js, 63 bytes

Uses the __filename global to obtain its file path as opposed to process.argv[1], which can be flawed:

require('fs').createReadStream(__filename).pipe(process.stdout)
\$\endgroup\$
1
\$\begingroup\$

GW-BASIC / Applesoft BASIC / IBM BASIC / Commodore BASIC,  6 bytes

1 LIST

Pretty simple. No matter where you loaded the program from or how much is in it, it will always print everything in the program buffer, including itself.

\$\endgroup\$
1
\$\begingroup\$

R, 44 bytes

cat(scan(sub(".*=","",commandArgs()[4]),""))

Prints to stderr as well. If that's not allowed this works for 46 bytes:

cat(readLines(sub(".*=","",commandArgs()[4])))

Run these from the command line using Rscript.

\$\endgroup\$
1
\$\begingroup\$

Burlesque - 25 bytes

With-IO

,%____FILE?rfQ

Disclaimer: I've just added ____FILE because I/O support is still very rudimentary and there was no way of detecting the name of the file. Otherwise this would have been impossible. I/O built-ins aren't available in default builds but can be activated by using ghc ... -DHAVE_IO_UNSAFE ....

Without-IO:

,#Q2 SH ~- ",#Q" \/ .+ sh

Explanation: Burlesque is nasty.

Actual explanation: #Q looks at its own source code and pushes the code that is left in the "execution pipeline" onto the stack. In otherwords: #Q pushes all the code that is to the right to the stack. However, #Q does not look at ALL the source code just what is left in the "execution pipeline of the current execution context":

blsq ) 2ro{#Qj}m[
{1 {j} 2 {j}}

The #Q here is only able to see the j due to the execution context.

On a side-note: Burlesque has other modifiers that allow you to modify code such as for example #q which allows you to overwrite the remaining code in the execution pipeline of the current execution context:

blsq ) 3 4 {?*}#q?+
12

{?*}#q overwrites the ?+ with ?*. With #J we can inject/delay a piece of code by appending it to the execution pipeline:

blsq ) 3 4 {J?*}#J?+
49

The #J here appends J?* to the ?+.

\$\endgroup\$
3
  • \$\begingroup\$ Hm, I'm not sure this satisfies "You must use file I/O to read the source code". \$\endgroup\$ Commented Nov 23, 2018 at 17:35
  • \$\begingroup\$ Oh, right. I should stop stopping prematurely while reading. \$\endgroup\$
    – mroman
    Commented Nov 23, 2018 at 17:36
  • \$\begingroup\$ Meh. If it's allowed for APL to read code from "in-memory" then I can do that too ;) \$\endgroup\$
    – mroman
    Commented Nov 23, 2018 at 18:04
1
\$\begingroup\$

Racket, 63 bytes

#lang racket
(display(file->string(find-system-path'run-file)))

Try it online!

Pretty straightforward - just finds the current file, reads it, and prints it back out.

\$\endgroup\$
1
\$\begingroup\$

Knight (C/AST, *nix), 50 49 bytes

\t represents a raw tab.

O`"cat `tr '\0' '\t'</proc/$PPID/cmdline|cut -f3`"

Doesn't work in the golfed interpreter for some reason, so no TIO.

Abuses the shell command built-in <backtick> and the standardized command line args for Knight, which is knight -f file.kn

/proc/$PPID/cmdline obtains the \0-separated command line arguments of the parent process (which is the knight interpreter itself), tr '\0' '\t' replaces \0 with \t, and cut -f3 takes the third tab-delimited argument. Then, we just cat the file and output the result.

A similar result can be done using the -e flag, but that doesn't read the source file from the disk (unless you count the cmdline file)

-1 byte using a raw tab over \t

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.