«Обман»


56

Давний Люркер, первый постер. Так что здесь идет.

На странице Википедии о квине говорится, что «квин считается« обманщиком », если она смотрит на собственный исходный код». Ваша задача состоит в том, чтобы создать одну из этих «обманных лозунгов», которая читает собственный исходный код.

Это , поэтому выигрывает самый короткий код в байтах - на каждом языке . Это означает, что 5-байтовый скрипт Pyth не побеждает 21-байтовый скрипт Python, а 15-байтовый скрипт Python.

Вы должны использовать файловый ввод / вывод для чтения исходного кода, поэтому следующий код JavaScript, взятый с официальной страницы Википедии, недопустим:

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

Он должен получить доступ к исходному коду файла на диске .

Вам не разрешено указывать имя файла. Вы должны заставить его обнаруживать само имя файла.

Всем понятно? Идти!


1
Разрешены ли завершающие символы новой строки в исходном файле?
Исаак

3
@isaacg IMHO Это не квин, так как это не исходный код.
mnxomaτ

3
Вы должны указать требование, чтобы оно определяло фактическое имя файла, вместо того, чтобы использовать жестко запрограммированную строку для исходного местоположения.
feersum

3
Я согласен с @feersum, однако, что требование конкретного имени файла делает этот вызов способом тривиальным.
Mynxomaτ

1
Можем ли мы предположить, что (для скомпилированных языков) исходный код находится в той же папке (т.е. мы можем просто добавить «.cpp» или «.hs» в arg [0], чтобы получить исходный код).
HEGX64

Ответы:


60

Зш , 4 байта

<$0

В оболочку Z встроены функции кошачьих. Четвертый символ - перевод строки.

Попробуйте онлайн!

Код никак не зависит от имени файла; это работает, даже если имя файла содержит специальный символ, такой как пробелы или переводы строки.

Тестовый забег

$ cat "my quine.sh"
<$0
$ zsh "my quine.sh" 
<$0
$ diff -s <(zsh "my quine.sh") <(cat "my quine.sh")
Files /dev/fd/63 and /dev/fd/62 are identical

28
feline functionalities:)
theB

48

Баш, 6 байт

cat $0

В основном.


3
Он не печатает новую строку.
Эддисон Крамп

2
catне добавляет символ новой строки (по крайней мере, в моей системе).
спагетто

7
@isaacg catпечатает содержимое предоставленного файла байт за байт.
Деннис

2
@LukStorms Но разве это не будет catрешением, а не bashрешением? И кошка на самом деле не
считается

30
Будет ли это работать, если файл называется -e?
Марк Плотник

32

Исполняемый загрузчик UNIX, 10 байт

#!/bin/cat

Если вы не заботитесь о спаме при стандартной ошибке, вы можете сделать его на один байт короче:

#!/bin/dd

7
Мне это нравится. Не уверен, что он квалифицируется как «язык».
Кевин

Возможно, немного обманул, но не могли бы вы переименовать папку bin и программу cat, чтобы сократить путь?
Джеймс Вебстер

3
Я не предлагаю тебе , кстати. Я полагаю, вы могли бы
Джеймс Вебстер

3
@Kevin «Язык» (то есть переводчик) есть cat. И я думаю, что если вы хотите быть очень конкретным, catпрограмма просто печатает сама себя и совместима с любым существующим форматом файла :)
l0b0

1
@JamesWebster sudo install /bin/cat /c. Знаешь, на всякий случай /binне в корневой файловой системе. Должен иметь это catв однопользовательском ...
Blacklight Shining

25

С, 52

s[99];main(){read(open(__FILE__,0),s,99);printf(s);}

Конечно, это читает исходный код, а не скомпилированную программу - я предполагаю, что это в спецификации.


Вы можете использовать printfвместо того, putsчтобы избежать завершающей новой строки.
feersum

@feersum да, хороший улов
Digital Trauma

19
@DigitalTrauma Конечно, из-за твоего аватара
Питер Олсон

3
На самом деле, putsможно использовать, вам просто нужно readменьше символов.
user4098326


13

PHP, 21 байт

<?=file(__FILE__)[0];

fileчитает файл построчно в массив, и файл имеет только одну строку. Это экономит байт по сравнению с readfile(__FILE__).


Обратите внимание, что это работает только с PHP5.4 и выше, который был первой версией, поддерживающей разыменование массива. Но кроме этого, довольно хороший ответ!
Исмаэль Мигель

1
readfileтоже 21 <?readfile(__FILE__);.
Примо

1
Правильно, это не нужно<?=
Фабиан Шменглер

12

Perl, 15 байт

open 0;print<0>

Сохранено 3 байта благодаря @ ThisSuitIsBlackNot !


