Programma di auto-mutilazione


16

In poche parole, il tuo obiettivo è quello di creare un programma completo che modifichi il proprio codice sorgente fino a quando ogni carattere della fonte è diverso da come è iniziato.

Si prega di includere la fonte iniziale e la fonte finale nel tuo post, nonché una descrizione. Ad esempio, descrivi cosa (altro) fa il tuo programma, la lingua che hai usato, la tua strategia, ecc.

Regole

  • Il programma deve arrestarsi dopo il completamento della modifica.
  • Deve effettivamente modificare il proprio codice sorgente attualmente in esecuzione (non necessariamente il file passato all'interprete, modifica le sue istruzioni), non stampare un nuovo programma o scrivere un nuovo file.
  • Le scappatoie standard non sono ammesse.
  • Vince il programma più breve.

  • Se la tua lingua può modificare il proprio file ed eseguire un nuovo processo di compilazione, ma non è possibile modificare il proprio codice sorgente (attualmente in esecuzione), è possibile scrivere tale programma invece con una penalità di + 20% byte, arrotondata per eccesso. Le lingue che si modificano da sole dovrebbero avere un vantaggio.

Modifica : se il programma si interrompe con errori, si prega di specificarlo come tale (e forse dire quali sono gli errori.)


7
Comprendo correttamente che il programma dovrebbe modificare la propria fonte mentre è in esecuzione, in modo da influire potenzialmente sul suo comportamento? Ciò escluderebbe la maggior parte delle lingue non esoteriche. O è consentito modificare l'origine e avviare un nuovo processo interprete / compilatore su di esso?
Zgarb,

@Zgarb Deve effettivamente modificare il proprio codice sorgente attualmente in esecuzione. Sì, questo esclude la maggior parte delle lingue.
mbomb007,

8
@ mbomb007 Questo è male.
mınxomaτ,

1
@ mbomb007 Da nessuna parte si dice che la sfida debba eseguire il codice sorgente modificato.
mınxomaτ,

1
Inoltre, no, non rende questa sfida banale, sarà comunque ben mirata. Hai escluso troppe lingue con questo.
mınxomaτ,

Risposte:


19

/// , 1 byte

/

Il programma trova un /(inizio di un gruppo di sostituzione del modello) e lo rimuove in preparazione per effettuare la sostituzione. Quindi raggiunge EOF, quindi si arrende e si ferma.


È la prima risposta con 1 byte, quindi è il vincitore.
mbomb007,

22

Labirinto , 2 byte

>@

I >ruota la sorgente in modo che diventi

@>

Il puntatore dell'istruzione è ora in un vicolo cieco e si gira per colpire il @quale termina il programma.

Certo, <@funzionerebbe anche.


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)

Il codice sorgente finale è una stringa di "0"s la cui lunghezza è uguale al numero di byte nell'oggetto codice compilato originale.

Il codice trova l'oggetto codice in esecuzione sys._getframe().f_code.co_codee crea una struttura che rappresenta gli oggetti stringa di Python. Quindi ottiene la memoria effettivamente acquisita dal codice e lo sostituisce "0"*len(c).

Quando eseguito, il programma termina con il seguente traceback:

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

Ciò dimostra che la sovrascrittura ha avuto esito positivo e il programma muore perché 0non è un codice operativo valido.

Sono sorpreso che questo sia persino possibile in Python, gli oggetti frame sono di sola lettura, non posso crearne di nuovi. L'unica cosa complicata che fa è cambiare un oggetto immutabile (una stringa).


Non sono sicuro se questo soddisfa abbastanza i requisiti che OGNI personaggio deve essere diverso. L '"1" nel codice sorgente originale sarebbe comunque un "1" nel codice modificato ...
Darrel Hoffman,

Bene in realtà, la "1"stringa nel codice non è in realtà parte del 'codice', è solo una costante a cui si fa riferimento nel bytecode. Quello che sto effettivamente cambiando sono i codici operativi compilati della macchina virtuale Python, non le costanti o le variabili. Quindi quello che sto cambiando non è il codice sorgente per dire, solo il codice compilato. Potrei modificare il codice sorgente come memorizzato ma ciò non influirebbe effettivamente sul codice in fase di esecuzione perché sarebbe già stato compilato. Se lo volessi, potrei postarlo in un "codice operativo Python 2.7 compilato con costanti", ma sarebbe sciocco IMO.
Blu,

