Write a program that encodes given text into its own text, provided as input, without disrupting its logic. The program must also work as a decoder, restoring the original message from its text. It must retain its encoding/decoding functions after transformation.

More formally speaking, the required program P must perform the following transformations with the given message text M:

Here P* is the transformed program, which also must satisfy the above rules, that is:
and so on... Each subsequent encoding doesn't erase previously encoded text, so P** carries two messages - M and M2.

The easiest way for the program to distinguish between encoding/decoding modes is by the presence of the extra argument M, but the final decision is up to you, provided it is clearly stated. The program may read it's own text from the file. If the chosen language doesn't have means for this, the source text can be passed to the program in any other way.

There are trivial solutions, of course, so this is rather a popularity contest. Nevertheless, I impose restriction forbidding comments in the program text.

  • \$\begingroup\$ If I call the transformed program P* with a new text, does P** contain both texts or only the last one? \$\endgroup\$
    – Tal
    Jun 15, 2014 at 13:41
  • \$\begingroup\$ So I am given the programs code as input when encoding and decoding? \$\endgroup\$ Jun 15, 2014 at 13:48
  • \$\begingroup\$ How is the program intended to distinguish between being asked to decode an encoded message, and being asked to encode a message which just happens to be itself an encoded message? \$\endgroup\$
    – celtschk
    Jun 15, 2014 at 13:54
  • 2
    \$\begingroup\$ @celtschk judging by the OPs notation: if your program is given two inputs, encode the first input in the second input. if the program is given only one input, extract the string most recently encoded in that input. \$\endgroup\$ Jun 15, 2014 at 14:07
  • 4
    \$\begingroup\$ Is there supposed to be any way to recover P* from P**? If not, why require that "P** carries two messages - M and M2"? I'm sorry, but although this challenge seems interesting, the spec is just way too confusing for me. \$\endgroup\$ Jun 15, 2014 at 23:13

5 Answers 5



This is a one-liner in Perl just because it's possible.


The messages are written after __DATA__, most recent first.

  • \$\begingroup\$ How about healthy competition and single expression? \$\endgroup\$
    – seequ
    Jun 16, 2014 at 6:57
  • \$\begingroup\$ That's a pretty large value of one you've got there. \$\endgroup\$ Jun 16, 2014 at 11:46


You know what? Why not make it a single 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)

Old message; The function P takes the arguments as specified and outputs the resulting code / decoded text.

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)


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") + ")");

Not sure if I understand the problem statement correctly: my decoder will decode any program and return the latest message that is encoded in the given program.

Test code:

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



// Unspecified behavior


@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

Note there needs to be a carriage return after 'the last line' of goto :EOF.

This takes two inputs from stdin. The first of which is what you want to do; e, or d (encode and decode). The second input depends on the first - if the first input is e, then the second input will be the message that you want to encode - if it is d, then the second input will be the number of the message you wish to decode (that will be provided after encoding a message).

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

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


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'
    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)

While the idea is trivial, the execution of said idea is less-so.


Encoding a message in the program will add the line .message = .message ? x immediately after def main. This line checks if .message is nil, and if so, then it sets .message to an integer array containing the character code values of each character in the message; the nil-check and positioning avoid overwriting the new message with an older one. The new program is saved to encode.cobra


Decoding the program will add three lines at the end of the main method which cause the program to convert the char codes in .message to a string, which is then saved to message.txt when the new program is run. The new program is then saved to decode.cobra and the compiler is invoked on it.

decode.cobra is used like a temporary file and cannot be used to encode or decode another message, use the original or encode.cobra


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.