2
Вы можете сохранить 3 байта сopen 0;print<0>
ThisSuitIsBlackNot

@ThisSuitIsBlackNot Я был уверен, что есть более короткий способ сделать это, но я не мог всю жизнь работать над этим ... Использование тогда 0предполагает $0?
Дом Гастингс

3
Ага. Смотрите perldoc -f open: «В качестве ярлыка вызов с одним аргументом берет имя файла из глобальной скалярной переменной с тем же именем, что и дескриптор файла: $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";»
ThisSuitIsBlackNot

11

Perl 6, 20 байт

print slurp $?FILE

Я не работал с Perl 6 очень долго, поэтому я не уверен, есть ли какие-то хитрости, чтобы сделать это короче.


2
Вы можете удалить второй пробел?
Eevee

3
@ Eevee Нет, это злится
Hotkeys

11

osascript (AppleScript из командной строки), 40 33 32 байта

(прочитайте путь ко мне), пункт 1

Выполнение в файле с именем osascript a.

Получает первый абзац (строку) файла и печатает его в STDOUT с завершающим символом новой строки, следовательно, новой строкой в ​​коде.


1
Смотрите мое редактирование в ОП
TheInitializer

Работаю над тем, чтобы заставить его работать.
Эддисон Крамп

read path to meкажется, работает на меня. El Cap.
Цифровая травма

Не видел этого, но я так и сделал. : P Спасибо, @DigitalTrauma. РЕДАКТИРОВАТЬ: должны быть рассмотрены завершающие символы новой строки, поэтому вы добавляете новую строку и используете абзацы 1.
Addison Crump

11

Python 2, 32 байта

В конце файла новая строка.

print open(__file__).readline()

Python 3, 33 байта

В конце файла новая строка.

print(open(__file__).readline())

Спасибо feersum за обнаружение проблемы и ее поставку __file__, Loovjo за новый подход к решению Python 2, который сэкономил 17 байтов, и Skyler за решение, которое сохранило еще один байт и работал как в Python 2, так и в 3 (ожидая, printчто это будет функция в Python 3)!

Ссылка на документ для readline


Это также сэкономит 2 байта в python3, потому что вы можете отказаться от endпараметра.
Скайлер

@Skyler Ты абсолютно прав.
Celeo

Как это работает в Python 3, для которого нужны парены print?
Дверная ручка

Python 3 должен print(open(__file__).readline())сопровождаться переводом строки.
Скайлер

В вашем примере с Python 3 написано Python 2, а не Python 3
TheInitializer


10

Python 2.7, 30 байт

print open(__file__).read(29)

Изменить: Просто чтобы быть ясно, код выше должен иметь новую строку в конце как 30-й байт. Я недостаточно знаком с уценкой, чтобы понять, как отобразить ее в блоке кода.

Я использую тот же трюк здесь, что и в моем C-представлении. Это читает весь исходный файл, за исключением завершающего символа новой строки, чтобы учесть дополнительный символ новой строки, который printбудет добавлен к выводу.


Встречается ли это с той же проблемой с завершающим переводом строки, что и в другом представлении?
Коул

Нет. Предполагается, что есть завершающий символ новой строки, который делает 30-й байт в исходном коде, но я не могу отобразить его в блоке кода. Мое представление работает, потому что оно читает первые 29 байтов исходного кода, так что перевод строки printне будет лишним.
xsot

4
Это не то, что делает запятая. Он добавляет пробел вместо новой строки.
xsot

2
можно использовать ␤, чтобы указать на семантически важный символ новой строки
Eevee

9

Java, 212 196 байт (171 байт с сомнительными правилами жесткого кодирования)

Спасибо @Cruncher за сокращение на ~ 15 байт!

Я не сомневаюсь, что это можно сыграть в гольф.

import java.nio.file.*;class A{public static void main(String[]a){new A();}A(){try{System.out.print(new String(Files.readAllBytes(Paths.get(getClass().getName()+".java"))));}catch(Exception e){}}}

Или другой метод, используя статический метод (и имя класса), я получаю 171 байт. Я не уверен, что это квалифицируется как жестко закодированное.

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

Использует конструктор, чтобы получить имя класса нестатическим методом. Использование статического метода ( A.class.getName()) было действительно жестко запрограммировано, поэтому я использовал «правильный» способ. Используя A.class.getName(), этот код сокращается до 171 байта.

Читаемые версии:

Используя конструктор и this.getClass():

import java.nio.file.*;
class A{
    public static void main(String[]a) {
        new A();
    }
    A(){
        try{
            System.out.print(
                new String(
                Files.readAllBytes(
                Paths.get(
                getClass().getName()+".java"))));
        }
        catch(Exception e) {}
    }
}

