Chương trình tự cắt xén


16

Nói một cách đơn giản, mục tiêu của bạn là tạo ra một chương trình hoàn chỉnh sửa đổi mã nguồn của chính nó cho đến khi mọi ký tự của nguồn khác với những gì nó bắt đầu.

Vui lòng bao gồm nguồn bắt đầu cũng như nguồn kết thúc trong bài viết của bạn, cũng như một mô tả. Ví dụ: Mô tả những gì (khác) chương trình của bạn làm, ngôn ngữ bạn đã sử dụng, chiến lược của bạn, v.v.

Quy tắc

  • Chương trình của bạn phải tạm dừng sau khi sửa đổi hoàn tất.
  • Nó thực sự phải sửa đổi mã nguồn của chính nó, hiện đang chạy (không nhất thiết là tệp bạn đã chuyển cho trình thông dịch, nó sửa đổi hướng dẫn của nó), không in một chương trình mới hoặc viết một tệp mới.
  • Sơ hở tiêu chuẩn là không được phép.
  • Chương trình ngắn nhất sẽ thắng.

  • Nếu ngôn ngữ của bạn có thể sửa đổi tệp của chính nó và thực hiện quy trình biên dịch mới, nhưng không thể sửa đổi mã nguồn của chính nó (hiện đang chạy), bạn có thể viết một chương trình như vậy thay vào đó với mức phạt + 20% byte, được làm tròn. Ngôn ngữ tự sửa đổi thực sự nên có một lợi thế.

Chỉnh sửa : Nếu chương trình của bạn tạm dừng có lỗi, vui lòng chỉ định nó như vậy (và có thể nói lỗi đó là gì.)


7
Tôi có hiểu chính xác rằng chương trình nên sửa đổi nguồn của chính nó trong khi nó đang chạy, theo cách có khả năng ảnh hưởng đến hành vi của nó không? Điều này sẽ loại trừ hầu hết các ngôn ngữ phi bí truyền. Hoặc nó được phép sửa đổi nguồn và khởi chạy một quá trình biên dịch / biên dịch mới trên nó?
Zgarb

@Zgarb Nó thực sự phải sửa đổi mã nguồn của chính nó, hiện đang chạy. Vâng, đó là quy tắc ra hầu hết các ngôn ngữ.
mbomb007

8
@ mbomb007 Điều đó thật tệ.
mınxomaτ

1
@ mbomb007 Điều đó nói rằng không nơi nào trong bạn thách thức rằng nó phải chạy mã nguồn được sửa đổi.
mınxomaτ

1
Ngoài ra, không, nó không làm cho thử thách này trở nên tầm thường, nó vẫn sẽ có phạm vi tốt. Bạn loại trừ quá nhiều ngôn ngữ với điều này.
mınxomaτ

Câu trả lời:


19

/// , 1 byte

/

Chương trình tìm thấy một /(sự khởi đầu của một nhóm thay thế mẫu) và loại bỏ nó để chuẩn bị thay thế. Sau đó, nó đạt đến EOF, vì vậy nó bỏ cuộc và dừng lại.


Đây là câu trả lời sớm nhất với 1 byte, vì vậy đây là người chiến thắng.
mbomb007

22

Mê cung , 2 byte

>@

Các >xoay nguồn để nó trở thành

@>

Con trỏ lệnh bây giờ đang ở trong ngõ cụt và quay lại để nhấn vào @đó kết thúc chương trình.

Tất nhiên, <@cũng sẽ làm việc.


12

Python 2, 225 byte

import sys
from ctypes import*
c=sys._getframe().f_code.co_code
i=c_int
p=POINTER
class S(Structure):_fields_=zip("r"*9+"v",(i,c_void_p,i,c_char_p,i,p(i),i,c_long,i,c_char*len(c)))
cast(id(c),p(S)).contents.v=`len([])`*len(c)

Mã nguồn kết thúc là một chuỗi "0"s có độ dài bằng số byte trong đối tượng mã được biên dịch ban đầu.

Mã tìm thấy đối tượng mã đang chạy sys._getframe().f_code.co_codevà tạo một cấu trúc đại diện cho các đối tượng chuỗi python. Sau đó, nó nhận được bộ nhớ mà mã thực sự lấy và thay thế nó bằng "0"*len(c).

Khi chạy, chương trình thoát với truy nguyên sau:

XXX lineno: 7, opcode: 49
Traceback (most recent call last):
  File "main.py", line 7, in <module>
    cast(id(c),p(S)).contents.v=`1+1`*len(c)
SystemError: unknown opcode

