自己切断プログラム


16

簡単に言えば、あなたの目標は、ソースのすべての文字が元の文字と異なるまで、独自のソースコード変更する完全なプログラムを作成することです。

投稿に開始ソースと終了ソース、および説明を含めてください。例えば、あなたのプログラムが何を(他に)、あなたが使用した言語、あなたの戦略などを記述してください。

ルール

  • 変更が完了した後、プログラムを停止する必要があります。
  • 新しいプログラムを印刷したり、新しいファイルを書き込んだりするのではなく、現在実行中のソースコード(インタープリターに渡したファイルである必要はなく、命令を変更する必要はありません)を実際に変更する必要があります。
  • 標準の抜け穴は許可されていません。
  • 最短のプログラムが勝ちます。

  • 言語が独自のファイルを変更して新しいコンパイラプロセスを実行できるが、独自の(現在実行中の)ソースコードを変更できない場合は、代わりに+ 20%バイトのペナルティで切り上げてそのようなプログラムを記述できます。実際の自己修正言語には利点があります。

編集:プログラムがエラーで停止した場合は、そのように指定してください(そして、エラーの内容を伝えてください)。


7
プログラムの動作に潜在的に影響を与える方法で、実行中にプログラムが独自のソースを変更する必要があることを正しく理解していますか?これは、ほとんどの非難解な言語を除外します。または、ソースを変更して、その上で新しいインタープリター/コンパイラプロセスを起動することは許可されていますか?
ズガルブ

@Zgarb 実際に、現在実行中のソースコードを変更する必要があります。はい、それはほとんどの言語を除外します。
mbomb007

8
@ mbomb007それは悪いです。
mınxomaτ

1
@ mbomb007修正されたソースコードを実行しなければならないことに挑戦するところはないという。
mınxomaτ

1
また、このチャレンジが簡単になるわけではありませんが、スコープは適切です。これで多すぎる言語を除外しました。
mınxomaτ

回答:


19

///、1バイト

/

プログラムは/(パターン置換グループの開始)を見つけ、置換を行う準備としてそれを削除します。その後、EOFに達するため、soめて停止します。


これは1バイトの最も早い回答であるため、勝者です。
mbomb007

22

ラビリンス、2バイト

>@

>それはなるようにソースを回転させ、

@>

命令ポインタは現在行き止まりになっており、方向を変え@てプログラムを終了します。

もちろん、<@動作します。


12

Python 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"長さが元のコンパイル済みコードオブジェクトのバイト数に等しいsの文字列です。

コードは実行中のコードオブジェクトを見つけ、sys._getframe().f_code.co_codepython文字列オブジェクトを表す構造体を作成します。次に、コードが実際に使用するメモリを取得し、それで置き換え"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、有効なオペコードではないため、上書きが成功し、プログラムが終了したことを示しています。

私はこれがPythonでも可能であることに驚いています、フレームオブジェクトは読み取り専用であり、新しいものを作成することはできません。これが行う唯一の複雑なことは、不変オブジェクト(文字列)の変更です。


これがすべてのキャラクターが異なる必要があるという要件を完全に満たしているかどうかはわかりません。元のソースコード内の「1」はまだマングルされたコード...で「1」になります
ダレル・ホフマン

実際、"1"コード内の文字列は実際には「コード」の一部ではなく、バイトコードで参照される単なる定数です。私が実際に変更しているのは、定数や変数ではなく、コンパイルされたpython仮想マシンのオペコードです。したがって、私が変更しているのは、ソースコードではなく、コンパイルされたコードだけです。ソースコードを保存済みとして変更できますが、既にコンパイルされているため、実行時にコードに実際には影響しません。必要に応じて、これを「定数付きのコンパイル済みPython 2.7オペコード」に投稿することもできますが、それは馬鹿げたIMOになります。
ブルー