Inoltre, non riesco a guardare il codice compilato perché cambiandolo per vedere dentro, sto effettivamente cambiando il codice, il che significa che non vedo effettivamente il codice. Quindi, davvero, non ho idea se il codice sostituisce davvero ogni carattere, solo che cambia la maggior parte (?) Di loro
Blue

Per aggirare il problema del 1 che non viene modificato nel codice compilato, è possibile modificare il "1"con <backtick>1+1<backtick>solo per altri 2 byte
Mego

Non quello che vedo (compilato con 2.7.10). Sfortunatamente, il 1+1mio suggerimento viene trasformato in un 2nella versione compilata ... Il compilatore è troppo intelligente per il suo bene!
Mego,

11

male , 1 byte

q

il male ha diversi archivi di memoria: uno è il codice sorgente stesso e uno è la ruota che è una coda circolare che viene inizializzata su un singolo zero. qscambia il codice sorgente e la ruota, quindi sostituisce il codice sorgente con un byte null. Tuttavia, solo le lettere minuscole sono veri e propri operatori malvagi, quindi quel personaggio è semplicemente un non-op e il programma termina.


6

MSM , 8 byte

'.qp.;.;

Trasforma il codice sorgente in pqpqpqpq

MSM opera su un elenco di stringhe. I comandi vengono presi da sinistra e trattano il lato destro come una pila. MSM funziona sempre sulla propria fonte.

Traccia di esecuzione:

'.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 o 2 byte.

D

Il linguaggio Malbolge "crittografa" ogni istruzione dopo averla eseguita, quindi questa lettera (Malbolge NOP) diventerà un !(che è anche un nop), e quindi terminerà. Per qualche motivo, l'interprete Malbolge che uso richiede due byte per l'esecuzione, dando DC(entrambi i quali sono nops) diventando !U(entrambi i quali sono anche nops)

Modifica: lo stato iniziale della memoria di Malbolge dipende dagli ultimi due caratteri nel codice, quindi non è ben definito per i programmi a un carattere. (Anche se a questo codice non interessa lo stato iniziale della memoria)


5

x86 asm - 6 byte

non sono sicuro se "fino a quando ogni carattere della sorgente è diverso da come è iniziato" si riferisce a ogni byte, ogni nemonica o modifica generale. se non sono valido posso cambiare lo xor in un rep xor in modo che ogni bit cambi valore ma speravo di non farlo per salvare altri 6 byte per rimanere almeno un po 'paragonabile a queste lingue di golf speciali.

Tutto ciò che fa è cambiare un c2 in un retn c3 ottenendo l'indirizzo live di eip e xoring 5 byte davanti.

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

Può essere giocato a golf, e probabilmente ci lavorerò più in seguito.

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

Spiegazione

Il programma genera i seguenti comandi alla fine del suo nastro per cancellare se stesso, quindi deve generare i seguenti valori sul nastro:

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

Crea un gruppo di 91s, con _valori null (mostrati come ) tra da utilizzare per i valori temporanei.

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

code__91_91_91_91_91_91_
   ^

Regola i valori in base alle differenze

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

Il nastro che segue l'esecuzione sarà tutto azzerato, ad eccezione del codice generato [_[_-_]_<_].

Nota:

Questo programma mi ha fatto capire che il mio interprete Python per SMBF ha un bug o due, e non ho ancora trovato una soluzione. Ora è riparato.


4

Emacs Lisp 22 byte

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

Esegui da 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)

La funzione ora valuta nil.

In alternativa (separare se stesso) 30 byte

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

Valuta ed errori come void-function. La funzione esisteva prima di essere eseguita.


4

Redcode , 7 byte, 1 istruzione (solo un esempio. Non in competizione)

Questo è un esempio banale.