Điều này cho thấy việc ghi đè đã thành công và chương trình chết vì 0không phải là mã opcode hợp lệ.

Tôi ngạc nhiên rằng điều này thậm chí có thể xảy ra với python, các đối tượng khung chỉ ở chế độ đọc, tôi không thể tạo mới. Điều phức tạp duy nhất này là thay đổi một đối tượng bất biến (một chuỗi).


Không chắc chắn nếu điều này khá đáp ứng các yêu cầu mà MỌI nhân vật phải khác nhau. Số "1" trong mã nguồn ban đầu vẫn là "1" trong mã được đọc sai ...
Darrel Hoffman

Thực ra, "1"chuỗi trong mã không thực sự là một phần của 'mã', nó chỉ là một hằng số được đề cập trong mã byte. Những gì tôi thực sự thay đổi là opcodes máy ảo python được biên dịch, không phải là hằng hoặc biến. Vì vậy, những gì tôi đang thay đổi không phải là mã nguồn mỗi lần nói, chỉ là mã được biên dịch. Tôi có thể thay đổi mã nguồn như được lưu trữ nhưng điều đó thực sự sẽ không ảnh hưởng đến mã khi chạy vì nó đã được biên dịch. Nếu bạn muốn, tôi có thể đăng bài này trong 'opcodes 2.7 được biên dịch với các hằng số', nhưng đó sẽ là IMO ngớ ngẩn.
Màu xanh

Ngoài ra, tôi không thể nhìn vào mã được biên dịch bởi vì bằng cách thay đổi mã để xem bên trong, tôi thực sự đang thay đổi mã, nghĩa là tôi không thực sự nhìn thấy mã. Vì vậy, thực sự, tôi không biết mã có thực sự thay thế mọi nhân vật hay không, chỉ là nó thay đổi hầu hết (?) Trong số họ
Blue

Để khắc phục vấn đề của 1 không được thay đổi trong các mã được biên dịch, bạn có thể thay đổi "1"để <backtick>1+1<backtick>cho chỉ có 2 byte nữa
MEGO

Không phải là tôi thấy (biên dịch với 2.7.10). Thật không may, 1+1từ đề xuất của tôi bị biến thành một 2phiên bản được biên dịch ... Trình biên dịch quá thông minh vì lợi ích của chính nó!
Mego

11

ác , 1 byte

q

cái ác có một số cửa hàng bộ nhớ - một là mã nguồn chính và một là bánh xe là một hàng đợi tròn được khởi tạo thành một số không. qhoán đổi mã nguồn và bánh xe, vì vậy nó thay thế nguồn bằng byte rỗng. Tuy nhiên, chỉ có các chữ cái viết thường là toán tử thực sự trong ác, do đó ký tự đó chỉ đơn giản là không có và chương trình chấm dứt.


6

MSM , 8 byte

'.qp.;.;

Chuyển đổi mã nguồn thành pqpqpqpq

MSM hoạt động trên một danh sách các chuỗi. Các lệnh được lấy từ bên trái và chúng coi phía bên phải là một ngăn xếp. MSM luôn hoạt động trên nguồn riêng của nó.

Dấu vết thực thi:

'.qp.;.;                       upon start the source is implicitly split into a
                               list of single char strings

' . q p . ; . ;                ' takes the next element and pushes it on the stack
    q p . ; . ; .              q is not a command so it's pushed
      p . ; . ; . q            same for p
        . ; . ; . q p          . concats the top and next to top element
          ; . ; . pq           ; duplicates the top element
            . ; . pq pq        concat
              ; . pqpq         dup
                . pqpq pqpq    concat
                  pqpqpqpq     MSM stops when there's only one element left      

6

Malbolge, 1 hoặc 2 byte.

D

Ngôn ngữ Malbolge "mã hóa" mỗi lệnh sau khi thực hiện nó, vì vậy chữ cái này (Malbolge NOP) sẽ trở thành một !(cũng là một nop), và sau đó chấm dứt. Vì một số lý do, trình thông dịch Malbolge mà tôi sử dụng yêu cầu hai byte để chạy, cho DC(cả hai đều là nops) trở thành !U(cả hai đều là nops)

Chỉnh sửa: Trạng thái ban đầu của bộ nhớ Malbolge phụ thuộc vào hai ký tự cuối cùng trong mã, do đó nó không được xác định rõ cho các chương trình một ký tự. (Mặc dù mã này không quan tâm đến trạng thái ban đầu của bộ nhớ)


5

x86 asm - 6 byte

