Convierta un programa en un programa palindrómico

15

Un palíndromo es una cadena que es igual hacia adelante y hacia atrás, como el "auto de carreras".

Escriba un programa en algún lenguaje L, que tome cualquier programa P1 en el lenguaje L como entrada, y genere un programa palindrómico P2 en el lenguaje L que haga lo mismo que P1.

No necesita preocuparse por manejar programas de entrada con errores de sintaxis.

Este es el código de golf , por lo que gana la solución con el menor número de bytes.

Peter Olson
fuente
¿Podemos definir el lenguaje L?
Greg Hewgill
1
@GregHewgill Sí. L es el idioma en el que eliges escribir tu programa.
Justin
En algunos idiomas, esto es sorprendentemente difícil.
Justin
3
Con un subconjunto Turing completo de Python, este es un valor válido x=input();print(x+'#'+x[::-1]). El subconjunto es el conjunto de todos los programas que no incluyen nuevas líneas.
Justin

Respuestas:

17

Perl, 55 54 bytes

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

Lee la fuente del programa de stdin y escribe en stdout.

Resultado de ejecutarse sobre sí mismo:

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

__END__

__DNE__

;a$esrever ralacs,a$tnirp;"n\__DNE__n\".><=a$;/$fednu
Greg Hewgill
fuente
+1 por no usar comentarios
3
Me gusta que marca el galimatías aparente en la parte inferior con "DNE", una abreviatura común de "No borrar" que se usa para marcar cosas en pizarras / pizarras blancas para que las personas no las confundan con garabatos sin importancia y las borren.
anaximander
¿Cómo funciona? No sé Perl. Más específicamente, ¿cómo funciona?
Cruncher
2
1+ Funciona en la mayoría de los casos, excepto cuando el programa termina __DATA__cuando se lee .. ej. print while(<DATA>);\n__DATA__cambiará el comportamiento.
Sylwester
1
@Sylwester: cierto. Esto funciona para el subconjunto de scripts de Perl que no se usan __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());}}

Salida en sí mismo (cuando se prettified de antemano):

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
fuente
1
Problema si el comentario termina en *. Ver comentario
edc65
10

Python 2, 68 bytes

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

No funciona si se ejecuta desde IDLE, porque necesita generar un carácter EOF para evitar que el programa espere la entrada.

Salida cuando se ejecuta en sí mismo:

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

Gracias a Greg Hewgill por ayudarnos a resolver problemas y al golf.

Justin
fuente
Buen trabajo, supera mi intento de Python un poco cojo.
Greg Hewgill
1
@GregHewgill Prefiero un buen voto a un buen comentario ;-)
Justin
1
Ok, ok ... No suelo votar en mi contra. :)
Greg Hewgill
55
@GregHewgill Yo voto "en contra de" yo mucho . Voto las respuestas en función de sus méritos, no en función de si respondí o no.
Justin
8

GolfScript, 10 9 bytes

"
}"+.-1%

Muy similar a la solución de minitech , pero funciona bien con nuevas líneas. Se basa en el comportamiento divertido (e indocumentado) de GolfScript para ignorar un elemento inigualable (y no comentado) }, así como todo lo que le sigue.

Fallará si la entrada contiene una incomparable {, pero eso técnicamente constituiría un error de sintaxis.

Cómo funciona

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

Ejemplo

$ 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
fuente
Intente 1\n2#( \nsería un carácter real de nueva línea) como su entrada.
Justin
1
@Quincunx: comentarios molestos ... Una nueva línea antes del paréntesis debería arreglar eso.
Dennis
Antes y después Necesito seguir siendo un palíndromo.
Justin
@Quincunx: Por supuesto. Debería funcionar ahora.
Dennis
5

Código de máquina x86 en DOS ( .comarchivo) - 70 bytes

Tratar con archivos .COM, crear un síndrome de palyndrome es fácil, ya que el "cargador" COM simplemente coloca el contenido del archivo en la dirección 100hy salta allí, el programa ya debe codificar su final de alguna manera e ignorar todo después de eso, así que solo podemos agregar el reverso de los primeros bytes N-1 (solo advertencia: si el programa de alguna manera intenta hacer trucos con la longitud del archivo, todo se rompe).

Aquí está el volcado hexadecimal de mi .COM-palyndromizing .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..|

Toma el archivo de entrada en la línea de comando y escribe la salida en stdout; El uso esperado es algo así compalyn source.com > out.com.

Asamblea comentada:

    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

Probado en sí mismo y las soluciones a una pregunta anterior parecen funcionar bien en DosBox, seguirán algunas pruebas más exhaustivas en ejecutables DOS "canónicos".

Matteo Italia
fuente
3

GolfScript, 8

.-1%'#'\

No maneja nuevas líneas, pero nadie las usa en GolfScript.

Ry-
fuente
66
El uso de nueva línea en literales de cadena se puede usar con bastante frecuencia ;-)
Howard
2

