Một trò lừa đảo gian lận


56

Lurker thời gian dài, poster lần đầu tiên. Vì vậy, ở đây đi.

Trong trang Wikipedia cho quine , nó nói rằng "một quine được coi là 'gian lận' nếu nó nhìn vào mã nguồn của chính nó." Nhiệm vụ của bạn là tạo ra một trong những "mánh gian lận" đọc mã nguồn của chính nó.

Đây là , vì vậy mã ngắn nhất tính bằng byte - trong mỗi ngôn ngữ - sẽ thắng. Điều này có nghĩa là tập lệnh Pyth 5 byte sẽ không đánh bại tập lệnh Python 21 byte - nhưng tập lệnh Python 15 byte thì có.

Bạn phải sử dụng tệp I / O để đọc mã nguồn, do đó, mã JavaScript sau, được lấy từ trang Wikipedia chính thức, không hợp lệ:

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

Nó phải truy cập mã nguồn của tệp trên đĩa .

Bạn không được phép chỉ định tên tệp. Bạn phải làm cho nó phát hiện tên tệp chính nó.

Mọi người rõ chưa? Đi!


1
Là một dòng mới không có trong tập tin gốc được cho phép?
isaacg

3
@isaacg IMHO Đó không phải là một câu hỏi, vì nó không phải là mã nguồn.
mınxomaτ

3
Bạn nên nêu một yêu cầu rằng nó xác định tên tệp thực tế thay vì giả sử một chuỗi mã hóa cứng cho vị trí nguồn.
frageum

3
Mặc dù vậy, tôi đồng ý với @feersum, việc yêu cầu một tên tệp cụ thể khiến cho thách thức này trở nên tầm thường.
mınxomaτ

1
Chúng ta có thể giả sử rằng (đối với các ngôn ngữ được biên dịch) mã nguồn nằm trong cùng một thư mục (nghĩa là chúng ta chỉ cần thêm ".cpp" hoặc ".hs" vào arg [0] để lấy nguồn).
HEGX64

Câu trả lời:


60

Zsh , 4 byte

<$0

Shell Z có các chức năng mèo được tích hợp sẵn. Ký tự thứ tư là một nguồn cấp dữ liệu.

Hãy thử trực tuyến!

Mã không phụ thuộc vào bất kỳ cách nào vào tên tệp; nó hoạt động ngay cả khi tên tệp chứa ký tự đặc biệt, chẳng hạn như dấu cách hoặc dòng mới.

Chạy thử nghiệm

$ 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

Bash, 6 byte

cat $0

Về cơ bản.


3
Nó không in một dòng mới.
Addison Crump

2
catkhông nối thêm một dòng mới (ít nhất là trên hệ thống của tôi).
một spaghetto

7
@isaacg catin nội dung của byte tệp được cung cấp trên mỗi byte.
Dennis

2
@LukStorms Nhưng đây không phải là một catgiải pháp, thay vì một bashgiải pháp? Và con mèo không thực sự đủ điều kiện làm ngôn ngữ lập trình
Fabian Schmengler

30
Điều này sẽ làm việc nếu tập tin được đặt tên -e?
Đánh dấu Plotnick

32

Trình tải thực thi UNIX, 10 byte

#!/bin/cat

Nếu bạn không quan tâm đến thư rác về lỗi tiêu chuẩn, bạn có thể làm cho nó ngắn hơn một byte:

#!/bin/dd

7
Tôi thích điều này. Không chắc chắn nếu nó đủ điều kiện là một "ngôn ngữ", mặc dù.
Kevin

Có lẽ gian lận một chút, nhưng bạn không thể đổi tên thư mục bin của mình và chương trình mèo để rút ngắn đường dẫn?
James Webster

3
Tôi không đề nghị bạn làm btw. Tôi đang đề nghị bạn có thể
James Webster

3
@Kevin "Ngôn ngữ" (nghĩa là thông dịch viên) là cat. Và tôi đoán nếu bạn muốn rất cụ thể, một catchương trình chỉ cần tự in và tương thích với mọi định dạng tệp đang tồn tại :)
l0b0

1
@JamesWebster sudo install /bin/cat /c. Vâng, chỉ trong trường hợp /binkhông có trên hệ thống tập tin gốc. Phải có điều đó cattrong một người chơi đơn
Blacklight Shining

25

C, 52

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

Tất nhiên, điều này đọc mã nguồn chứ không phải chương trình được biên dịch - tôi cho rằng đó là trong spec.


