Convertir un programme en programme palindromique


15

Un palindrome est une chaîne qui est la même en avant et en arrière, comme "racecar".

Écrivez un programme dans une langue L, qui prend tout programme P1 dans la langue L comme entrée, et génère un programme palindromique P2 dans la langue L qui fait la même chose que P1.

Vous n'avez pas à vous soucier de la gestion des programmes d'entrée avec des erreurs de syntaxe.

C'est le golf de code , donc la solution avec le moins d'octets gagne.


Peut-on définir le langage L?
Greg Hewgill

1
@GregHewgill Oui. L est la langue dans laquelle vous choisissez d'écrire votre programme.
Justin

Dans certaines langues, cela est étonnamment difficile.
Justin

3
Avec un sous - ensemble complet de turing Python, ceci est une entrée valide: x=input();print(x+'#'+x[::-1]). Le sous-ensemble est l'ensemble de tous les programmes qui n'incluent pas de sauts de ligne.
Justin

Réponses:


17

Perl, 55 54 octets

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

Lit la source du programme depuis stdin et écrit dans stdout.

Résultat du fonctionnement sur lui-même:

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

__END__

__DNE__

;a$esrever ralacs,a$tnirp;"n\__DNE__n\".><=a$;/$fednu

+1 pour ne pas utiliser les commentaires

3
J'aime qu'il marque le charabia apparent en bas avec "DNE" - un raccourci commun pour "Ne pas effacer" utilisé pour marquer les choses sur les tableaux noirs / blancs afin que les gens ne les confondent pas avec des gribouillages sans importance et les essuient.
anaximander

comment ça marche, je ne connais pas perl, plus précisément comment ça marche (obtenir la ligne qu'il inverse)?
Cruncher

2
1+ Fonctionne dans la plupart des cas, sauf lorsque le programme se termine par ce __DATA__qui est lu .. par exemple. print while(<DATA>);\n__DATA__va changer le comportement.
Sylwester

1
@Sylwester: Vrai. Cela fonctionne pour le sous-ensemble de scripts Perl qui n'utilisent pas __DATA__. :)
Greg Hewgill

11

Java, 225 octets

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

Sortie sur elle-même (lorsqu'elle a été préalablement optimisée):

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

1
Problème si le commentaire se terminant par *. Voir le commentaire
edc65

10

Python 2, 68 octets

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

Ne fonctionne pas si exécuté à partir de IDLE, car vous devez générer un caractère EOF pour empêcher le programme d'attendre l'entrée.

Sortie lorsqu'il est exécuté sur lui-même:

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

Merci à Greg Hewgill d'avoir aidé à résoudre les problèmes et à jouer au golf.


Beau travail, bat ma tentative un peu boiteuse de Python.
Greg Hewgill

1
@GregHewgill Je préfère un bon vote positif à un bon commentaire ;-)
Justin

1
D'accord, je ne vote généralement pas contre moi-même. :)
Greg Hewgill

5
@GregHewgill Je vote beaucoup contre moi - même . J'évalue les réponses en fonction de leurs mérites, et non selon que j'ai répondu ou non.
Justin

8

GolfScript, 10 9 octets

"
}"+.-1%

Assez similaire à la solution de minitech , mais elle fonctionne bien avec les nouvelles lignes. Il s'appuie sur le comportement drôle (et non documenté) de GolfScript pour ignorer un élément inégalé (et non commenté) }, ainsi que tout ce qui le suit.

Il échouera si l'entrée contient une valeur inégalée {, mais cela constituerait techniquement une erreur de syntaxe.

Comment ça fonctionne

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

Exemple

$ 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

Essayez 1\n2#(ce \nserait un caractère de nouvelle ligne) comme entrée.
Justin

1
@Quincunx: commentaires pesky ... Une nouvelle ligne avant le crochet devrait résoudre ce problème.
Dennis

Avant et après. Besoin de rester un palindrome.
Justin

@Quincunx: Bien sûr. Ça devrait marcher maintenant.
Dennis

5

code machine x86 sous DOS ( .comfichier) - 70 octets

