Pull to refresh

С днем программиста !! атсиммаргорп менд С (Квайн-палиндром)

Reading time 6 min
Views 13K
Я тоже присоединяюсь к поздравлениям в честь дня программиста! И делаю это с помощью квайна-палиндрома.

Читая пост о мультиквайногенераторах и другие посты о квайнах в последнее время, мне захотелось сделать тоже что-нибудь интересное и нестандартное в области квайнов. Думать долго не пришлось, поскольку идея квайнов-палиндромов лежит на поверхности.

Квайн

Итак, чтобы понять что мне нужно, я сразу решил взять готовый квайн на википедии и попробовать его модифицировать.

Палиндром

Сразу написать квайн-палиндром для меня оказалось тяжело. Поэтому я решил начать с обычной программы-палиндрома. Но как написать программу так, чтобы чтобы она правильно исполнялась и при реверсе исходников, ведь получится некомпилируемый набор символов? Сразу приходит в голову, что можно комментировать весь этот мусор. Так как в C# два вида комментариев (однострочные и многострочные), то и программы были написаны соответствующие:

Однострочные комментарии
//}}{)(niaM diov citats{P ssalc
class P{static void Main(){}}//


Многострочные комментарии
/**/class P{static void Main(){}};/*/;}}{)(niaM diov citats{P ssalc/**/

Второй вариант лучше, поскольку он не зависит от того, есть ли разрыв строки или нет. До него я не сразу додумался. Однако потом удалось нагуглить программы-палиндромы на разных языках на stackoverflow.

Утилиты для проверки программ

Поскольку реверсить код для комментариев процесс довольно нудный и может сопровождаться ошибками, то перед написанием квайна-палиндрома были написаны методы для проверки строк на палиндромность и, что более интересно, методы для проверки того, может ли входная строка компилироваться. Если да, то является ли скомпилированная программа квайном? Выглядит это примерно так:
Компиляция программы из строчки во время выполнения
public static CheckingResult CompileAndGetOutput(string program)
{
    CompilerResults compilerResults = null;
    using (CSharpCodeProvider provider = new CSharpCodeProvider())
    {
        compilerResults = provider.CompileAssemblyFromSource(new CompilerParameters(new string[]
		{
			"System.dll"
		})
        {
            GenerateExecutable = true
        }, new string[]
		{
			program
		});
    }
    CheckingResult result;
    if (compilerResults.Errors.HasErrors)
    {
        result.FirstErrorLine = compilerResults.Errors[0].Line;
        result.FirstErrorColumn = compilerResults.Errors[0].Column;
        result.Output = null;
    }
    else
    {
        try
        {
            Process process = Process.Start(new ProcessStartInfo(compilerResults.PathToAssembly)
            {
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardInput = true,
                RedirectStandardOutput = true
            });
            process.StandardInput.WriteLine(Environment.NewLine);
            process.WaitForExit();
            string output = process.StandardOutput.ReadToEnd();
            try
            {
                File.Delete(compilerResults.PathToAssembly);
            }
            catch
            {
            }
            result.FirstErrorLine = -1;
            result.FirstErrorColumn = -1;
            result.Output = output;
        }
        catch
        {
            result.FirstErrorLine = 0;
            result.FirstErrorColumn = 0;
            result.Output = null;
        }
    }
    return result;
}



Квайн-Палиндром

Результат после нескольких попыток минификации получились следующими. (Программы писались в виде половинок и с форматированием для удобства написания. После этого пробелы убирались и добавлялась недостающая часть в виде комментариев в начало или конец.)