Bash + coreutils, 39 bytes

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

Lecturas de STDIN y salidas a STDOUT:

$ cat hello.sh 
#!/bin/bash

echo 'Hello, World!'

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

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

hsab/nib/!#
$ 
Trauma digital
fuente
@ user23013 Parece funcionar bien. Al menos una prueba simple como ( echo 'Hello, World!' ). bash prácticamente ignora todo después del exit.
Trauma digital
2

Javascript ( ES6 ) Multilínea - 71

Un poco más o menos robó el método de comentarios de Quincunx aquí:

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

Línea simple - 49

alert((x=prompt()+'/')+[...x].reverse().join(''))
nderscore
fuente
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();}}

Resultado de ejecutarse sobre sí mismo:

#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
fuente
Falla cuando se usa la continuación char '\'. Prueba [ ideone.com/TCZHr9]
edc65
@ edc65: Sí, pensé en eso más tarde. La única forma obvia en la que puedo pensar para manejar eso sería desplegar las líneas dobladas primero.
Greg Hewgill
se puede hacer a bajo costo - ver mi respuesta en C
edc65
2

Brainfuck, 749 sin espacios en blanco (sin golf)

Esto produce programas de brainfuck que reflejan palíndromos, es decir, son imágenes especulares de sí mismos.

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

Dado un programa, genera

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

con PROGRAMy MIRRORreemplazado por el programa (sin caracteres que no sean brainfuck) y su imagen especular.

caja de cartón
fuente
2

C 168 175

Maneja correctamente la nueva línea escapada dentro del código fuente

Editar 1 error corregido cuando falta la última línea nueva
Editar 2 error corregido cuando la línea dentro del comentario termina con *: agregue una pestaña antes del //comentario
(y más golf)

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 estándar, código válido, muchas advertencias

Sin golf

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
fuente
1
Hay un pequeño error en él. 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()));}}

Prueba de entrada:

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())); 
    } 
} 

Prueba de salida:

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
fuente
Creo que puede haber entendido mal una de las instrucciones. Su programa debería poder tomar cualquier programa como entrada y escribir un programa palindrómico que haga lo mismo que el programa original.
Greg Hewgill
Puede ... Si ingreso el código C ++ de su respuesta, devuelve exactamente lo que tiene.
jzm
Todo lo que hace su programa es invertir su entrada. La salida de su programa no es un programa palindrómico completo.
Greg Hewgill
Oh sí, te entiendo. Actualizado: ¿mejor ahora?
jzm
2
SIP eso es. Sin //embargo, su salida de prueba debería tener el final de cada línea ahora.
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;");
}

Uso de muestra:

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

Esto no es nada inteligente. Es solo un simple código que hace el trabajo ... Estaba de humor para jugar. ¡Sé que este código está plagado de malas prácticas de programación!

Finalmente, con mucho gusto aceptaré cualquier crítica y edición de este código.

Jefe tribal
fuente
Bienvenido a Code Golf. Esta es una función, no un programa. Vea las otras respuestas, proporcionan buenos ejemplos.
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
fuente
0

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

Sin golf (pero aún muy imperativo):

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

Salida cuando se le da la versión sin golf como entrada:

(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
fuente