Konvertieren Sie ein Programm in ein palindromisches Programm

15

Ein Palindrom ist eine Zeichenfolge, die vorwärts und rückwärts gleich ist, z. B. "Rennwagen".

Schreiben Sie ein Programm in einer Sprache L, das ein beliebiges Programm P1 in Sprache L als Eingabe verwendet, und geben Sie ein palindromes Programm P2 in Sprache L aus, das dasselbe wie P1 ausführt.

Sie müssen sich nicht um die Behandlung von Eingabeprogrammen mit Syntaxfehlern kümmern.

Dies ist Codegolf , daher gewinnt die Lösung mit der geringsten Anzahl von Bytes.

Peter Olson
quelle
Können wir die Sprache L definieren?
Greg Hewgill
1
@ GregHewgill Ja. L ist die Sprache, in der Sie Ihr Programm schreiben möchten.
Justin
In einigen Sprachen ist dies überraschend schwierig.
Justin
3
Mit einer Turing kompletten Teilmenge von Python, ist dies ein gültiger Eintrag: x=input();print(x+'#'+x[::-1]). Die Untermenge ist die Menge aller Programme, die keine Zeilenumbrüche enthalten.
Justin

Antworten:

17

Perl, 55 54 Bytes

undef$/;$a=<>."\n__END__\n";print$a,scalar reverse$a;

Liest die Programmquelle von stdin und schreibt nach stdout.

Ergebnis des Laufens auf sich selbst:

undef$/;$a=<>."\n__END__\n";print$a,scalar reverse$a;

__END__

__DNE__

;a$esrever ralacs,a$tnirp;"n\__DNE__n\".><=a$;/$fednu
Greg Hewgill
quelle
+1 für die
3
Ich finde es gut, dass es den offensichtlichen Kauderwelsch am unteren Rand mit "DNE" markiert - eine gebräuchliche Abkürzung für "Do Not Erase" (Nicht löschen), mit der Dinge auf Kreidetafeln / Whiteboards markiert werden, damit die Leute sie nicht für unwichtige Kritzeleien halten und sie abwischen.
Anaximander
Wie funktioniert es, ich weiß nicht, Perl, genauer gesagt, wie quiniert es (erhalte die Zeile, die es umkehrt)?
Cruncher
2
1+ Funktioniert in den meisten Fällen, außer wenn das Programm damit endet __DATA__. print while(<DATA>);\n__DATA__wird das Verhalten ändern.
Sylwester
1
@ Sylwester: Stimmt. Dies funktioniert für die Teilmenge von Perl-Skripten, die nicht verwendet werden __DATA__. :)
Greg Hewgill
11

Java, 225 Bytes

class c{public static void main(String[]a){String s="";java.util.Scanner r=new java.util.Scanner(System.in);while(r.hasNext())s+=r.nextLine()+"\n";s=s.replace("\n","//\n");System.out.print(s+new StringBuilder(s).reverse());}}

Ausgabe auf sich selbst (wenn vorher verschönert):

class c {//
    public static void main(String[] a) {//
        String s = "";//
        java.util.Scanner r = new java.util.Scanner(System.in);//
        while (r.hasNext()) s += r.nextLine() + "\n";//
        s = s.replace("\n", "//\n");//
        System.out.print(s + new StringBuilder(s).reverse());//
    }//
}//

//}
//}
//;))(esrever.)s(redliuBgnirtS wen + s(tnirp.tuo.metsyS        
//;)"n\//" ,"n\"(ecalper.s = s        
//;"n\" + )(eniLtxen.r =+ s ))(txeNsah.r( elihw        
//;)ni.metsyS(rennacS.litu.avaj wen = r rennacS.litu.avaj        
//;"" = s gnirtS        
//{ )a ][gnirtS(niam diov citats cilbup    
//{ c ssalc
Justin
quelle
1
Problem, wenn der Kommentar mit * endet. Siehe Kommentar
edc65
10

Python 2, 68 Bytes

import sys
x=''.join(l[:-1]+'#\n'for l in sys.stdin)
print x+x[::-1]

Funktioniert nicht, wenn IDLE ausgeführt wird, da Sie ein EOF-Zeichen generieren müssen, um zu verhindern, dass das Programm auf Eingaben wartet.