không chắc chắn nếu "cho đến khi mọi ký tự của nguồn khác với giá trị bắt đầu" đề cập đến từng byte, từng phép thuật hoặc sửa đổi chung. Nếu tôi không hợp lệ, tôi có thể thay đổi xor thành rep xor để mỗi bit thay đổi giá trị nhưng hy vọng không làm điều đó để tiết kiệm thêm 6 byte để duy trì ít nhất một chút so với các ngôn ngữ golf đặc biệt này.

Tất cả điều này là thay đổi một c2 thành một c3 retn bằng cách lấy địa chỉ trực tiếp của eip và xored 5 byte ở phía trước.

58          | pop eax                        ; store addr of eip in eax
83 70 05 01 | xor dword ptr ds:[eax + 5], 1  ; c2 ^ 1 = c3 = RETN
c2          | retn                           ; leave

5

SMBF , 92 byte

Có thể chơi gôn và có lẽ tôi sẽ làm việc nhiều hơn sau này.

>>+>>+>>+>>+>>+>>+[<-[>+<---]>+++++<<]>>>>>--[>-<++++++]>--->>++>+++++[>------<-]>->>++[<<]<

Giải trình

Chương trình tạo các lệnh sau ở cuối băng để tự xóa, do đó, nó phải tạo các giá trị sau trên băng:

[[-]<]          ASCII: 91 91 45 93 60 93

Tạo một bó 91s, với null (hiển thị dưới dạng _) giữa để sử dụng cho các giá trị tạm thời.

>>+>>+>>+>>+>>+>>+[<-[>+<---]>+++++<<]

code__91_91_91_91_91_91_
   ^

Điều chỉnh các giá trị bằng sự khác biệt

>>>>>--[>-<++++++]>---  Sub 46
>>++                    Add 2
>+++++[>------<-]>-     Sub 31
>>++                    Add 2
[<<]<                   Shift left to the code
code__[_[_-_]_<_]_      Zero out the code
   ^

Băng sau khi thực hiện sẽ là tất cả các số không, ngoại trừ mã được tạo [_[_-_]_<_].

Ghi chú:

Chương trình này khiến tôi nhận ra rằng trình thông dịch Python của tôi cho SMBF có một hoặc hai lỗi và tôi chưa tìm ra cách khắc phục. Bây giờ nó đã được sửa.


4

Emacs Lisp 22 byte

(defun a()(defun a()))

Chạy từ REPL:

