Programa de auto-mutilação


16

Simplificando, seu objetivo é criar um programa completo que modifique seu próprio código-fonte até que cada caractere da fonte seja diferente do que foi iniciado.

Inclua a fonte inicial e a fonte final em sua postagem, bem como uma descrição. Por exemplo, descreva o que (mais) seu programa faz, o idioma que você usou, sua estratégia etc.

Regras

  • Seu programa deve parar algum tempo após a conclusão da modificação.
  • Na verdade, ele deve modificar seu próprio código-fonte em execução no momento (não necessariamente o arquivo que você passou para o intérprete, ele modifica suas instruções), não imprimir um novo programa ou gravar um novo arquivo.
  • As brechas padrão não são permitidas.
  • O programa mais curto vence.

  • Se seu idioma puder modificar seu próprio arquivo e executar um novo processo do compilador, mas não puder modificar seu próprio código-fonte (atualmente em execução), você poderá escrever um programa como esse com uma penalidade de + 20% bytes, arredondados para cima. Linguagens auto-modificadoras reais devem ter uma vantagem.

Editar : se o seu programa parar com erros, especifique-o como tal (e talvez diga quais são os erros).


7
Entendo corretamente que o programa deve modificar sua própria fonte enquanto está em execução, de uma maneira que potencialmente afeta seu comportamento? Isso excluiria a maioria das línguas não esotéricas. Ou é permitido modificar a fonte e iniciar um novo processo de intérprete / compilador?
Zgarb 7/10

@ Zgarb Na verdade, ele deve modificar seu próprio código-fonte em execução no momento. Sim, isso exclui a maioria dos idiomas.
mbomb007

8
@ mbomb007 Isso é ruim.
mınxomaτ 7/10/2015

11
@ mbomb007 Diz que em nenhum lugar do seu desafio você precisa executar o código fonte modificado.
mınxomaτ 7/10/2015

11
Além disso, não, isso não torna esse desafio trivial, ainda terá um bom escopo. Você descartou muitos idiomas com isso.
mınxomaτ 7/10/2015

Respostas:


19

/// , 1 byte

/

O programa localiza um /(o início de um grupo de substituição de padrão) e o remove em preparação para fazer a substituição. Então atinge EOF, então desiste e pára.


A resposta é a mais antiga com 1 byte, por isso é a vencedora.
mbomb007

22

Labirinto , 2 bytes

>@

O >gira a fonte para que ela se torne

@>

O ponteiro de instruções está agora em um beco sem saída e se vira para atingir o @que encerra o programa.

Claro, <@também funcionaria.


12

Python 2, 225 bytes

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)

O código-fonte final é uma sequência de "0"s cujo comprimento é igual ao número de bytes no objeto de código compilado original.

O código localiza o objeto de código em execução,, sys._getframe().f_code.co_codee cria uma estrutura que representa objetos de string python. Em seguida, ele obtém a memória que o código realmente leva e o substitui "0"*len(c).

Quando executado, o programa sai com o seguinte rastreamento:

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

Isso mostra que a substituição foi bem-sucedida e o programa morre porque 0não é um código de operação válido.

Estou surpreso que isso seja possível em python, os objetos de quadro são somente leitura, não consigo criar novos. A única coisa complicada que isso faz é alterar um objeto imutável (uma string).


Não tenho certeza se isso atende aos requisitos de que CADA caractere deve ser diferente. O "1" no código fonte original ainda seria um "1" no código mutilado ...
Darrel Hoffman

Bem, na verdade, a "1"string no código não faz parte do 'code', é apenas uma constante mencionada no bytecode. Na verdade, estou mudando os opcodes da máquina virtual python compilada, não as constantes ou variáveis. Então, o que estou mudando não é o código fonte, por exemplo, apenas o código compilado. Eu poderia alterar o código-fonte como armazenado, mas isso não afetaria o código em tempo de execução, porque ele já teria sido compilado. Se você quisesse, eu poderia postar isso em um 'código de código compilado do Python 2.7 com constantes', mas isso seria idiota da IMO.
Blue

Além disso, não consigo olhar para o código compilado porque, ao alterá-lo para dentro, estou alterando o código, o que significa que não vejo o código. Então, realmente, eu não tenho idéia se o código realmente substitui cada personagem, só que ele muda a maioria deles (?)
azul

Para contornar o problema do 1 que não está sendo alterado no código compilado, você pode alterá-lo "1"para <backtick>1+1<backtick>por apenas mais 2 bytes
Mego 28/04

Não que eu veja (compilado com 2.7.10). Infelizmente, o 1+1da minha sugestão se transformou em um 2na versão compilada ... O compilador é inteligente demais para o seu próprio bem!
Mego

11

mal , 1 byte

q

o mal tem vários armazenamentos de memória - um é o próprio código-fonte e o outro é a roda, que é uma fila circular que é inicializada em um único zero. qtroca o código fonte e a roda, substituindo a fonte por um byte nulo. No entanto, apenas letras minúsculas são operadores reais no mal, de modo que o caractere é simplesmente um não-op e o programa termina.


6

MSM , 8 bytes

'.qp.;.;

Transforma o código fonte em pqpqpqpq

MSM opera em uma lista de seqüências de caracteres. Os comandos são obtidos da esquerda e tratam o lado direito como uma pilha. O MSM sempre trabalha em sua própria fonte.

Rastreio de execução:

'.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 ou 2 bytes.

D

A linguagem Malbolge "criptografa" cada instrução após executá-la; portanto, esta carta (Malbolge NOP) se tornará uma !(que também é um nop) e será encerrada. Por alguma razão, o intérprete de Malbolge que eu uso requer dois bytes para ser executado, dando DC(ambos os nops)!U (os dois também são nops)

