Programme qui encode un message dans son propre texte

13

Écrivez un programme qui code un texte donné dans son propre texte, fourni en entrée, sans perturber sa logique. Le programme doit également fonctionner comme un décodeur, en restaurant le message d'origine à partir de son texte. Il doit conserver ses fonctions d'encodage / décodage après transformation.

Plus formellement, le programme requis P doit effectuer les transformations suivantes avec le texte de message donné M:
P (M, P) -> P *
P * (P *) -> M

Ici P * est le programme transformé, qui doit également satisfaire aux règles ci-dessus, c'est-à-dire:
P * (M2, P *) -> P **
P ** (P **) -> M2
et ainsi de suite ... Chacun l'encodage suivant n'efface pas le texte précédemment encodé, donc P ** transporte deux messages - M et M2.

Le moyen le plus simple pour le programme de distinguer les modes d'encodage / décodage est la présence de l'argument supplémentaire M, mais la décision finale vous appartient, à condition qu'elle soit clairement indiquée. Le programme peut lire son propre texte dans le fichier. Si la langue choisie n'a pas de moyen pour cela, le texte source peut être transmis au programme de toute autre manière.

Il existe bien sûr des solutions triviales, il s'agit donc plutôt d'un concours de popularité. Néanmoins, j'impose une restriction interdisant les commentaires dans le texte du programme.

Tr00rle
la source
Si j'appelle le programme transformé P * avec un nouveau texte, P ** contient-il les deux textes ou seulement le dernier?
Tal
On me donne donc le code des programmes en entrée lors de l'encodage et du décodage?
Martin Ender
Comment le programme est-il censé faire la distinction entre être invité à décoder un message codé et être invité à coder un message qui se trouve être lui-même un message codé?
celtschk
2
@celtschk à en juger par la notation OP: si votre programme reçoit deux entrées, encodez la première entrée dans la deuxième entrée. si le programme ne reçoit qu'une seule entrée, extrayez la chaîne codée le plus récemment dans cette entrée.
Martin Ender
4
Est-il censé y avoir un moyen de récupérer P * de P **? Sinon, pourquoi exiger que " P ** porte deux messages - M et M2 "? Je suis désolé, mais bien que ce défi semble intéressant, la spécification est tout simplement trop confuse pour moi.
Ilmari Karonen

Réponses:

8

Perl

Il s'agit d'un one-liner en Perl simplement parce que c'est possible.

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

Les messages sont écrits après __DATA__, le plus récent en premier.

Greg Hewgill
la source
Que diriez-vous d'une compétition saine et d'une expression unique?
seequ
C'est une valeur assez importante de celui que vous avez là-bas.
Gilles 'SO- arrête d'être méchant'
4

Python

Vous savez quoi? Pourquoi ne pas en faire une seule expression?

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)

Ancien message; La fonction P prend les arguments comme spécifié et sort le code / texte décodé résultant.

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)
seequ
la source
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") + ")");
    }
}

Je ne sais pas si je comprends correctement l'énoncé du problème: mon décodeur décode tout programme et renvoie le dernier message codé dans le programme donné.

Code de test:

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))
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
la source
2

Lot

@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

Notez qu'il doit y avoir un retour chariot après «la dernière ligne» de goto :EOF.

Cela prend deux entrées de stdin. Le premier est ce que vous voulez faire; e, ou d(encoder et décoder). La deuxième entrée dépend de la première - si la première entrée est e, alors la deuxième entrée sera le message que vous voulez encoder - si c'est le cas d, alors la deuxième entrée sera le numéro du message que vous souhaitez décoder (qui sera être fourni après avoir encodé un message).

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

H:\uprof>ed.bat d 1
Just a message
dégrader
la source
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)

Bien que l' idée soit banale, l' exécution de cette idée l'est moins.

Codage

L'encodage d'un message dans le programme ajoutera la ligne .message = .message ? ximmédiatement après def main. Cette ligne vérifie si .messageest nul, et si oui, elle définit.message alors un tableau d'entiers contenant les valeurs de code de caractère de chaque caractère du message; la vérification zéro et le positionnement évitent d'écraser le nouveau message par un ancien. Le nouveau programme est enregistré dansencode.cobra

Décodage

Le décodage du programme ajoutera trois lignes à la fin de la méthode principale, ce qui obligera le programme à convertir les codes de caractères en .messageune chaîne, qui sera ensuite enregistrée message.txtlors de l'exécution du nouveau programme. Le nouveau programme est ensuite enregistré dans decode.cobraet le compilateur est appelé dessus.

decode.cobra est utilisé comme un fichier temporaire et ne peut pas être utilisé pour encoder ou décoder un autre message, utilisez l'original ou encode.cobra

Οurous
la source