자해 프로그램


16

간단히 말해서, 소스의 모든 문자가 시작된 문자와 다를 때까지 자체 소스 코드수정 하는 완전한 프로그램을 작성하는 것이 목표입니다 .

게시물에 시작 소스와 끝 소스 및 설명을 포함 시키십시오. 예 : 프로그램의 기능 (사용 된 언어, 전략 등)을 설명하십시오.

규칙

  • 수정이 완료된 후 언젠가 프로그램이 중단되어야합니다.
  • 실제로 현재 실행중인 자체 소스 코드 (인터프리터에 전달한 파일 일 필요는 없으며 명령을 수정 함)를 수정하거나 새 프로그램을 인쇄하거나 새 파일을 작성하지 않아야합니다.
  • 표준 허점은 허용되지 않습니다.
  • 최단 프로그램이 이깁니다.

  • 언어가 자체 파일을 수정하고 새 컴파일러 프로세스를 실행할 수 있지만 자체 (현재 실행중인) 소스 코드를 수정할 수없는 경우 + 20 % 바이트 페널티 대신 반올림하여 이러한 프로그램을 작성할 수 있습니다. 실제 자체 수정 언어는 이점이 있어야합니다.

편집 : 프로그램이 오류와 함께 중지되면 해당 프로그램을 지정하십시오 (오류가 무엇인지 말하십시오).


7
프로그램이 실행 중에 잠재적으로 동작에 영향을 줄 수있는 방식으로 자체 소스를 수정해야한다는 것을 올바르게 알고 있습니까? 이것은 비 비전 어를 배제 할 것입니다. 아니면 소스를 수정하고 새로운 인터프리터 / 컴파일러 프로세스를 시작할 수 있습니까?
Zgarb

@Zgarb 실제로 현재 실행중인 소스 코드를 수정해야합니다. 예, 대부분의 언어를 배제합니다.
mbomb007

8
@ mbomb007 나쁘다.
mınxomaτ

1
@ mbomb007 수정 된 소스 코드를 실행해야한다는 도전은 없습니다.
mınxomaτ

1
또한,이 도전을 사소한 것으로 만들지는 않지만 여전히 범위가 넓습니다. 이것으로 너무 많은 언어를 배제했습니다.
mınxomaτ

답변:


19

/// , 1 바이트

/

프로그램은 /(패턴 교체 그룹의 시작)을 찾아서 교체 준비를 위해 제거합니다. 그런 다음 EOF에 도달하여 포기하고 정지합니다.


는 1 바이트의 가장 빠른 답변이므로 승자입니다.
mbomb007

22

미로 , 2 바이트

>@

>소스가되도록 회전된다

@>

명령 포인터가 이제 막 다른 곳에 @있으며 프로그램을 종료시키는 명령을 실행합니다.

물론 <@작동합니다.


12

파이썬 2, 225 바이트

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)

종료 소스 코드는 "0" 길이가 원래 컴파일 된 코드 오브젝트의 바이트 수와 동일한의 .

코드는 실행중인 코드 객체를 찾아 sys._getframe().f_code.co_code파이썬 문자열 객체를 나타내는 구조를 만듭니다. 그런 다음 코드가 실제로 사용하는 메모리를 가져 와서"0"*len(c) .

실행되면 프로그램은 다음 역 추적과 함께 종료됩니다.

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

이것은 덮어 쓰기에 성공했으며 0유효한 opcode가 아니기 때문에 프로그램이 종료되었음을 나타냅니다 .

이것은 파이썬에서도 가능하며 프레임 객체는 읽기 전용이며 새 객체를 만들 수 없다는 것에 놀랐습니다. 이것이하는 유일한 복잡한 일은 불변의 객체 (문자열)를 변경하는 것입니다.


모든 문자가 달라야한다는 요구 사항을 충족하는지 확실하지 않습니다. 은 "1"원래의 소스 코드에서 여전히 "1"엉망이 코드에서 ... 것
대럴 호프만

실제로 "1"코드 의 문자열은 실제로 '코드'의 일부가 아니며 바이트 코드에서 참조되는 상수입니다. 실제로 변경하는 것은 상수 또는 변수가 아닌 컴파일 된 파이썬 가상 머신 opcode입니다. 그래서 내가 바꾸고있는 것은 말하는 소스 코드가 아니라 컴파일 된 코드입니다. 소스 코드를 저장된 것으로 변경할 수는 있지만 이미 컴파일되어 있기 때문에 런타임에 실제로 영향을 미치지 않습니다. 원한다면 이것을 상수가있는 컴파일 된 Python 2.7 opcodes에 게시 할 수는 있지만 어리석은 IMO입니다.
Blue