Edit: O estado inicial da memória Malbolge depende dos dois últimos caracteres no código, portanto, não está bem definido para programas de um caractere. (Embora esse código não se importe com o estado inicial da memória)


5

x86 asm - 6 bytes

não tenho certeza se "até que cada caractere da fonte seja diferente do que foi iniciado" se refere a cada byte, cada modificação nemônica ou geral. se eu for inválido, posso alterar o xor para um rep xor, para que cada bit mude os valores, mas esperava não fazer isso para economizar mais 6 bytes para permanecer pelo menos um pouco comparável a esses idiomas de golfe especializados.

Tudo o que isso faz é alterar um c2 para um c3 retn, obtendo o endereço ativo de eip e xorando 5 bytes à frente.

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 bytes

Pode jogar golfe, e provavelmente vou trabalhar mais nisso mais tarde.

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

Explicação

O programa gera os seguintes comandos no final de sua fita para se apagar, portanto, ele precisa gerar os seguintes valores na fita:

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

Faça um monte de 91s, com nulos (mostrados como _) entre para usar para valores temporários.

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

code__91_91_91_91_91_91_
   ^

Ajuste os valores pelas diferenças

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

A fita após a execução será toda zerada, com exceção do código gerado [_[_-_]_<_].

Nota:

Esse programa me fez perceber que meu intérprete Python para SMBF tem um bug ou dois e ainda não descobri uma correção. Está consertado agora.


4

Emacs Lisp 22 bytes

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

Execute a partir do 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)

A função agora é avaliada como nil.

Como alternativa (desvincular-se) 30 bytes

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

Avalie e erros como void-function. A função existia antes de ser executada.


4

Código vermelho , 7 bytes, 1 instrução (Apenas um exemplo. Não competindo)

Este é um exemplo trivial.

Move a próxima localização da memória para si mesma e depois pára (porque toda a memória é inicializada DAT 0 0, o que interrompe o programa quando executado).

MOV 1 0

2
Por que você está contando isso como instruções em vez de bytes?
Martin Ender

Porque eu não sei quantos bytes são. ? Eu acho que é dependente do tamanho da memória, ou a implementação ...
mbomb007

4
Eu contaria por caracteres ASCII se você não souber como é implementado.
Jun /

11
Na página da Wikipedia: cada instrução Redcode ocupa exatamente um slot de memória e leva exatamente um ciclo para executar. ... A memória é endereçada em unidades de uma instrução.
mbomb007

3
Todas as mensagens de código de golfe são pontuadas em bytes. Como não há código de máquina Redcode, devemos usar os caracteres na "fonte de montagem", não no que ele monta.
lirtosiast

3

Powershell 65 bytes

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

Defina uma função que se reescreve como nula.

Avalie uma vez e se elimina.

Como alternativa (exclui-se da memória) 36 bytes

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

Chamar primeiro remove e depois tenta avaliar recursivamente. Erro como um comando desconhecido.


3

MIXAL, 6 bytes (contando 2 guias)

    STZ    0

O programa inicia no local de memória 0 e depois grava 0 no local de memória 0, apagando-se. A máquina pára automaticamente.

Essa é a linguagem assembly para o hipotético computador MIX de Donald Knuth, que pode ser montado e executado usando o kit de desenvolvimento GNU MIX ( https://www.gnu.org/software/mdk/ ).


3

> <> , 40 34 30 bytes

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

Experimente aqui!

Explicação:

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

Basicamente, isso coloca um monte de 3 blocos de caracteres na pilha da seguinte forma: (ypos, xpos, caractere ASCII) que é revertido no final para que o comando final 'p' leia (caractere, xpos, ypos) e define essa posição no código para esse caractere. O primeiro caractere é definido manualmente como '<', para que o código acabe sendo '> p <' no final para executar um loop no comando. Todos os outros caracteres são substituídos como "", incluindo o caractere p. O '' é realmente "ASCII CHAR 0", que NÃO é um NOP e causará um erro quando lido.

Também deve haver um número ímpar (?) De caracteres antes do comando 'p' ou ele não será repetido pela última vez e substituído.


2

Lote, 11 bytes

@echo>%0&&*

Modifica o código fonte para 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.

O @existe para que o comando não seja repetido, mas principalmente para que os dois echonão se alinhem.


o @pode ser removido, porque ECHO(maiúsculas) =! echo(em minúsculas)
pppery

@ppperry Os dois echos não podem se alinhar.
ericw31415

Mas são casos diferentes.
achou


0

(Sistema de arquivos) Entre 98, 46 bytes

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

Observe que este programa cria e manipula um arquivo chamado a. Como funciona:

  1. O código cria um arquivo chamado a contendo o código inteiro (com 256 caracteres em cada dimensão) deslocou um espaço para cima e dois para a esquerda.
  2. Este programa lê o arquivo nomeado acomo uma linha, substituindo a primeira linha inteira pelo conteúdo doa arquivo.
  3. A segunda linha, que foi copiada na frente do IP, é executada
  4. Que lê o aarquivo na segunda linha mudou duas posições para a direita.

Como efeito colateral, o código-fonte final não é válido Befunge! (porque contém novas linhas como dados em uma única linha)


0

Python 2, 238 bytes + 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"):])

Basicamente, isso alterna a codificação de arquivo atual da fonte python entre asciie utf-8, portanto, essencialmente alterando todos os caracteres da fonte!


Existem alguns espaços extras que podem ser removidos. ) as-> )as, ) else-> )else, "utf-8"if, 'w',encoding.
mbomb007
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.