Sposta la posizione di memoria successiva su se stessa, quindi si arresta (poiché l'intera memoria è inizializzata su DAT 0 0, che arresta il programma quando eseguito.)

MOV 1 0

2
Perché stai contando questo come istruzioni anziché byte?
Martin Ender,

Perché non so quanti byte è. Penso che dipenda dalle dimensioni della memoria o dall'implementazione? ...
mbomb007

4
Conterei per i caratteri ASCII se non sai come è implementato.
lirtosiast

1
Dalla pagina Wikipedia: ogni istruzione Redcode occupa esattamente uno slot di memoria e richiede esattamente un ciclo per l'esecuzione. ... La memoria è indirizzata in unità di un'istruzione.
mbomb007,

3
Tutti i post di code-golf sono assegnati in byte. Dato che non esiste un codice macchina Redcode, dobbiamo usare i caratteri in "sorgente assembly", non ciò a cui si assembla.
lirtosiast

3

Powershell 65 byte

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

Definire una funzione che si riscrive da sola a null.

Valutalo una volta e si elimina da solo.

In alternativa (si cancella dalla memoria) 36 byte

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

Chiamarlo prima lo rimuove, quindi tenta di valutare in modo ricorsivo. Errore come comando sconosciuto.


3

MIXAL, 6 byte (contando 2 schede)

    STZ    0

Il programma inizia nella posizione di memoria 0 e quindi scrive 0 nella posizione di memoria 0, cancellandosi così. La macchina si ferma automaticamente.

Questo è il linguaggio assembly per l'ipotetico computer MIX di Donald Knuth, che può essere assemblato ed eseguito utilizzando il kit di sviluppo GNU MIX ( https://www.gnu.org/software/mdk/ ).


3

> <> , 40 34 30 byte

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

Provalo qui!

Spiegazione:

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

Fondamentalmente questo mette un mucchio di 3 blocchi di caratteri nello stack in questo modo: (ypos, xpos, carattere ASCII) che viene invertito alla fine in modo che il comando finale 'p' legga (carattere, xpos, ypos) e imposta quella posizione nella codice per quel carattere. Il primo carattere viene impostato manualmente come '<', in modo che il codice finisca per essere '> p <' alla fine per eseguire il ciclo in sequenza del comando. Quindi ogni altro personaggio viene sovrascritto come un '' incluso il carattere p. '' È in realtà "ASCII CHAR 0" che NON è un NOP e genererà un errore durante la lettura.

Inoltre, ci deve essere un numero dispari (?) Di caratteri prima del comando 'p', altrimenti non verrà ricollegato in un'ultima volta e sovrascritto.


2

Lotto, 11 byte

@echo>%0&&*

Modifica il codice sorgente in 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.

Il @c'è così il comando non è ripreso, ma per lo più in modo che i due echos non si allineano.


il @può essere rimosso, perché ECHO(maiuscolo) =! echo(minuscolo)
pppery

@ppperry I due echonon riescono ad allinearsi.
ericw31415,

Ma sono casi diversi.
pepery

2

Jolf, 4 byte, non competitivo

₯S₯C

Ciò ₯Sconsente di impostare il ₯Cvalore dell'elemento ode sull'input, undefinedpoiché non ne viene fornito nessuno. Provalo qui!


0

(Filesystem) Befunge 98, 46 byte

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

Si noti che questo programma crea e manipola un file denominato a. Come funziona:

  1. Il codice crea un file denominato acontenente l'intero codice (fino a 256 caratteri in ogni dimensione) spostato di uno spazio verso l'alto e due a sinistra.
  2. Questo programma legge quindi il file denominato acome una riga, sostituendo l'intera prima riga con il contenuto dia file.
  3. Viene eseguita la seconda riga, che è stata copiata davanti all'IP
  4. Che legge il afile nella seconda riga spostato di due posizioni a destra.

Come effetto collaterale, il codice sorgente finale non è nemmeno valido Befunge! (perché contiene newline come dati in una singola riga)


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

Fondamentalmente, questo alterna la codifica del file corrente tra la sorgente Python asciie utf-8, cambiando sostanzialmente ogni carattere della sorgente!


Ci sono alcuni spazi extra che possono essere rimossi. ) as-> )as, ) else-> )else, "utf-8"if, 'w',encoding.
mbomb007,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.