Используя статический метод A.class.getName():

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

Захватывает все байты файла одновременно и выводит его в STDOUT. Довольно просто.


Почему бы просто не использовать A.class.getName()?
Фабио Ф.

3
Это CodeGolf, а не CodeReview! ;)
Фабио Ф.

1
@FabioF. Да, но я думаю, что это похоже на жестко закодированное имя файла, что противоречит правилам. Суть в том, что если вы измените имя файла, вы должны изменить имя класса (очевидно), но также изменить эту строку, которая похожа на жестко закодированное имя файла.
Cruncher

1
Разве вы не можете вызвать оператор print внутри конструктора и избавить себя от установки статической переменной?
Cruncher

1
@ Cruncher Нах. Вы получаете java.io, я буду придерживаться java.nio - дело не в том, чтобы выиграть, а в том, чтобы показать способы сделать это чрезвычайно лаконично, используя разные методы.
Эддисон Крамп

8

AutoIt, 34 байта

Выводит себя в буфер обмена:

ClipPut(FileRead(@ScriptFullPath))


7

Go, 111 105 байт

package main
import("io"
."os"
."runtime")
func main(){_,p,_,_:=Caller(0)
f,_:=Open(p)
io.Copy(Stdout,f)}

Мой первый код-гольф в Go - я думаю, здесь можно использовать только несколько трюков.


В Go уже есть ответ - использует ли он тот же метод?
Эддисон Крамп

@VoteToClose: Я понимаю это, я действительно был вдохновлен другим, но использовал здесь переименование пакетов (дешевый трюк), а также другую технику для открытия и передачи файла в stdout. Спасли мне массивные 22 байта ;-)
Томаш

Метод на самом деле немного другой, хороший!
Фабиан Шменглер

7

PowerShell, 39 36 31 25 байт

Примерно так крепко, как я могу это получить:

gc $MyInvocation.MyCommand.Path | oh

Поддержанный популярным спросом это было изменено на:

gc $PSCommandPath|echo -n

печатает на текущий стандартный вывод оболочки .


gc $MyInvocation.MyCommand.Pathдостаточно. Он автоматически распечатает его.
Андрей

Это не гарантируется, особенно если сценарий работает тихо
Чад Бакстер

Хаха, да, мне все равно. Я собирался опубликовать, если у кого-то еще не было ответа PowerShell. Но я забыл, что gcэто псевдоним, и он собирался использовать cat, так что у вас там все равно есть байт.
Андрей

Я бы не стал так строг в этом. В противном случае каждый ответ PS явно должен был бы передавать по конвейеру к хост-оболочке, но это зависит от вас ...
Эндрю

Вместо этого вы можете использовать gc $PSCommandPathдля 17 байтов. Проблема, которую я вижу, состоит в том, что это выплевывает новую строку (которой нет в источнике). Сейчас двусмысленно, если завершающий перевод новой строки в порядке или нет ... в зависимости от того, как это правило, нам может понадобиться что-то хитрое, например, gc $PSCommandPath|write-host -nдля 31 байта.
AdmBorkBork


5

C, 49 байтов

s[];main(){read(open(__FILE__,0),s,48);puts(s);}

Изменить: чтобы уточнить, 49-й байт является новой строкой.

Это читает исходный код минус перевод строки в конце, чтобы учесть перевод строки, который putsбудет добавлен в конец вывода.


Этот код вызывает неопределенное поведение дважды.
Джошуа

5
Ну, это код гольф. Мой код выдает желаемый результат, так что это правильное представление.
xsot

1
@xsot В этом случае вам, вероятно, следует перечислить версию + опции компилятора; в противном случае это может быть невозможно проверить.
Джастин

1
Если разрешено неопределенное поведение, если у вас есть какой-то компилятор, который производит желаемый вывод на некотором компьютере во время фазы Луны, тогда я предлагаю int main (void) {* 0; } как решение. В конце концов, стандарт разрешил бы реализацию, которая компилирует это в программу, которая решает проблему. Я бы хорошо использовал поведение, зависящее от реализации, если вы указали компилятор, но с неопределенным поведением вы даже не можете гарантировать, что вы не получите десять разных ответов, если вы выполняете это десять раз подряд на та же машина.
Рэй