Bạn có thể sử dụng printfthay vì putsđể tránh một dòng mới.
frageum

@feersum vâng, bắt tốt
Chấn thương kỹ thuật số

19
@DigitalTrauma Tất nhiên là vì hình đại diện của bạn
Peter Olson

3
Trên thực tế, putscó thể được sử dụng, bạn chỉ cần readít ký tự hơn.
dùng4098326


13

PHP, 21 byte

<?=file(__FILE__)[0];

fileđọc một dòng tệp theo dòng thành một mảng và tệp chỉ có một dòng. Điều này tiết kiệm một byte so với readfile(__FILE__).


Lưu ý rằng điều này chỉ hoạt động từ PHP5.4 trở lên, đây là phiên bản đầu tiên hỗ trợ tham chiếu mảng. Nhưng khác hơn, một câu trả lời khá hay!
Ismael Miguel

1
readfilecũng là 21 : <?readfile(__FILE__);.
primo

1
Phải, không cần<?=
Fabian Schmengler

12

Perl, 15 byte

open 0;print<0>

Đã lưu 3 byte nhờ @ ThisSuitIsBlackNot !


2
Bạn có thể lưu 3 byte vớiopen 0;print<0>
ThisSuitIsBlackNot

@ ThisSuitIsBlackNot Tôi chắc chắn có một cách ngắn hơn để làm điều đó, nhưng tôi không thể làm hết công việc của mình ... Sử dụng 0giả định $0sau đó?
Dom Hastings

3
Vâng. Xem perldoc -f open: "Là một lối tắt, một cuộc gọi một đối số sẽ lấy tên tệp từ biến vô hướng toàn cầu có cùng tên với tệp tay cầm: $ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";"
ThisSuitIsBlackNot

11

Perl 6, 20 byte

print slurp $?FILE

Tôi đã không làm việc với Perl 6 rất lâu nên tôi không chắc có bất kỳ thủ thuật nào để làm cho việc này ngắn hơn không.


2
bạn có thể loại bỏ không gian thứ hai?
Eevee

3
@Eevee không, nó tức giận
Hotkeys

11

osascript (AppleScript từ dòng lệnh), 40 33 32 byte

(đọc đường dẫn đến tôi) đoạn 1

Thực hiện trên một tập tin gọi là với osascript a.

Lấy đoạn đầu tiên (dòng) của tệp và in nó thành STDOUT với một dòng mới, do đó dòng mới trong mã.


1
Xem bản chỉnh sửa của tôi cho OP
TheInitializer

Làm việc để có được nó để làm việc.
Addison Crump

read path to meDường như làm việc cho tôi. El Cap.
Chấn thương kỹ thuật số

Không thấy điều này, nhưng đây là cách tôi đã làm nó. : P Cảm ơn, @DigitalTrauma. EDIT: các dòng mới phải được xem xét, vì vậy bạn thêm dòng mới và sử dụng các đoạn 1.
Addison Crump

11

Python 2, 32 byte

Có một dòng mới ở cuối tập tin.

print open(__file__).readline()

Python 3, 33 byte

Có một dòng mới ở cuối tập tin.

print(open(__file__).readline())

Cảm ơn frageum đã nắm bắt được vấn đề và cung cấp __file__, Loovjo cho cách tiếp cận mới với giải pháp Python 2 đã lưu 17 byte và Skyler cho một giải pháp đã lưu một byte khác và hoạt động trong cả Python 2 và 3 (đang chờ xử lý printlà một hàm trong Python 3)!

Liên kết tài liệu cho readline


Điều này cũng sẽ lưu 2 byte trong python3 vì bạn có thể loại bỏ endtham số.
Skyler

@Skyler Bạn hoàn toàn chính xác.
Celeo

Làm thế nào để nó hoạt động trong Python 3, cần parens cho print?
Doorknob

Python 3 nên được print(open(__file__).readline())theo sau bởi một dòng mới.
Skyler

Ví dụ về Python 3 của bạn cho biết Python 2 chứ không phải Python 3
TheInitializer

10

Mẻ 9 8 byte

@type %0

Đã lưu một byte nhờ @Joshua


3
Bạn có thể lưu một byte bằng cách loại bỏ% trailing.
Joshua

10

Python 2.7, 30 byte

print open(__file__).read(29)

Chỉnh sửa: Để rõ ràng, mã ở trên được cho là có một dòng mới ở cuối là byte thứ 30. Tôi không quen với việc đánh dấu đủ để tìm ra cách hiển thị nó trong khối mã.

