63
\$\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\$
12
  • 1
    \$\begingroup\$ Is a trailing newlines not present in the original file allowed? \$\endgroup\$
    – isaacg
    Oct 29 '15 at 22:04
  • 3
    \$\begingroup\$ @isaacg IMHO That's not a quine, since it is not the source code. \$\endgroup\$
    – user42643
    Oct 29 '15 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
    Oct 29 '15 at 22:26
  • 3
    \$\begingroup\$ I agree with @feersum though, that requiring a specific file name makes this challenge way to trivial. \$\endgroup\$
    – user42643
    Oct 29 '15 at 22:33
  • 1
    \$\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
    Nov 1 '15 at 9:15

73 Answers 73

3
\$\begingroup\$

Java 8, 133 125 Bytes (or 150 142 slightly cleaner)

Based on @VoteToClose's answer but choosing Files.copy and thus avoiding the intermediate String creation needed to call System.out:

import java.nio.file.*;interface A{static void main(String[]a) throws Exception{Files.copy(Paths.get(A.class.getName()+".java"),System.out);}}

or hard-coding the class-name even more:

import java.nio.file.*;interface A{static void main(String[] a)throws Exception{Files.copy(Paths.get("A.java"),System.out);}}

Cleaned up:

import java.nio.file.*;

class A {
    public static void main(String[] a) throws Exception {
        Files.copy(Paths.get("A.java"), System.out);
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Welcome to PPCG! (Programming Puzzles and Code Golf). Nice first answer! \$\endgroup\$
    – J Atkin
    Nov 3 '15 at 14:17
  • \$\begingroup\$ This is almost invalid, as we were told to not hardcode a filename. \$\endgroup\$ Dec 5 '15 at 0:28
  • \$\begingroup\$ You are not allowed to assume the file extension is .java. \$\endgroup\$
    – Makonede
    Jul 9 at 20:43
3
\$\begingroup\$

HTML with JavaScript, 115 bytes (doesn't really count)

<!DOCTYPE html><html><title>x</title><script>alert(new XMLSerializer().serializeToString(document))</script></html>

Does this count? I don't mind, it was fun :)

Technically it doesn't open a file. It's also a well-formed HTML5 document. The XMLSerializer was the only tool which also returned the DOCTYPE portion, but is non-standard. Still, it works on chrome and firefox, and I bet other browsers.

And as a bonus:

JavaScript, 41 bytes

alert(document.currentScript.textContent)
\$\endgroup\$
4
  • \$\begingroup\$ Remove ";" at the end, save 1 byte :) \$\endgroup\$ Jul 3 '17 at 7:44
  • 1
    \$\begingroup\$ @ЕвгенийНовиков You're right, not sure why I left that in back then. It seems like I didn't count it though. \$\endgroup\$
    – Domino
    Jul 4 '17 at 11:07
  • \$\begingroup\$ You don't need the <title>x</title> \$\endgroup\$
    – VFDan
    Jul 8 at 21:21
  • \$\begingroup\$ @VFDan A well-formed standalone HTML document needs a title of at least one character, even if browsers will make do without it. I thought it was a nice bit of trivia to display in this silly answer. \$\endgroup\$
    – Domino
    Jul 9 at 6:39
3
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟, 2 chars / 6 bytes

ℹ⬮

Try it here (Firefox only).

The ℹ function both returns and pushes to the stack the source code. There is automatic outputting, so the contents of the stack will be outputted. Therefore, the source code will be outputted.

\$\endgroup\$
6
  • \$\begingroup\$ Does this read the source file, or a copy of the source code? \$\endgroup\$
    – lirtosiast
    Oct 30 '15 at 1:59
  • \$\begingroup\$ Here's the line in the interpreter source with the function. It's not really a file-based interpreter, but it reads the textarea value (aka the code). \$\endgroup\$ Oct 30 '15 at 2:31
  • \$\begingroup\$ You made this change an hour ago. Would your code have worked with the previous version? \$\endgroup\$
    – Dennis
    Oct 30 '15 at 2:47
  • \$\begingroup\$ @Dennis I actually made that change before seeing this challenge. It was because I didn't like the original output format. \$\endgroup\$ Oct 30 '15 at 2:53
  • 3
    \$\begingroup\$ @molarmanful Nevertheless, according to site policy, this is a noncompeting answer due to the fact that it uses a version of your language created after the challenge was posted. \$\endgroup\$
    – Doorknob
    Oct 30 '15 at 3:03
3
\$\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\$
3
  • \$\begingroup\$ This doesn't work unfortunately as print will output a trailing newline not present in the original code. \$\endgroup\$
    – Sisyphus
    Sep 28 '20 at 22:58
  • \$\begingroup\$ You can suppress the newline by passing end='' parameter to print: Try it online! \$\endgroup\$
    – Bubbler
    Sep 28 '20 at 23:07
  • \$\begingroup\$ Oh, I actually knew that but didn't know trailing newlines weren't allowed. I'll fix that. \$\endgroup\$
    – Makonede
    Sep 29 '20 at 15:45
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\$ Oct 30 '15 at 17:19
  • \$\begingroup\$ You are not allowed to assume the file extension is .java. \$\endgroup\$
    – Makonede
    Jul 9 at 20:47
  • \$\begingroup\$ @Makonede Are you sure? I get an error trying to compile anything that isn't .java \$\endgroup\$
    – Cruncher
    Jul 9 at 20:56
  • \$\begingroup\$ @Cruncher It doesn't matter, it's still specifying part of the file name. \$\endgroup\$
    – Makonede
    Jul 9 at 21:36
2
\$\begingroup\$

JavaScript (node.js), 65

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

Python 2, 27 bytes

print next(open(__file__))

Python 3, 28 bytes

print(next(open(__file__)))

Byte count includes new line.

\$\endgroup\$
1
  • \$\begingroup\$ My first contribution: harsh criticism welcomed. \$\endgroup\$ Nov 3 '15 at 13:48
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\$ Oct 30 '15 at 19:01
  • 1
    \$\begingroup\$ It's possible to get the source file name using the CallerFilePathAttribute. \$\endgroup\$
    – Johnbot
    Nov 2 '15 at 14:18
  • 1
    \$\begingroup\$ You save 26 characters with string s instead of string sourceFilePath. \$\endgroup\$
    – Comintern
    Nov 2 '15 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
    Nov 3 '15 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\$ Nov 3 '15 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
  • 1
    \$\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\$ May 12 '17 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
    May 12 '17 at 20:31
2
\$\begingroup\$

Rust, 45 bytes

fn main(){print!("{}",include_str!(file!()))}

Try it online!

The file macro expands to the file it's invoked in's file path, the include_str macro expands to a string literal containing the contents of the file at the specified path, and the print macro prints.

\$\endgroup\$
0
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\$ Jul 7 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\$ Jul 8 at 15:27
  • \$\begingroup\$ thats what im going to do thank you \$\endgroup\$
    – moum bou
    Jul 8 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
    Jul 8 at 23:04
  • \$\begingroup\$ i missed that point, also thanks for your help man \$\endgroup\$
    – moum bou
    Jul 9 at 2:19
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
    Sep 24 '18 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_
    Jan 9 '17 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\$ Jan 9 '17 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
    Jan 24 '17 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\$ Nov 23 '18 at 17:35
  • \$\begingroup\$ Oh, right. I should stop stopping prematurely while reading. \$\endgroup\$
    – mroman
    Nov 23 '18 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
    Nov 23 '18 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\$
1
\$\begingroup\$

Julia 1.0, 29 26 bytes

print(readline(@__FILE__))

Try it online!

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

Nim, 43 bytes

import os
echo readFile(paramStr(0)&".nim")
\$\endgroup\$
1
  • \$\begingroup\$ See my comment on the above answer. You are not allowed to assume the filename ends in .nim. \$\endgroup\$
    – Makonede
    Jul 9 at 20:41
0
\$\begingroup\$

Tcl, 37 bytes

chan copy [open [info script]] stdout

The older, more self explanatory version (43 bytes):

puts -nonewline [read [open [info script]]]
\$\endgroup\$
0
\$\begingroup\$

Lua, 59 characters

print(io.open(debug.getinfo(1,'S').source:sub(2)):read'*a')

Sample run:

bash-4.3$ lua quine.lua 
print(io.open(debug.getinfo(1,'S').source:sub(2)):read'*a')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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