Ausgabe, wenn auf sich selbst ausgeführt:

import sys#
x=''.join(l[:-1]+'#\n'for l in sys.stdin)#
print(x+x[::-1])#

#)]1-::[x+x(tnirp
#)nidts.sys ni l rof'n\#'+]1-:[l(nioj.''=x
#sys tropmi

Vielen Dank an Greg Hewgill, der geholfen hat, Probleme zu lösen und Golf zu spielen.

Justin
quelle
Netter Job, schlägt meinen irgendwie lahmen Python-Versuch.
Greg Hewgill
1
@ GregHewgill Ich bevorzuge eine nette Aufwertung zu einem schönen Kommentar ;-)
Justin
1
Ok okay ... Ich stimme normalerweise nicht gegen mich. :)
Greg Hewgill
5
@ GregHewgill Ich stimme viel gegen mich . Ich habe Antworten nach ihren Vorzügen bewertet, nicht danach, ob ich geantwortet habe oder nicht.
Justin
8

GolfScript, 10 9 Bytes

"
}"+.-1%

Ähnlich wie die Minitech-Lösung , funktioniert aber gut mit Zeilenumbrüchen. Es beruht auf dem lustigen (undokumentierten) Verhalten von GolfScript, um ein nicht übereinstimmendes (und nicht kommentiertes) }sowie alles, was darauf folgt, zu ignorieren .

Es wird fehlschlagen, wenn die Eingabe eine nicht übereinstimmende enthält {, aber dies würde technisch einen Syntaxfehler darstellen.

Wie es funktioniert

"
}"   # Push the string "\n}".
+    # Concatenate it with the input string.
.    # Duplicate the modified string.
-1%  # Reverse the copy.

Beispiel