Tôi đang sử dụng thủ thuật tương tự ở đây với thủ thuật trong bài nộp C của tôi. Điều này đọc toàn bộ tệp nguồn không bao gồm dòng mới theo dõi để tính đến dòng mới bổ sung printsẽ nối vào đầu ra.


Điều này có gặp phải vấn đề tương tự với dòng mới mà trình khác đã làm không?
cole

Không. Có lẽ là một dòng mới kéo dài tạo ra byte thứ 30 trong mã nguồn nhưng tôi không thể làm cho nó hiển thị trong khối mã. Trình của tôi hoạt động vì nó đọc 29 byte đầu tiên của mã nguồn để dòng mới từ printsẽ không bị ngoại lai.
xsot

4
Đó không phải là những gì dấu phẩy làm. Nó nối thêm một không gian thay vì một dòng mới.
xsot

2
có thể sử dụng để chỉ ra một dòng mới quan trọng về mặt ngữ nghĩa
Eevee

9

Java, 212 196 Byte (171 byte với các quy tắc mã hóa đáng ngờ)

Cảm ơn @Cruncher đã rút ngắn nó xuống ~ 15 byte!

Tôi không có nghi ngờ điều này có thể được chơi golf.

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

Hoặc, một phương thức khác, sử dụng phương thức tĩnh (và tên của lớp), tôi nhận được 171 byte. Tôi không chắc chắn nếu điều này đủ điều kiện là mã hóa cứng, mặc dù.

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

Sử dụng một hàm tạo để lấy tên lớp bằng một phương thức không tĩnh. Sử dụng một phương thức tĩnh ( A.class.getName()) thực sự được mã hóa cứng, vì vậy tôi đã sử dụng cách 'phù hợp'. Sử dụng A.class.getName(), mã này rút ngắn xuống còn 171 byte.

Phiên bản dễ đọc:

Sử dụng hàm tạo và 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) {}
    }
}

Sử dụng phương pháp tĩnh 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"))));
    }
}

Lấy tất cả các byte của tệp cùng một lúc và xuất nó thành STDOUT. Khá đơn giản.


Tại sao không sử dụng A.class.getName()?
Fabio F.

3
Đó là CodeGolf chứ không phải CodeReview! ;)
Fabio F.

1
@FabioF. Vâng, nhưng tôi nghĩ rằng các điệu nhảy trên dòng tên mã hóa cứng, trái với quy tắc. Vấn đề là, nếu bạn thay đổi tên của tệp, bạn phải thay đổi tên của lớp (rõ ràng), nhưng cũng thay đổi dòng này, giống như một tên tệp được mã hóa cứng.
Cruncher

1
Bạn không thể gọi câu lệnh in bên trong hàm tạo và tự cứu mình khỏi việc đặt biến tĩnh?
Cruncher

1
@Cruncher Nah. Bạn nhận được java.io, tôi sẽ gắn bó với java.nio - vấn đề không phải là giành chiến thắng, mà chỉ ra các cách để làm điều đó cực kỳ chính xác với các phương pháp khác nhau.
Addison Crump

8

Tự động, 34 byte

Đầu ra chính nó vào clipboard:

ClipPut(FileRead(@ScriptFullPath))

8

Hồng ngọc, 14

$>.<<IO.read$0

Cách sử dụng tuyệt vời .để tránh dấu ngoặc đơn
Cyoce

7

Đi, 111 105 byte

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

Tôi đoán môn đánh gôn đầu tiên trong môn cờ vây - chỉ một vài mẹo bạn có thể sử dụng ở đây tôi đoán vậy.


Đã có câu trả lời trong Go - điều này có sử dụng cùng một phương pháp không?
Addison Crump

@VoteToClose: Tôi nhận ra điều đó, tôi thực sự được truyền cảm hứng bởi một người khác, nhưng đã sử dụng đổi tên gói ở đây (thủ thuật giá rẻ) cũng như kỹ thuật khác nhau để mở và đặt tệp đường ống vào thiết bị xuất chuẩn. Tiết kiệm cho tôi 22 byte lớn ;-)
tomasz

Phương pháp này thực sự là một chút khác nhau, một trong những tốt!
Fabian Schmengler

7

PowerShell, 39 36 31 25 byte

Về chặt chẽ như tôi có thể nhận được nó:

gc $MyInvocation.MyCommand.Path | oh

Được hỗ trợ bởi nhu cầu phổ biến, điều này đã được thay đổi thành:

