Programa que codifica uma mensagem em seu próprio texto


13

Escreva um programa que codifique o texto fornecido em seu próprio texto, fornecido como entrada, sem interromper sua lógica. O programa também deve funcionar como um decodificador, restaurando a mensagem original do seu texto. Ele deve manter suas funções de codificação / decodificação após a transformação.

Mais formalmente, o programa requerido P deve executar as seguintes transformações com o texto de mensagem M:
P (M, P) -> P *
P * (P *) -> M

Aqui, P * é o programa transformado, que também deve satisfazer as regras acima, ou seja:
P * (M2, P *) -> P **
P ** (P **) -> M2
e assim por diante ... a codificação subsequente não apaga o texto codificado anteriormente; portanto, P ** carrega duas mensagens - M e M2.

A maneira mais fácil para o programa distinguir entre os modos de codificação / decodificação é pela presença do argumento extra M, mas a decisão final é com você, desde que claramente indicado. O programa pode ler o próprio texto do arquivo. Se o idioma escolhido não tiver meios para isso, o texto fonte pode ser passado para o programa de qualquer outra maneira.

Existem soluções triviais, é claro, então esse é um concurso de popularidade. No entanto, imponho restrições que proíbem comentários no texto do programa.


Se eu chamar o programa transformado P * com um novo texto, P ** contém os dois textos ou apenas o último?
Tal

Então, eu recebo o código do programa como entrada ao codificar e decodificar?
Martin Ender

Como o programa pretende distinguir entre ser solicitado a decodificar uma mensagem codificada e ser solicitado a codificar uma mensagem que, por acaso, é uma mensagem codificada?
celtschk

2
@celtschk a julgar pela notação do OP: se o seu programa receber duas entradas, codifique a primeira entrada na segunda entrada. se o programa receber apenas uma entrada, extraia a sequência codificada mais recentemente nessa entrada.
Martin Ender

4
Supõe-se que haja alguma maneira de recuperar P * de P **? Caso contrário, por que exigir que " P ** transporta duas mensagens - M e M2 "? Sinto muito, mas embora esse desafio pareça interessante, as especificações são muito confusas para mim.
Ilmari Karonen

Respostas:


8

Perl

Esta é uma linha única no Perl apenas porque é possível.

if($ARGV[0]){open(F,__FILE__);while(<F>){print;print"$ARGV[0]\n"if/^_/;}}else{print<DATA>;}
__DATA__

As mensagens são gravadas depois __DATA__, as mais recentes primeiro.


Que tal competição saudável e expressão única?
see

Esse é um valor muito grande de um que você tem lá.
Gilles 'SO- stop be evil'

4

Pitão

Você sabe o que? Por que não torná-lo uma única expressão?

P = (lambda M,P=None:(lambda t:P[:74]+repr(M)[1:-1]+"'))"if P else M[74:-3])(''))
Pc = "(lambda M,P=None:(lambda t:P[:74]+repr(M)[1:-1]+\"'))\"if P else M[74:-3])(''))"
P2c = P('Hi there, mate!', Pc)
print "Encode tests:"
print " P2 = P('Hi there, mate!', Pc) =", P2c
exec 'P2 = ' + P2c
print " P2(\"Test 2's the best.\", P2c) =", P2("Test 2's the best.", P2c)

print "Decode tests:"
print "P2(P2) =", P2(P2c)
print "P(P2)  =", P(P2c)
print "P2(P)  =", P2(Pc)
print "P(P)   =", P(Pc)

Mensagem antiga; A função P aceita os argumentos conforme especificado e gera o código resultante / texto decodificado.

def P(data,func=None):
    text = ""
    if func:
        return func[:35]+data+'"\n'+'\n'.join(func.split('\n')[2:])
    return data[35:].split('\n')[0][:-1]

# The source code.
Pc = """def P(data,func=None):
    text = ""
    if func:
        return func[:35]+data+'"\\n'+'\\n'.join(func.split('\\n')[2:])
    return data[35:].split('\\n')[0][:-1]"""

P2c = P('Hi there, mate!', Pc)
print "Encode test:"
print "P('Hi there, mate!', P) ->"
print P2c

# This is outputted by P('Hi there, mate!', code-of-P)
def P2(data,func=None):
    text = "Hi there, mate!"
    if func:
        return func[:35]+data+'"\n'+'\n'.join(func.split('\n')[2:])
    return data[35:].split('\n')[0][:-1]

print "P2('Text 2', P2) -<"
print P2('Text 2', P2c)