ELISP> (defun a()(defun a()))
a
ELISP> (symbol-function 'a)
(lambda nil
  (defun a nil))

ELISP> (a)
a
ELISP> (symbol-function 'a)
(lambda nil nil)

Chức năng bây giờ đánh giá nil.

Luân phiên (tự hủy) 30 byte

(defun a()(fmakunbound 'a)(a))

Đánh giá và lỗi như void-function. Chức năng tồn tại trước khi được chạy.


4

Redcode , 7 byte, 1 hướng dẫn (Chỉ là một ví dụ. Không cạnh tranh)

Đây là một ví dụ tầm thường.

Di chuyển vị trí bộ nhớ tiếp theo vào chính nó, sau đó tạm dừng (vì toàn bộ bộ nhớ được khởi tạo DAT 0 0, sẽ tạm dừng chương trình khi được thực thi.)

MOV 1 0

2
Tại sao bạn lại coi đây là hướng dẫn thay vì byte?
Martin Ender

Bởi vì tôi không biết nó có bao nhiêu byte. Tôi nghĩ rằng điều đó phụ thuộc vào kích thước bộ nhớ hoặc việc triển khai? ...
mbomb007

4
Tôi sẽ đếm theo các ký tự ASCII nếu bạn không biết cách triển khai.
lirtosiast

1
Từ trang Wikipedia: Mỗi lệnh Redcode chiếm chính xác một khe nhớ và mất chính xác một chu kỳ để thực thi. ... Bộ nhớ được xử lý theo đơn vị của một hướng dẫn.
mbomb007 7/10/2015

3
Tất cả các bài viết mã golf được ghi bằng byte. Vì không có mã máy Redcode, chúng tôi phải sử dụng các ký tự trong "nguồn lắp ráp", chứ không phải những gì nó lắp ráp.
lirtosiast

3

Powershell 65 byte

function a{si -pat:function:a -va:([scriptblock]::create($null))}

Xác định một hàm tự viết lại thành null.

Đánh giá nó một lần và nó tự loại bỏ.

Luân phiên (xóa chính nó khỏi bộ nhớ) 36 byte

function a{remove-item function:a;a}

Gọi nó trước tiên loại bỏ nó sau đó cố gắng đánh giá đệ quy. Lỗi là một lệnh không xác định.


3

MIXAL, 6 byte (đếm 2 tab)

    STZ    0

Chương trình bắt đầu tại vị trí bộ nhớ 0 và sau đó ghi 0 vào vị trí bộ nhớ 0, do đó tự xóa. Máy tự động dừng lại.

Đây là ngôn ngữ lắp ráp cho máy tính MIX giả định của Donald Knuth, có thể được lắp ráp và chạy bằng bộ phát triển GNU MIX ( https://www.gnu.org/software/mdk/ ).


3

> <> , 40 34 30 byte

0&00a6*0&1+:&060"c"l=?!.~~r >p

Hãy thử nó ở đây!

Giải trình:

0&          Adds 0 to the registry
00a6*       Adds "0,0,<" to the stack; coords followed by a character
------------loop start (for clarity)
0           0 added to stack
&1+:&       Registry retrieved, increased by 1, duplicated, one put back in registry
0           ASCII character 0 added to stack (just a 0 but will be converted to that character when inserted in the code)
60          6 and 0 added to stack
"c"         The number 99 added to stack (length of code + 1 * 3)
l=?         Code length added to stack, checks if it is equal to 111

!.          If false, pointer jumps back to character (9,0) (loop start position)
~~r >p      If true, removes the 0 and 9, reverses stack, then loops the p command setting
all the characters to a "<" character and the 2nd character to a " "

Về cơ bản, điều này đặt một nhóm gồm 3 khối ký tự trong ngăn xếp như sau: (ypose, xpose, ký tự ASCII) được đảo ngược ở cuối để lệnh 'p' cuối cùng đọc (ký tự, xpose, ypose) và đặt vị trí đó trong mã cho nhân vật đó. Ký tự đầu tiên được đặt thủ công là '<', để mã kết thúc là '> p <' ở cuối để lặp lệnh. Sau đó, mọi ký tự khác được ghi đè là '' bao gồm cả ký tự p. '' Thực sự là "ASCII CHAR 0" KHÔNG phải là NOP và sẽ báo lỗi khi đọc.

Ngoài ra, phải có một số lượng ký tự lẻ (?) Trước lệnh 'p' nếu không nó sẽ không được lặp lại vào lần cuối và ghi đè.


2

Mẻ, 11 byte

@echo>%0&&*

Sửa đổi mã nguồn thành ECHO is on.

@           - don't echo the command.
 echo       - print ECHO is on.
     >%0    - write to own file.
        &&* - execute * command after the above is done, * doesn't exist so program halts.

Các @là có nên lệnh không được lặp lại, nhưng chủ yếu là để hai echos không xếp hàng.


các @thể được gỡ bỏ, bởi vì ECHO(chữ hoa) =! echo(chữ thường)
pppery

@ppperry Hai echos không thể xếp hàng.
ericw31415

Nhưng chúng là những trường hợp khác nhau.
pppery


0

(Hệ thống tập tin) Befunge 98, 46 byte

ff*:1100'aof0'ai
               21f0'ai@

Lưu ý rằng chương trình này tạo và thao tác một tệp có tên a. Làm thế nào nó hoạt động:

  1. Mã này tạo một tệp có tên achứa toàn bộ mã (tối đa 256 ký tự ở mỗi chiều) đã dịch chuyển một khoảng trắng lên trên và hai bên trái.
  2. Chương trình này sau đó đọc tệp có tên alà một dòng, thay thế toàn bộ dòng đầu tiên bằng nội dung của atệp.
  3. Dòng thứ hai, đã được sao chép ở phía trước IP, được thực thi
  4. Mà đọc atập tin vào dòng thứ hai đã dịch chuyển hai nơi sang phải.

Là một tác dụng phụ, mã nguồn kết thúc thậm chí không hợp lệ Befunge! (bởi vì nó chứa các dòng mới dưới dạng dữ liệu trong một dòng)


0

Python 2, 238 byte + 20% = 285,6

# coding: utf-8
import codecs
with codecs.open(__file__,'r') as f:
    t = f.read()
n="utf-8" if t.startswith("# coding: ascii") else "ascii"
with codecs.open(__file__,'w', encoding=n) as f:
    f.write(t[0]+" coding: "+n+t[t.find("\n"):])

Về cơ bản, điều này làm bật mã hóa tệp hiện tại của nguồn python giữa asciiutf-8, do đó về cơ bản thay đổi mọi ký tự của nguồn!


Có một số không gian thêm có thể được gỡ bỏ. ) as-> )as, ) else-> )else, "utf-8"if, 'w',encoding.
mbomb007
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.