gc $PSCommandPath|echo -n

in ra máy chủ lưu trữ tiêu chuẩn hiện tại vỏ .


gc $MyInvocation.MyCommand.PathLà đủ. Nó sẽ tự động in ra.
Andrew

nó không được đảm bảo đặc biệt nếu kịch bản đang chạy âm thầm
Chad Baxter

Haha phải tôi không quan tâm. Tôi sẽ đăng nếu không ai khác có câu trả lời PowerShell. Nhưng tôi quên rằng đó gclà một bí danh và sẽ sử dụng cat, vì vậy dù sao bạn cũng có một byte cho tôi.
Andrew

Uh, tôi sẽ không nghiêm khắc về điều đó. Nếu không, mọi câu trả lời của PS rõ ràng sẽ phải chuyển sang vỏ máy chủ, nhưng điều đó tùy thuộc vào bạn ...
Andrew

Thay vào đó, bạn có thể sử dụng gc $PSCommandPathcho 17 byte. Vấn đề tôi thấy là điều này tạo ra một dòng mới (không tồn tại trong nguồn). Bây giờ nó không rõ ràng nếu theo dõi dòng mới có ổn hay không ... tùy thuộc vào quy tắc đó như thế nào, chúng ta có thể cần phải làm một cái gì đó khó khăn như gc $PSCommandPath|write-host -nđối với 31 byte.
admBorkBork


5

C, 49 byte

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

Chỉnh sửa: Để làm rõ, byte thứ 49 là một dòng mới.

Điều này đọc mã nguồn trừ đi dòng mới ở cuối để tính đến dòng mới putssẽ nối vào cuối đầu ra.


Mã này gọi hành vi không xác định hai lần.
Joshua

5
Vâng, đây là mã golf. Mã của tôi tạo ra đầu ra mong muốn để nó là một đệ trình hợp lệ.
xsot

1
@xsot Trong trường hợp đó, có lẽ bạn nên liệt kê các tùy chọn phiên bản + trình biên dịch; nếu không thì điều này có thể không thể kiểm chứng được.
Justin

1
Nếu có hành vi không xác định được cho phép miễn là bạn có thể có một số trình biên dịch tạo ra đầu ra mong muốn trên một số máy trong một số giai đoạn của mặt trăng, thì tôi đề xuất int main (void) {* 0; } như một giải pháp. Rốt cuộc, tiêu chuẩn sẽ cho phép thực hiện biên dịch nó thành một chương trình giải quyết vấn đề. Tôi sẽ ổn khi sử dụng hành vi phụ thuộc vào triển khai miễn là bạn chỉ định trình biên dịch, nhưng với hành vi không xác định, bạn thậm chí không thể đảm bảo rằng bạn sẽ không nhận được mười câu trả lời khác nhau nếu bạn chạy liên tục mười lần trên cùng một máy.
Ray

1
@MDXF Tôi không nghiêm túc đề nghị chúng tôi viết giải pháp đó. Tôi đã tranh luận chống lại việc cho phép hành vi không xác định. int main() {*0;} có thể hoạt động ngay cả trên các trình biên dịch hiện có, vì nó chứa hành vi không xác định. Tương tự, giải pháp của xsot có thể hoạt động trên các trình biên dịch hiện có, vì nó chứa hành vi không xác định. Không ai được đảm bảo để giải quyết vấn đề. (Mặc dù xsot được thừa nhận nhiều khả năng làm như vậy, nhưng nó có thể dễ dàng bị sập). Lập luận thực tế của tôi là chúng ta nên cho phép các giải pháp phụ thuộc vào hành vi phụ thuộc vào thực hiện hoặc không xác định, nhưng không xác định hành vi.
Ray


4

Bình thường, 25 byte

$import sys$h'e$sys.argv

Điều này đọc tên tập tin của nó. Về cơ bản, nó tìm kiếm argv, mở tệp tương ứng với đối số cuối cùng của nó và in dòng đầu tiên của nó.


Bạn không thể làm gì h'$__file__$?
kirbyfan64sos

@ kirbyfan64sos Điều đó cho tôi lỗi NameError: name '__file__' is not defined. Pyth được biên dịch thành Python và sau đó chuỗi kết quả được thực thi. Vì vậy, tôi sẽ không mong đợi rằng sẽ làm việc.
isaacg

4

Đi, 133 byte

Mọi người rõ chưa? Đi!

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