Квайн-палиндром с использованием однострочных комментариев:
//}};)s+"r\n\r\"+)c(gnirts wen(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'\\','"',s,s(tamroF.gnirts=s;"//}}}};)s+}1{r}2{n}2{r}2{}1{+)c(gnirts wen(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'}2{}2{','}1{',s,s(tamroF.gnirts=s;}1{}0{}1{=s rav{{)(niaM diov citats{{P ssalc;metsyS gnisu"=s rav{)(niaM diov citats{P ssalc;metsyS gnisu
using System;class P{static void Main(){var s="using System;class P{{static void Main(){{var s={1}{0}{1};s=string.Format(s,s,'{1}','{2}{2}');var c=s.ToCharArray();Array.Reverse(c);Console.Write(new string(c)+{1}{2}r{2}n{2}r{1}+s);}}}}//";s=string.Format(s,s,'"','\\');var c=s.ToCharArray();Array.Reverse(c);Console.Write(new string(c)+"\r\n\r"+s);}}//


Квайн-палиндром с использованием многострочных комментариев:
/*С днем программиста!*/using System;class P{static void Main(){var s="{2}*С днем программиста!*/using System;class P{{static void Main(){{var s={1}{0}{1};s=string.Format(s,s,'{1}','{2}');var c=s.ToCharArray();Array.Reverse(c);Console.Write(s+'*'+new string(c));}}}}/";s=string.Format(s,s,'"','/');var c=s.ToCharArray();Array.Reverse(c);Console.Write(s+'*'+new string(c));}}/*/}};))c(gnirts wen+'*'+s(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'/','"',s,s(tamroF.gnirts=s;"/}}}};))c(gnirts wen+'*'+s(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'}2{','}1{',s,s(tamroF.gnirts=s;}1{}0{}1{=s rav{{)(niaM diov citats{{P ssalc;metsyS gnisu/*!атсиммаргорп менд С*}2{"=s rav{)(niaM diov citats{P ssalc;metsyS gnisu/*!атсиммаргорп менд С*/


По данной тематике удалось найти лишь одну дельную ссылку на квайн-палиндромы. Однако там не оказалось решения на C#.

Ссылка на проект на github: (в будущем коллекция будет пополняться): Freaky-Sources

Кидайте в комментарии квайны-палиндромы на других языках, а также просто палиндромы в честь дня атсиммаргорп или 31 уцинтяп или все вместе :)

Желаю меньше багов, больше интересных идей и просто хорошей пятницы в этот чудесный день!

Скрытый текст
! ьнед йынседуч тотэ в ыцинтяп йешорох отсорп и йеди хынсеретни ешьлоб, вогаб ешьнем юалеЖ

): етсемв есв или пятницу 13 или программиста янд ьтсеч в ыморднилап отсорп ежкат а, хакызя хигурд ан ыморднилап-ынйавк ииратнеммок в етйадиК

