Програма, що кодує повідомлення у власному тексті


13

Напишіть програму, кодує заданий текст у свій власний текст, поданий як введення, не порушуючи його логіки. Програма також повинна працювати як декодер, відновлюючи початкове повідомлення з його тексту. Він повинен зберігати свої функції кодування / декодування після перетворення.

Більш формально кажучи, потрібна програма P повинна виконати наступні перетворення із заданим текстом повідомлення M:
P (M, P) -> P *
P * (P *) -> M

Тут P * - це перетворена програма, яка також повинна відповідати вищевказаним правилам, тобто:
P * (M2, P *) -> P **
P ** (P **) -> M2
і так далі ... Кожна наступне кодування не стирає раніше кодований текст, тому P ** несе два повідомлення - M і M2.

Найпростіший спосіб розрізнити програми кодування / декодування - це наявність додаткового аргументу M, але остаточне рішення залежить від вас, якщо це чітко зазначено. Програма може прочитати власний текст із файлу. Якщо обрана мова не має засобів для цього, вихідний текст може бути переданий програмі будь-яким іншим способом.

Звичайно, є тривіальні рішення, тож це доволі популярний конкурс. Тим не менш, я накладаю обмеження щодо заборони коментарів у тексті програми.


Якщо я називаю перетворену програму P * новим текстом, чи містить P ** обидва тексти чи лише останній?
Тал

Отже, мені дається код програми як вхідний при кодуванні та декодуванні?
Мартін Ендер

Як програма має на меті розрізняти запит на розшифровку кодованого повідомлення та прохання кодувати повідомлення, яке, як буває, саме кодоване повідомлення?
celtschk

2
@celtschk, судячи з позначення ОП: якщо вашій програмі надано два входи, кодуйте перший вхід на другий. якщо програмі надано лише один вхід, витягніть рядок, який останнім часом закодований у цьому вході.
Мартін Ендер

4
Чи має бути якийсь спосіб відновити P * з P **? Якщо ні, навіщо вимагати, щоб " P ** несе два повідомлення - M та M2 "? Мені дуже шкода, але хоча ця проблема виглядає цікавою, специфіка є для мене занадто заплутаною.
Ільмарі Каронен

Відповіді:


8

Perl

Це однолінійний лайнер у Perl лише тому, що це можливо.

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

Повідомлення пишуться після __DATA__, найперші спочатку.


Як щодо здорової конкуренції та єдиного самовираження?
seequ

Це досить велике значення того, що у вас там є.
Жил 'ТАК - перестань бути злим'

4

Пітон

Знаєш, що? Чому б не зробити це єдиним виразом?

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)

Старе повідомлення; Функція P приймає аргументи як зазначені та виводить отриманий код / ​​декодований текст.

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

Не впевнений, чи правильно я розумію постановку проблеми: мій декодер розшифрує будь-яку програму та поверне останнє повідомлення, кодоване в даній програмі.

Код тесту:

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

Пакетна

@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

Зауважте, що після "останнього рядка" потрібно повернути вагон goto :EOF.

Це займає два входи від stdin. Перший з них - те, що ви хочете зробити; e, або d(кодувати і декодувати). Другий вхід залежить від першого - якщо перший вхід є e, то другим входом буде повідомлення, яке ви хочете кодувати - якщо воно є d, то другим входом буде номер повідомлення, яке ви хочете розшифрувати (це буде надається після кодування повідомлення).

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

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

0

Кобра

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)

Хоча ідея є тривіальною, виконання зазначеної ідеї є менш таким.

Кодування

Кодування повідомлення в програмі додасть рядок .message = .message ? xвідразу після def main. Цей рядок перевіряє, чи .messageє нуль, і якщо так, то він встановлює .messageцілий масив, що містить значення символьних кодів кожного символу в повідомленні; нульова перевірка та позиціонування уникають перезаписування нового повідомлення старішим. Нова програма зберігається вencode.cobra

Розшифровка

Розшифровка програми додасть три рядки в кінці основного методу, які змусять програму перетворити коди char у .messageрядок, до якої потім зберігається message.txtпри запуску нової програми. Потім нова програма зберігається decode.cobraі компілятор викликається на неї.

decode.cobra використовується як тимчасовий файл і не може бути використаний для кодування або декодування іншого повідомлення, використання оригіналу або encode.cobra

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.