1
@MDXF Я серьезно не предлагал написать это решение. Я был против разрешения неопределенного поведения. int main() {*0;} может работать даже на существующих компиляторах, поскольку он содержит неопределенное поведение. Точно так же решение xsot может работать на существующих компиляторах, поскольку оно содержит неопределенное поведение. Ни один из них не может решить проблему. (Хотя, по общему признанию, xsot's, скорее всего , так и сделает, он может так же легко потерпеть крах). Мой фактический аргумент заключается в том, что мы должны разрешать решения, которые зависят от реализации или неопределенного поведения, но не от неопределенного поведения.
Рэй


4

Pyth, 25 байт

$import sys$h'e$sys.argv

Это читает его имя файла. По сути, он ищет argv, открывает файл, соответствующий его последнему аргументу, и печатает его первую строку.


Вы не можете просто сделать h'$__file__$?
kirbyfan64sos

@ kirbyfan64sos Это дает мне ошибку NameError: name '__file__' is not defined. Pyth компилируется в Python, а затем выполняется результирующая строка. Так что я не ожидал, что это сработает.
Исаак

4

Go, 133 байта

Всем понятно? Идти!

package main
import("fmt"
"io/ioutil"
"runtime")
func main(){_,f,_,_:=runtime.Caller(0)
s,_:=ioutil.ReadFile(f)
fmt.Print(string(s))}

2
Это вдохновило меня написать собственное (и самое первое) решение для игры в гольф на Go. Ища некоторые общие приемы, вы можете легко перейти к 123 символам, применяя, например, однобуквенные имена для пакетов r"runtime".
Томас

4

> <> , 13 байт

0:0go:c=?;1+!

Проверено как на онлайн, так и на оффлайн переводчиках. Эта gкоманда наиболее близка к возможности чтения из исходного файла, и если она не учитывается для этой задачи, я отмечу мою запись как не конкурирующую; Я полагаю, что это обычно считается "изменой" для муки.

Попробуйте онлайн.


4

Haskell, 63 байта

Для науки!

import System.Environment
main=getProgName>>=readFile>>=putStr

Работает только с runhaskellкомандой. Очень круто, хотя
HEGX64

4

> <> , 31 байт

Отказ от ответственности: в> <> нет файлового ввода-вывода, однако я подумал, что было бы интересно продемонстрировать его кодовое пространство ввода-вывода, унаследованное от Befunge, одного из языков, который вдохновил> <>.

00voa0+1;!?$~<
1+> :r:@g: ?!^o$

Само читающий Куайн, который я сделал некоторое время назад, вы можете попробовать здесь .

Я только что увидел, что есть более короткая> <> само читающая куина . Хотя он явно лучше в стандартах кода-гольфа, я хотел бы отметить, что он имеет жестко закодированную длину кода, в то время как мой будет копировать дополнительные строки или столбцы кода (при условии, что они не нарушают исходный код).


Я думал о публикации в> <>, но думал, что> <> будет невозможно из-за правила: «Вы должны использовать файловый ввод / вывод для чтения исходного кода»
Sp3000

@ Sp3000 действительно, похоже, я не достаточно хорошо прочитал задание. Я добавлю отказ от ответственности
Аарон

3

F #, 54 байта

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

Использование:

fsi --exec a.fsx

3

Perl 5, 15 13 байт

Благодарим Bash за то, что вдохновили:

print`cat $0`

РЕДАКТИРОВАТЬ: не нужно точку с запятой или первый пробел.


Не чистый Perl, ему нужен какой-то другой исполняемый файл, а именно catприсутствующий и находящийся в $PATH. Но если он присутствует, его можно считать просто доступной командой perl, так почему бы и нет.
Голар Рамблар

3

Node.js, 66 63 байта

p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))

Не использует console.log, что добавляет новую строку.


1
Вы можете сохранить несколько байтов, используя синхронный API:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
Почему не console.log(require('fs').readFileSync(process.argv[1]))\nдля 57 байтов?
Конор О'Брайен,

Это не всегда работает. Скажи, что файл назван test.js. Допустимо вызывать его, запустив node test, что приведет к ошибке.
Патрик Робертс


3

Haskell , 49 байтов

{-#LANGUAGE CPP#-}main=putStr=<<readFile __FILE__

Попробуйте онлайн!

(GHC) Haskell имеет расширение для использования препроцессора C (обычно используется для переносимости между версиями и архитектурами.) Надеюсь, это самоочевидно.


3

HTML с JavaScript, 115 байт (на самом деле не считается)

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

Это считается? Я не против, было весело :)

Технически это не открывает файл. Это также правильно сформированный документ HTML5. XMLSerializer был единственным инструментом, который также возвращал часть DOCTYPE, но не является стандартным. Тем не менее, он работает на Chrome и Firefox, и я держу пари, что другие браузеры.

И в качестве бонуса:

JavaScript, 41 байт

alert(document.currentScript.textContent)

Удалить ";" в конце сохраните 1 байт :)
Евгений Новиков

1
@ ЕвгенийНовиков Вы правы, не знаете, почему я оставил это тогда. Похоже, я не посчитал это все же.
Домино
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.