secruoS-ykaerF :)ясьтянлопоп тедуб яицкеллок мещудуб в( :buhtig ан ткеорп ан аклысС

.#C ан яинешер ьсолазако ен мат окандО.ыморднилап-нйавк ан уклысс юуньлед ундо ьшил итйан ьсоладу екитамет йоннад оП

/*С днем программиста!*/using System;class P{static void Main(){var s="{2}*С днем программиста!*/using System;class P{{static void Main(){{var s={1}{0}{1};s=string.Format(s,s,'{1}','{2}');var c=s.ToCharArray();Array.Reverse©;Console.Write(s+'*'+new string©);}}}}/";s=string.Format(s,s,'"','/');var c=s.ToCharArray();Array.Reverse©;Console.Write(s+'*'+new string©);}}/*/}};))c(gnirts wen+'*'+s(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'/','"',s,s(tamroF.gnirts=s;"/}}}};))c(gnirts wen+'*'+s(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'}2{','}1{',s,s(tamroF.gnirts=s;}1{}0{}1{=s rav{{)(niaM diov citats{{P ssalc;metsyS gnisu/*! атсиммаргорп менд С*}2{"=s rav{)(niaM diov citats{P ssalc;metsyS gnisu/*! атсиммаргорп менд С*/

: веиратнеммок хынчортсогонм меинавозьлопси с морднилап-нйавК

//}};)s+«r\n\r\»+)c(gnirts wen(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'\\','"',s,s(tamroF.gnirts=s;"//}}}};)s+}1{r}2{n}2{r}2{}1{+)c(gnirts wen(etirW.elosnoC;)c(esreveR.yarrA;)(yarrArahCoT.s=c rav;)'}2{}2{','}1{',s,s(tamroF.gnirts=s;}1{}0{}1{=s rav{{)(niaM diov citats{{P ssalc;metsyS gnisu"=s rav{)(niaM diov citats{P ssalc;metsyS gnisu

using System;class P{static void Main(){var s=«using System;class P{{static void Main(){{var s={1}{0}{1};s=string.Format(s,s,'{1}','{2}{2}');var c=s.ToCharArray();Array.Reverse©;Console.Write(new string©+{1}{2}r{2}n{2}r{1}+s);}}}}//»;s=string.Format(s,s,'"','\\');var c=s.ToCharArray();Array.Reverse©;Console.Write(new string©+"\r\n\r"+s);}}//

: веиратнеммок хынчортсондо меинавозьлопси с морднилап-нйавК

).ценок или олачан в веиратнеммок едив в ьтсач яащюатсоден ьсалялвабод и ьсиларибу ылеборп оготэ елсоП.яинасипан автсбоду ялд меинаворитамроф с и кониволоп едив в ьсиласип ыммаргорП(.имищюуделс ьсиличулоп иицакифиним котыпоп хикьлоксен елсоп татьлузеР

морднилаП-нйавК

яиненлопыв ямерв ов икчортс зи ыммаргорп яицялипмоК

: кат онремирп отэ тидялгыВ? монйавк аммаргорп яаннаворилипмокс ил ястеялвя от, ад илсЕ.ясьтаворилипмок акортс яандохв ил тежом, огот икреворп ялд ыдотем, онсеретни еелоб отч, и ьтсонморднилап ан кортс икреворп ялд ыдотем ынасипан илыб аморднилап-анйавк меинасипан дереп от, имакбишо ясьтаджоворпос тежом и йындун оньловод ссецорп веиратнеммок ялд док ьтисревер укьлоксоП

ммаргорп икреворп ялд ытилитУ

.wolfrevokcats ан хакызя хынзар ан ыморднилап-ыммаргорп ьтилгуган ьсоладу мотоп окандО.ясламудод узарс ен я оген оД.тен или икортс вырзар ил ьтсе, огот то тисиваз ен но укьлоксоп, ешчул тнаирав йоротВ

/**/class P{static void Main(){}};/*/;}}{)(niaM diov citats{P ssalc/**/

ииратнеммок еынчортсогонМ

//}}{)(niaM diov citats{P ssalc

class P{static void Main(){}}//

ииратнеммок еынчортсондО

: еищюувтстевтоос ынасипан илыб ыммаргорп и от ,)еынчортсогонм и еынчортсондо( веиратнеммок адив авд #C в как каТ.росум тотэ ьсев ьтаворитнеммок онжом отч, уволог в тидохирп узарС? воловмис робан йымеурилипмокен ясьтичулоп ьдев, вокиндохси есревер ирп и ьсалянлопси оньливарп ано ыботч ыботч, кат уммаргорп ьтасипан как оН.аморднилап-ыммаргорп йончыбо с ьтачан лишер я умотэоП.олежят ьсолазако янем ялд морднилап-нйавк ьтасипан узарС

морднилаП

.ьтаворицифидом оге ьтавоборпоп и иидепикив ан нйавк йывотог ьтязв лишер узарс я, онжун енм отч ьтяноп ыботч, катИ

нйавК

.итсонхревоп ан тижел воморднилап-вонйавк яеди укьлоксоп, ьсолширп ен оглод ьтамуД.вонйавк итсалбо в еонтраднатсен и еонсеретни ьдубин-отч ежот ьталедс ьсолетохаз енм, ямерв еенделсоп в ханйавк о ытсоп еигурд и харотаренегонйавкитьлум о тсоп яатиЧ

.аморднилап-анйавк юьщомоп с отэ юалед И! атсиммаргорп янд ьтсеч в мяинелвардзоп к ьсюянидеосирп ежот Я
Tags:
Hubs:
+34
Comments 24
Comments Comments 24

Articles