また、コンパイルされたコードを見ることができません。内部を見るように変更することで、実際にコードを変更しているため、実際にはコードが表示されません。だから、コードは実際にそれがそれらのほとんどを変更するだけのことを、すべての文字を置き換える場合は、本当に、私は分からない(?)
ブルー

コンパイルされたコードに変更されていない1の問題を回避するには、変更される可能性"1"への<backtick>1+1<backtick>唯一の2以上のバイトのために
MEGO

私が見ることではありません(2.7.10でコンパイル)。残念ながら、1+1私の提案から2コンパイルされたバージョンになります...コンパイラはそれ自体の利益のためにあまりにもスマートです!
メゴ

11

、1バイト

q

evilには複数のメモリストアがあります。1つはソースコード自体で、もう1つは単一のゼロに初期化される循環キューであるホイールです。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インタープリターを実行するには2バイトが必要で、DC(両方ともnops)になる!U(両方ともnopsになる)

編集:Malbolgeメモリの初期状態はコードの最後の2文字に依存するため、1つの文字プログラムに対しては明確に定義されていません。(このコードはメモリの初期状態を気にしませんが)


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

一時値に使用するため91に、null(として表示_)を使用して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
   ^

生成されたコードを除き、実行後のテープはすべてゼロになります[_[_-_]_<_]

注意:

このプログラムにより、SMBF用のPythonインタープリターにバグが1つまたは2つあることがわかりましたが、まだ修正されていません。現在修正されています。


4

Emacs 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バイト、1命令(ほんの一例。競合していません)

これは簡単な例です。

次のメモリ位置を自分自身に移動してから停止します(メモリ全体がに初期化されるためDAT 0 0、実行時にプログラムが停止します)。

MOV 1 0

2
これをバイトではなく命令として数えるのはなぜですか?
マーティンエンダー

何バイトかわからないからです。メモリサイズ、または実装に依存していると思いますか?...
mbomb007

4
実装方法がわからない場合は、ASCII文字でカウントします。
リスト管理者

1
ウィキペディアのページから:各Redcode命令は、正確に1つのメモリスロットを占有し、実行するのにちょうど1サイクルかかります。...メモリは1つの命令単位でアドレス指定されます。
mbomb007

3
すべてのコードゴルフの投稿は、バイト単位で記録されます。Redcodeマシンコードはないので、アセンブル対象ではなく「アセンブリソース」の文字を使用する必要があります。
リルトシアスト

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 character)これは最後に反転しますので、最後の 'p'コマンドは(character、xpos、ypos)を読み取り、その位置をその文字のコード。最初の文字は手動で「<」として設定されるため、コードは最後に「> p <」となってコマンドをループします。次に、1文字おきに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.

@そこにそのコマンドがエコーされませんが、ほとんどはので、2つのechosがラインアップされません。


@ので、削除することができますECHO!(大文字)= echo(小文字)
pppery

@ppperry 2つechoのsは整列できません。
ericw31415

しかし、それらは異なるケースです。
pppery


0

(ファイルシステム)Befunge 98、46バイト

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

このプログラムはという名前のファイルを作成および操作することに注意してくださいa。使い方:

  1. このコードは、コードa全体(各次元で256文字まで)を含むファイルを作成し、1スペース上に左に2スペースシフトします。
  2. 次に、このプログラムはa、1行という名前のファイルを読み取り、最初の行全体をaファイルの内容に置き換えます。
  3. IPの前にコピーされた2行目が実行されます
  4. aファイルを2行目に右に2つシフトして読み取ります。

副作用として、終了するソースコードは有効なBefungeでさえありません!(1行のデータとして改行が含まれているため)


0

Python 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"):])

基本的に、これは間のpythonソースの現在のファイルのエンコーディングを切り替えますasciiutf-8、このようにして本質的にソースのすべての文字を変更します!


削除できる余分なスペースがいくつかあります。) as- > )as) else- > )else"utf-8"if'w',encoding
mbomb007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.