2
Điều này truyền cảm hứng cho tôi để viết giải pháp chơi gôn mã (và đầu tiên) của riêng tôi trong Go. Tìm kiếm một số thủ thuật chung, bạn có thể dễ dàng đi xuống 123 ký tự ở đây bằng cách áp dụng tên một chữ cái cho các gói chẳng hạn r"runtime".
tomasz

4

> <> , 13 byte

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

Đã thử nghiệm cả trên phiên dịch trực tuyến và ngoại tuyến. Cácg lệnh là gần nhất để có thể đọc từ tập tin nguồn và nếu nó không đếm với mục đích thử thách này, tôi sẽ đánh dấu nhập cảnh của tôi không cạnh tranh; Tôi tin rằng nó thường được coi là "gian lận" cho quines.

Hãy thử trực tuyến.


4

Haskell, 63 byte

Đối với khoa học!

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

Chỉ hoạt động với runhaskelllệnh. Mặc dù rất tuyệt
HEGX64

4

> <> , 31 byte

Tuyên bố miễn trừ trách nhiệm: không có tệp I / O trong> <>, tuy nhiên tôi nghĩ sẽ rất thú vị khi giới thiệu không gian mã I / O được thừa hưởng từ Befunge, một trong những ngôn ngữ được truyền cảm hứng> <>.

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

Một Quine tự đọc tôi đã thực hiện một thời gian trước đây, bạn có thể thử nó ở đây .

Tôi chỉ thấy có một đoạn ngắn> <> tự đọc . Mặc dù rõ ràng là tốt hơn trong các tiêu chuẩn golf-code tôi muốn chỉ ra rằng nó có độ dài mã được mã hóa cứng, trong khi tôi sẽ sao chép các dòng hoặc cột mã bổ sung (miễn là chúng không phá vỡ mã gốc).


Tôi đã nghĩ đến việc đăng bài trong> <>, nhưng tôi nghĩ> <> sẽ không thể thực hiện được do quy tắc: "Bạn phải sử dụng tệp I / O để đọc mã nguồn"
Sp3000

@ Sp3000 woops thực sự, có vẻ như tôi đã không đọc thử thách đủ tốt. Tôi sẽ thêm từ chối trách nhiệm
Aaron

3

F #, 54 byte

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

Sử dụng:

fsi --exec a.fsx

3

Perl 5, 15 13 byte

Tín dụng cho giải pháp Bash để truyền cảm hứng này:

print`cat $0`

EDIT: Không cần dấu chấm phẩy hoặc dấu cách đầu tiên.


Không thuần túy perl, nó cần một số thực thi khác, cụ thể là cat, hiện tại và có thể tìm thấy trong $PATH. Nhưng nếu nó có mặt, nó có thể được coi là một lệnh có sẵn perl, vậy tại sao không.
Gole Ramblar

3

Node.js, 66 63 byte

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

Không sử dụng console.log, mà nối thêm một dòng mới.


1
Bạn có thể lưu một vài byte bằng cách sử dụng api đồng bộ:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike

1
Tại sao không console.log(require('fs').readFileSync(process.argv[1]))\ncho 57 byte?
Conor O'Brien

Điều này không phải lúc nào cũng hoạt động. Nói các tập tin được đặt tên test.js. Nó là hợp lệ để gọi nó bằng cách chạy node test, điều này sẽ gây ra lỗi này.
Patrick Roberts


3

Haskell , 49 byte

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

Hãy thử trực tuyến!

(GHC) Haskell có một phần mở rộng để sử dụng bộ tiền xử lý C (thường được sử dụng cho tính di động giữa các phiên bản và kiến ​​trúc.) Hy vọng sẽ tự giải thích.


3

HTML với JavaScript, 115 byte (không thực sự được tính)

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

Điều này có tính không? Tôi không phiền, nó rất vui :)

Về mặt kỹ thuật, nó không mở một tập tin. Đây cũng là một tài liệu HTML5 được hình thành tốt. XMLSerializer là công cụ duy nhất cũng trả về phần DOCTYPE, nhưng không chuẩn. Tuy nhiên, nó hoạt động trên chrome và firefox và tôi đặt cược các trình duyệt khác.

Và như một phần thưởng:

JavaScript, 41 byte

alert(document.currentScript.textContent)

Tẩy ";" ở cuối, tiết kiệm 1 byte :)
Евгений Новиков

1
@ ВгенийiTовиков Bạn nói đúng, không biết tại sao sau đó tôi lại để nó. Có vẻ như tôi đã không đếm được.
Domino
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.