또한 내부에서 볼 수 있도록 코드를 변경하면 실제로 코드가 변경되므로 실제로 코드를 볼 수 없기 때문에 컴파일 된 코드를 볼 수 없습니다. 코드가 실제로 모든 문자를 대체 할 것인지 전혀 모릅니다. 대부분의 문자 (?)가 바뀌는 것입니다.
Blue

컴파일 된 코드에서 1이 변경되지 않는 문제를 해결 "1"하기 <backtick>1+1<backtick>위해 2 바이트 만
더할

내가 아는 것은 아닙니다 (2.7.10으로 컴파일 됨). 불행히도 1+1내 제안 2에서 컴파일 된 버전으로 바뀝니다 ... 컴파일러는 자신의 이익을 위해 너무 똑똑합니다!
Mego

11

이블 , 1 바이트

q

악 여러 메모리 저장을 갖는 - 하나는 소스 코드 자체가 하나의 인 단일 제로로 초기화하는 순환 큐이다. q소스 코드와 휠을 교체하여 소스를 널 바이트로 바꿉니다. 그러나 소문자 만 악의적 인 실제 연산자이므로 문자가 단순히 작동하지 않으며 프로그램이 종료됩니다.


6

MSM , 8 바이트

'.qp.;.;

소스 코드를 pqpqpqpq

MSM은 문자열 목록에서 작동합니다. 명령은 왼쪽에서 가져 오며 오른쪽을 스택으로 취급합니다. MSM은 항상 자체 소스에서 작동합니다.

실행 추적 :

'.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 또는 2 바이트

D

Malbolge 언어는 명령을 실행 한 후 각 명령을 "암호화"하므로이 문자 (Malbolge NOP)는 !(nop이기도 함 )이되어 종료됩니다. 어떤 이유로 든, 내가 사용하는 Malbolge 인터프리터는 두 바이트를 실행하여 DC(둘 다 nops)되고 !U(둘 다 nops입니다)

편집 : Malbolge 메모리의 초기 상태는 코드의 마지막 두 문자에 따라 다르므로 하나의 문자 프로그램에 대해서는 잘 정의되어 있지 않습니다. (이 코드는 초기 메모리 상태에 신경 쓰지 않지만)


5

x86 asm -6 바이트

"소스의 모든 문자가 시작된 문자와 다를 때까지"가 각 바이트, 각 네모 닉 또는 일반 수정을 참조하는지 확실하지 않습니다. 내가 유효하지 않으면 xor를 rep xor로 변경할 수 있으므로 각 비트는 값을 변경하지만 6 개 이상의 바이트를 절약 하여이 특수 골프 언어와 비교할 수있는 약간의 비트를 유지하지 않기를 바랐습니다.

이 모든 것은 eip의 라이브 주소를 가져 와서 5 바이트 앞에 xoring하여 c2를 c3 retn으로 변경하는 것입니다.

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 바이트

골프를 타면 나중에 더 많은 작업을 할 것입니다.

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

설명

프로그램은 테이프 끝에서 다음 명령을 생성하여 자체를 지우므로 테이프에서 다음 값을 생성해야합니다.

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

임시 값으로 사용하기 위해 사이에 91null (으로 표시 _) 을 묶어 s를 만드십시오 .

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

code__91_91_91_91_91_91_
   ^

차이로 값을 조정

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

실행 후 테이프는 생성 된 코드를 제외하고 모두 0 [_[_-_]_<_]입니다.

노트 :

이 프로그램을 통해 SMBF 용 Python 인터프리터에 버그가 있음을 알았 으며 아직 해결 방법을 찾지 못했습니다. 이제 수정되었습니다.


4

이맥스 Lisp 22 바이트

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

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)

함수는 이제로 평가됩니다 nil.

교대로 (바인드 해제) 30 바이트

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

평가와 같은 오류 void-function. 기능이 실행되기 전에 존재했습니다.


4

Redcode , 7 bytes, 1 instruction (단지 예. 경쟁하지 않음)

이것은 간단한 예입니다.

다음 메모리 위치를 자체로 이동 한 다음 중지됩니다 (전체 메모리가로 초기화되어 DAT 0 0실행시 프로그램이 중지되므로).