Gérer les fichiers .COM, créer un palyndrome est facile - puisque le "chargeur" ​​COM met simplement le contenu du fichier à l'adresse 100h et y saute, le programme doit déjà coder en dur sa fin en quelque sorte et ignorer tout ce qui se trouve après, donc nous pouvons simplement ajouter l'inverse des N-1 premiers octets (seule mise en garde: si le programme essaie en quelque sorte de faire des tours avec la longueur du fichier, tout se casse).

Voici le vidage hexadécimal de mon .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..|

Il prend le fichier d'entrée sur la ligne de commande et écrit la sortie sur stdout; l'utilisation attendue est quelque chose commecompalyn source.com > out.com .

Montage commenté:

    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

Testé sur lui-même et les solutions à une question précédente semblent bien fonctionner dans DosBox, quelques tests plus approfondis sur les exécutables DOS "canoniques" suivront.


3

GolfScript, 8

.-1%'#'\

Ne gère pas les sauts de ligne, mais personne ne les utilise dans GolfScript.


6
L'utilisation de la nouvelle ligne dans les littéraux de chaîne peut être utilisée assez souvent ;-)
Howard

2

Bash + coreutils, 39 octets

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

Lit depuis STDIN et sort vers 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/!#
$ 

@ user23013 Semble fonctionner correctement. Au moins un test simple comme ( echo 'Hello, World!' ). bash ignore à peu près tout après le exit.
Digital Trauma

2

Javascript ( ES6 ) multiligne - 71

Sorta sorta volé la méthode de commentaire de Quincunx ici:

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

Ligne unique - 49

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

2

C ++, 214 209 octets

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

Résultat du fonctionnement sur lui-même:

#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#

Échec lorsque le caractère de continuation '\' est utilisé. Essayez [ ideone.com/TCZHr9]
edc65

@ edc65: Oui, j'y ai pensé plus tard. La seule façon évidente de penser à cela serait de déplier les lignes pliées en premier.
Greg Hewgill

peut être fait à peu de frais - voir ma réponse C
edc65

2

Brainfuck, 749 sans espace (pas de golf)

Cela produit des programmes de brainfuck qui reflétaient des palindromes, c'est-à-dire qu'ils sont des images miroir d'eux-mêmes.

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

Étant donné un programme qu'il génère

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

avec PROGRAMet MIRRORremplacé par le programme (sans personnages non-brainfuck) et son image miroir.


2

C 168 175

Gère correctement la nouvelle ligne échappée dans le code source

Modifier 1 bug fixe lorsque la dernière nouvelle ligne est manquante
Modifier 2 bug fixe lorsque la ligne à l'intérieur du commentaire se termine par *: ajoutez un caractère de tabulation avant le //commentaire
(et jouez plus)

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, code valide, nombreux avertissements

Non 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
}

1
il y a un petit bug dedans. 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()));}}

Entrée de test:

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

Sortie de test:

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

Je pense que vous avez peut-être mal compris l'une des instructions. Votre programme devrait être capable de prendre n'importe quel programme en entrée et d'écrire un programme palindromique qui fait la même chose que le programme d'origine.
Greg Hewgill

Il peut .. Si j'entre le code C ++ de votre réponse, il renvoie exactement ce que vous avez.
jzm

Tout ce que fait votre programme, c'est inverser sa saisie. La sortie de votre programme n'est pas un programme palindromique complet.
Greg Hewgill

Oh ouais, je te comprends. Mis à jour - mieux maintenant?
jzm

2
Ouais, c'est tout. //Cependant, votre sortie de test devrait avoir la fin de chaque ligne.
Greg Hewgill

0

PHP, 96 octets

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

Exemple d'utilisation:

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

Ce n'est rien d'intelligent. C'est juste un simple morceau de code qui fait le travail ... J'étais d'humeur à jouer. Je sais que ce code regorge de mauvaises pratiques de programmation!

Enfin, j'accepterai volontiers toute critique et modification de ce code!


Bienvenue chez Code Golf. C'est une fonction, pas un programme. Voir les autres réponses, elles fournissent de bons exemples.
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#/'

0

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

Non golfé (mais toujours très impératif):

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

Sortie lorsque la version non golfée est entrée:

(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(
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.