$ echo -n '1{"race{car"}
> {"foo\"bar"}
> if#' | golfscript make-palindrome.gs
1{"race{car"}
{"foo\"bar"}
if#
}}
#fi
}"rab"\oof"{
}"rac{ecar"{1
$ echo '1{"race{car"}
> {"foo\"bar"}
> if#
> }}
> #fi
> }"rab"\oof"{
> }"rac{ecar"{1' | golfscript
race{car
Dennis
quelle
Versuchen Sie 1\n2#( \nwäre ein tatsächliches Newline-Zeichen) als Eingabe.
Justin
1
@Quincunx: Lästige Kommentare ... Eine neue Zeile vor der geschweiften Klammer sollte das beheben.
Dennis
Vorher und nachher. Muss ein Palindrom bleiben.
Justin
@ Quincunx: Natürlich. Es sollte jetzt funktionieren.
Dennis
5

x86-Maschinencode unter DOS ( .comDatei) - 70 Byte

Mit .COM-Dateien umzugehen und ein Palyndrom zu erstellen ist einfach - da der COM-"Loader" den Inhalt der Datei nur an die Adresse legt 100hund dorthin springt, muss das Programm sein Ende bereits fest codieren und alles danach ignorieren, damit wir es einfach anhängen können die Umkehrung der ersten N-1 Bytes (nur Vorbehalt: wenn das Programm irgendwie versucht, Tricks mit der Länge der Datei zu machen, bricht alles zusammen).

Hier ist der Hex-Dump meiner .COM-Palyndromisierung .COM:

00000000  31 db 8a 1e 80 00 c6 87  81 00 00 ba 82 00 b8 00  |1...............|
00000010  3d cd 21 72 30 89 c6 bf  ff ff b9 01 00 ba fe 00  |=.!r0...........|
00000020  89 f3 b4 3f cd 21 3c 01  75 18 b4 40 bb 01 00 cd  |...?.!<.u..@....|
00000030  21 85 ff 75 e5 89 f3 f7  d9 88 ee b8 01 42 cd 21  |!..u.........B.!|
00000040  eb d8 47 74 f0 c3                                 |..Gt..|

Es nimmt die Eingabedatei in die Befehlszeile und schreibt die Ausgabe auf stdout. die erwartete nutzung ist so etwas wie compalyn source.com > out.com.

Kommentierte Versammlung:

    org 100h

section .text

start:
    ; NUL-terminate the command line
    xor bx,bx
    mov bl, byte[80h]
    mov byte[81h+bx],0
    ; open the input file
    mov dx,82h
    mov ax,3d00h
    int 21h
    ; in case of error (missing file, etc.) quit
    jc end
    ; si: source file handle
    mov si,ax
    ; di: iteration flag
    ; -1 => straight pass, 0 reverse pass
    mov di,-1
loop:
    ; we read one byte at time at a bizarre memory
    ; location (so that dl is already at -2 later - we shave one byte)
    mov cx,1
    mov dx,0feh
    mov bx,si
    mov ah,3fh
    int 21h
    ; if we didn't read 1 byte it means we either got to EOF
    ; or sought before the start of file
    cmp al,1
    jne out
    ; write the byte on stdout
    mov ah,40h
    mov bx,1
    int 21h
    ; if we are at the first pass we go on normally
    test di,di
    jnz loop
back:
    ; otherwise, we have to seek back
    mov bx,si
    ; one byte shorter than mov cx,-1
    neg cx
    ; dl is already at -2, fix dh so cx:dx = -2
    mov dh,ch
    mov ax,4201h
    int 21h
    jmp loop
out:
    ; next iteration
    inc di
    ; if it's not zero we already did the reverse pass
    jz back
end:
    ret

Auf sich selbst getestet und die Lösungen für eine vorherige Frage scheinen in DosBox gut zu funktionieren, einige ausführlichere Tests auf "kanonischen" DOS-ausführbaren Dateien werden folgen.

Matteo Italia
quelle
3

GolfScript, 8

.-1%'#'\

Behandelt keine Zeilenumbrüche, aber niemand verwendet diese in GolfScript.

Ry-
quelle
6
Die Verwendung von Newline in String-Literalen kann recht häufig verwendet werden ;-)
Howard
2

Bash + Coreutils, 39 Bytes

f="`cat`
exit"
echo "$f"
tac<<<"$f"|rev

Liest von STDIN und gibt an STDOUT aus:

$ cat hello.sh 
#!/bin/bash

echo 'Hello, World!'

$ ./palin.sh < hello.sh 
#!/bin/bash

echo 'Hello, World!'
exit
tixe
'!dlroW ,olleH' ohce

hsab/nib/!#
$ 
Digitales Trauma
quelle
@ user23013 Scheint gut zu funktionieren. Zumindest ein einfacher Test wie ( echo 'Hello, World!' ). Bash ignoriert so ziemlich alles nach dem exit.
Digital Trauma
2

Javascript ( ES6 ) Mehrzeilig - 71

Irgendwie hat Quincunx die Kommentarmethode hier gestohlen :

alert((x=prompt().replace(/\n/g,'//\n')+'/')+[...x].reverse().join(''))

Einzeilig - 49

alert((x=prompt()+'/')+[...x].reverse().join(''))
nderscore
quelle
2

C ++ 214 209 Bytes

#include<cstdio>
#include<stack>
int main(){std::stack<char>s;int c;while((c=getc(stdin))>EOF){if(c=='\n')for(int i=2;i;i--)s.push(putchar('/'));s.push(putchar(c));}while(s.size()){putchar(s.top());s.pop();}}

Ergebnis des Laufens auf sich selbst:

#include<cstdio>//
#include<stack>//
int main(){std::stack<char>s;int c;while((c=getc(stdin))>EOF){if(c=='\n')for(int i=2;i;i--)s.push(putchar('/'));s.push(putchar(c));}while(s.size()){putchar(s.top());s.pop();}}//

//}};)(pop.s;))(pot.s(rahctup{))(ezis.s(elihw};))c(rahctup(hsup.s;))'/'(rahctup(hsup.s)--i;i;2=i tni(rof)'n\'==c(fi{)FOE>))nidts(cteg=c((elihw;c tni;s>rahc<kcats::dts{)(niam tni
//>kcats<edulcni#
//>oidtsc<edulcni#
Greg Hewgill
quelle
Fehler, wenn das Fortsetzungszeichen '\' verwendet wird. Versuchen Sie [ ideone.com/TCZHr9]
edc65
@ edc65: Ja, darüber habe ich später nachgedacht. Die einzige naheliegende Möglichkeit, dies zu handhaben, besteht darin, die gefalteten Linien zuerst zu entfalten.
Greg Hewgill
kann zu kleinen Kosten erledigt werden
siehe
2

Brainfuck, 749 ohne Leerzeichen (nicht golfen)

Dies erzeugt Brainfuck-Programme, die Palindrome spiegeln, dh sie sind Spiegelbilder von sich.

++++++++++
[->++++>+++++++++<<]>+++.>+..<.>++.
>>>>+[>,]<-[+<-]
>[
  [-<+<<+>>>]
  +<-------------------------------------------[-<+>>[-]<]>[-<<<.>>>]
  +<<-[->+>[-]<<]>>[-<<<.>>>]
  +<-[-<+>>[-]<]>[-<<<.>>>]
  +<<-[->+>[-]<<]>>[-<<<.>>>]
  +<--------------[-<+>>[-]<]>[-<<<.>>>]
  +<<--[->+>[-]<<]>>[-<<<.>>>]
  +<-----------------------------[-<+>>[-]<]>[-<<<.>>>]
  +<<--[->+>[-]<<]>>[-<<<.>>>]
  <[-]>>
]
<<<<[<]
<--.<.>++..--..<.>++.
>>[>]
<[
  [->+>>+<<<]
  +>-------------------------------------------[->+<<[-]>]<[->>>.<<<]
  +>>-[-<+<[-]>>]<<[->>>.<<<]
  +>-[->+<<[-]>]<[->>>.<<<]
  +>>-[-<+<[-]>>]<<[->>>.<<<]
  +>--------------[->+<<[-]>]<[->>>++.--<<<]
  +>>--[-<+<[-]>>]<<[->>>--.++<<<]
  +>-----------------------------[->+<<[-]>]<[->>>++.--<<<]
  +>>--[-<+<[-]>>]<<[->>>--.++<<<]
  >[-]<<
]
<--.<.>++..<.

Ein gegebenes Programm gibt es aus

+[[+]PROGRAM[+]][[+]MIRROR[+]]+

mit PROGRAMund MIRRORersetzt durch das Programm (ohne Nicht-Brainfuck-Zeichen) und dessen Spiegelbild.

Pappschachtel
quelle
2

C 168 175

Behandelt maskierte Zeilenumbrüche im Quellcode korrekt

1 Fehler behoben, wenn die letzte Zeile fehlt
2 Fehler behoben, wenn die Zeile innerhalb des Kommentars endet mit *: vor dem //Kommentar ein Tabulatorzeichen
einfügen

b[999999];main(c,z){char*p,for(p=b;(*p=c=getchar())>=0;z=c,p++)c-10||(z-92?*p++=9,*p++=47,*p++=47,*p=c:(p-=2));*p=47;for(p=b;*p;)putchar(*p++);for(;p>b;)putchar(*--p);}

C99 Standard, gültiger Code, viele Warnungen

Ungolfed

b[999999]; // working buffer ~ 4M on 32 bit machine, max source size
// c is current char, z is previous char,
main(c,z) // z  start as argv pointer, will be out of char range
{
  char *p;
  for(p = b; 
      (*p=c=getchar()) >= 0; // while testing EOF copy char to buffer set c variable
      z=c, p++) // at end loop increment p and set previous = current
  {
      c-'\n' || // if newline 
       (z - '\\' // check if escaped
          ? *p++='\t',*p++='/',*p++='/', *p=c // if not escaped, add tab,/,/ and newline
          : (p-=2) // if escaped, drop both escape and newline
       ); 
  }
  *p='/'; // if last newline missing, will add a comment anyway
  for(p=b;*p;) putchar(*p++); // ouput buffer 
  for(;--p>=b;) putchar(*p); // outbut buffer reversed
}
edc65
quelle
1
da ist ein kleiner Fehler drin. try/* *<NL> */int main(){}
jimmy23013
1

C # - 174

using System;using System.Linq;class c{public static void Main(){var a="";var b="";while((a=Console.ReadLine())!="")b+=a+"//\n";Console.Write(b+string.Concat(b.Reverse()));}}

Testeingang:

using System; 
using System.Linq; 
class c 
{ 
    public static void Main() 
    { 
        var a = ""; 
        var b = ""; 
        while ((a = Console.ReadLine()) != "") 
            b += a + "//\n"; 
        Console.Write(b+string.Concat(b.Reverse())); 
    } 
} 

Testausgang:

using System; 
using System.Linq; 
class c 
{ 
    public static void Main() 
    { 
        var a = ""; 
        var b = ""; 
        while ((a = Console.ReadLine()) != "") 
            b += a + "//\n"; 
        Console.Write(b+string.Concat(b.Reverse())); 
    } 
} 

// }
// }
// ;)))(esreveR.b(tacnoC.gnirts+b(etirW.elosnoC
// ;"n\//" + a =+ b
// )"" =! ))(eniLdaeR.elosnoC = a(( elihw
// ;"" = b rav
// ;"" = a rav
// {
// )(niaM diov citats cilbup
// {
// c ssalc
// ;qniL.metsyS gnisu
// ;metsyS gnisu
jzm
quelle
Ich denke, Sie haben möglicherweise eine der Anweisungen falsch verstanden. Ihr Programm sollte in der Lage sein, jedes Programm als Eingabe zu verwenden und ein palindromisches Programm zu schreiben, das das Gleiche wie das ursprüngliche Programm ausführt.
Greg Hewgill
Es kann ... Wenn ich den C ++ - Code aus Ihrer Antwort eingebe, gibt es genau das zurück, was Sie haben.
JZM
Alles, was Ihr Programm tut, ist die Eingabe umzukehren. Die Ausgabe Ihres Programms ist kein vollständiges palindromisches Programm.
Greg Hewgill
Oh ja, ich verstehe. Aktualisiert - jetzt besser?
JZM
2
Ja, das ist es. Ihre Testausgabe sollte jetzt jedoch //am Ende jeder Zeile stehen.
Greg Hewgill
0

PHP, 96 Bytes

function a($b){
    echo $c = "a('$b')" . strrev("a)'" . $b . "'(");
    $d = substr($c, 0, strlen($b) + 5);
    eval("$d;");
}

Beispielnutzung:

a('apple'); // echoes a('apple')('elppa')a until your bytes get exhausted

Das ist nichts Schlaues. Es ist nur ein einfaches Stück Code, das den Job macht ... Ich hatte Lust zu spielen. Ich weiß, dass dieser Code mit schlechten Programmierpraktiken weit verbreitet ist!

Zum Schluss nehme ich gerne Kritik und Änderungen an diesem Code entgegen!

Stammesführer
quelle
Willkommen bei Code Golf. Dies ist eine Funktion, kein Programm. Siehe die anderen Antworten, sie liefern gute Beispiele.
AL
0

Cobra - 134

class P
    def main
        i=List<of String?>(Console.readLine.split('\n'))
        print '/#\n[i.reversed.join("\n")]\n#/#\n[i.join("\n")]\n#/'
Οurous
quelle
0

Schläger 133

(require srfi/13)(let((r read-line)(w display))(let l((i(r)))(when
(not(eq? eof i))(w i)(w";\n")(l(r))(w"\n;")(w(string-reverse i)))))

Ungolfed (aber immer noch sehr wichtig):

(require srfi/13)
(let recurse ((instr (read-line)))
  (when (not (eof-object? instr))
    (display instr)
    (display ";\n")
    (recurse (read-line))
    (display "\n;")
    (display (string-reverse instr))))

Ausgabe bei Angabe der ungolfed version als Eingabe:

(require srfi/13);
(let recurse ((instr (read-line)));
  (when (not(eof-object? instr));
    (display instr);
    (display ";\n");
    (recurse (read-line));
    (display "\n;");
    (display (string-reverse instr))));

;))))rtsni esrever-gnirts( yalpsid(    
;)";n\" yalpsid(    
;))enil-daer( esrucer(    
;)"n\;" yalpsid(    
;)rtsni yalpsid(    
;))rtsni ?tcejbo-foe(ton( nehw(  
;)))enil-daer( rtsni(( esrucer tel(
;)31/ifrs eriuqer(
Sylwester
quelle