MOV 1 0

2
왜 이것을 바이트 대신 명령어로 계산합니까?
Martin Ender

바이트 수를 모르기 때문에. 나는 그것이 메모리 크기 또는 구현에 달려 있다고 생각합니까? ...
mbomb007

4
구현 방법을 모른다면 ASCII 문자로 계산합니다.
lirtosiast

1
Wikipedia 페이지에서 : 각 Redcode 명령어는 정확히 하나의 메모리 슬롯을 차지하고 실행하는 데 정확히 한주기가 걸립니다. ... 메모리는 하나의 명령 단위로 주소가 지정됩니다.
mbomb007

3
모든 코드 골프 게시물은 바이트 단위로 점수가 매겨집니다. Redcode 기계어 코드가 없으므로 "어셈블리 소스"의 문자를 어셈블하지 말고 사용해야합니다.
lirtosiast

3

Powershell 65 바이트

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

자신을 null로 다시 쓰는 함수를 정의하십시오.

한 번 평가하면 제거됩니다.

또는 36 바이트 ( 메모리에서 자체 삭제)

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

먼저 호출하면 제거되고 재귀 적으로 평가됩니다. 알 수없는 명령으로 오류가 발생했습니다.


3

MIXAL, 6 바이트 (2 탭 계산)

    STZ    0

프로그램은 메모리 위치 0에서 시작한 다음 0을 메모리 위치 0에 기록하여 자체적으로 지워집니다. 기계가 자동으로 정지합니다.

이것은 GNU MIX 개발 키트 ( https://www.gnu.org/software/mdk/ )를 사용하여 조립 및 실행할 수있는 Donald Knuth의 가상 MIX 컴퓨터의 조립 언어입니다 .


3

> <> , 40 34 30 바이트

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

여기 사용해보십시오!

설명:

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 " "

기본적으로 이것은 스택에 3 개의 문자 블록을 다음과 같이 스택에 넣습니다 : (ypos, xpos, ASCII 문자) 마지막에 반전되어 최종 'p'명령은 (character, xpos, ypos)를 읽고 그 위치를 설정합니다 그 캐릭터에 코드. 첫 번째 문자는 수동으로 '<'로 설정되므로 코드가 명령을 반복하기 위해 끝에 '> p <'가됩니다. 그런 다음 다른 모든 문자는 p 문자를 포함하여 ''로 겹쳐 씁니다. ''는 실제로 "ASCII CHAR 0"이며 NOP가 아니며 읽을 때 오류가 발생합니다.

또한 'p'명령 앞에 홀수 (?) 문자가 있어야합니다. 그렇지 않으면 마지막으로 다시 루프되어 덮어 쓰지 않습니다.


2

배치, 11 바이트

@echo>%0&&*

소스 코드를 수정 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.

@이 때문에 명령이 에코되지이다,하지만 대부분 이렇게 두 echo들 정렬되지 않습니다.


@때문에, 제거 할 수 있습니다 ECHO! (대문자) = echo(소문자)
pppery

@ppperry 두 개의 echo줄을 가질 수 없습니다.
ericw31415

그러나 그들은 다른 경우입니다.
pppery


0

(파일 시스템) Befunge 98, 46 바이트

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

이 프로그램은이라는 파일을 작성하고 조작합니다 a. 작동 방식 :

  1. 이 코드 a는 전체 코드를 포함 하는 파일 (각 차원에서 256 자까지)을 한 칸 위로, 두 칸은 왼쪽으로 이동 한 파일을 만듭니다 .
  2. 그런 다음이 프로그램 a은 한 줄로 명명 된 파일을 읽고 첫 번째 줄 전체를 a파일 내용으로 바꿉니다 .
  3. IP 앞에 복사 된 두 번째 줄이 실행됩니다.
  4. a두 번째 줄로 파일을 읽는 것은 오른쪽으로 두 자리 이동했습니다.

부작용으로, 종료 소스 코드는 유효하지 않습니다. (한 줄에 데이터로 개행 문자가 포함되어 있기 때문에)


0

파이썬 2, 238 바이트 + 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"):])

기본적으로,이 사이 파이썬 소스의 현재 파일 인코딩을 전환 ascii하고 utf-8, 따라서 본질적으로 소스의 모든 문자를 변경!


제거 할 수있는 추가 공간이 있습니다. ) as-> )as, ) else-> )else, "utf-8"if, 'w',encoding.
mbomb007
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.