print "Decode test:"
print "P2(P2) =", P2(P2c)
print "P(P2)  =", P(P2c)
print "P2(P)  =", P2(Pc)
print "P(P)   =", P(Pc)

2

Javascript

var transform = function (p, m) {
    var _M_ = '';
    var source = arguments.callee.toString();
    var msgre = /(_M_ = ').*(';)/;
    var regex = new RegExp(source.replace(/[.*+?^$\[\]{}()\\|]/g, "\\$&").replace(msgre, "$1(.*)$2"));

    var a = p.toString().match(regex);

    if (!a) {
        throw "first argument must be a transform function"
    } else {
        a = a[1];
    }

    if (typeof m == "undefined") {
        return eval("[" + a.split("|")[0] + "]").map(x=>String.fromCharCode(x)).join("");
    } else {
        a = m.toString().split("").map(x => x.charCodeAt(0)) + (a.length ? "|" + a: a);
        return eval("(" + source.replace(msgre, "$1" + a + "$2") + ")");
    }
}

Não tenho certeza se entendi corretamente a declaração do problema: meu decodificador decodificará qualquer programa e retornará a mensagem mais recente codificada no programa fornecido.

Código do teste:

P1 = transform(transform, "first message");
P2 = P1(P1, "second message");

console.log(P1(P1));
console.log(P2(P2));

console.log(P2(P1));
console.log(P1(P2));

// Unspecified behavior
console.log(transform(transform))

2

Lote

@echo off

setLocal enableDelayedExpansion
for /f %%a in (%0) do set a=%%a

if "%~1"=="e" (
    set /a a+=1
    echo !a! %~2 >> %0
    echo message encoded as !a!
) else if "%~1"=="d" for /f "skip=12 tokens=1*" %%a in (%0) do if "%%a"=="%~2" echo %%b

goto :EOF

Observe que precisa haver um retorno de carro após 'a última linha' de goto :EOF.

Isso requer duas entradas do stdin. O primeiro deles é o que você deseja fazer; e, ou d(codifique e decodifique). A segunda entrada depende da primeira - se a primeira entrada for e, a segunda entrada será a mensagem que você deseja codificar - se for d, a segunda entrada será o número da mensagem que você deseja decodificar (que será fornecido após a codificação de uma mensagem).

H:\uprof>ed.bat e "Just a message"
message encoded as 1

H:\uprof>ed.bat d 1
Just a message

0

Cobra

use System.Diagnostics
class Program
    var message as int[]? = nil
    def decode(program as String)
        temp = List<of String>(program.split('\n'))
        temp.insert(4, '\t\tEnvironment.exit(0)')
        temp.add('\t\tmessage = \'\'')
        temp.add('\t\tfor i in .message, message += Convert.toString(i to char)')
        temp.add('\t\tFile.writeAllText(\'message.txt\', message)')
        program = temp.join('\n')
        File.writeAllText('decode.cobra', program)
        process = Process()
        process.startInfo.fileName = 'cmd.exe'
        process.startInfo.arguments = '/C cobra decode.cobra'
        process.start
    def encode(message as String, program as String)
        temp = List<of String>()
        for i in message.toCharArray, temp.add(Convert.toString(i to int))
        message = '@' + Convert.toString(c'[')
        for n in temp.count-1, message += temp[n] + ','
        message += temp.pop + ']'
        temp = List<of String>(program.split('\n'))
        temp.insert(26,'\t\t.message = .message ? [message]')
        program = temp.join('\n')
        File.writeAllText('encode.cobra', program)
    def main
        #call methods here
        #.encode(message, program)
        #.decode(program)

Enquanto a ideia é trivial, a execução da mesma é menos.

Codificação

A codificação de uma mensagem no programa adicionará a linha .message = .message ? ximediatamente após def main. Essa linha verifica se .messageé nulo e, em caso afirmativo, define .messagecomo uma matriz inteira contendo os valores do código de caractere de cada caractere na mensagem; a verificação e o posicionamento nulos evitam sobrescrever a nova mensagem por uma mais antiga. O novo programa é salvo emencode.cobra

Decodificação

A decodificação do programa adicionará três linhas no final do método principal, que fazem com que o programa converta os códigos de caracteres em .messageuma string, que é salva no message.txtmomento em que o novo programa é executado. O novo programa é salvo decode.cobrae o compilador é chamado nele.

decode.cobra é usado como um arquivo temporário e não pode ser usado para codificar ou decodificar outra mensagem, use o original ou encode.cobra

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.