Konversikan suatu program menjadi program palindromik

15

Sebuah palindrom adalah string yang adalah maju dan mundur yang sama, seperti "mobil balap".

Tulis sebuah program dalam beberapa bahasa L, yang mengambil program P1 apa pun dalam bahasa L sebagai input, dan mengeluarkan program palindromic P2 dalam bahasa L yang melakukan hal yang sama seperti P1.

Anda tidak perlu khawatir menangani program input dengan kesalahan sintaksis.

Ini adalah kode golf , jadi solusi dengan jumlah byte paling sedikit menang.

Peter Olson
sumber
Bisakah kita mendefinisikan bahasa L?
Greg Hewgill
1
@GregHewgill Ya. L adalah bahasa yang Anda pilih untuk menulis program Anda.
Justin
Dalam beberapa bahasa, ini sangat sulit.
Justin
3
Dengan subset lengkap turing dari Python, ini adalah entri yang valid: x=input();print(x+'#'+x[::-1]). Subset adalah himpunan semua program yang tidak termasuk baris baru.
Justin

Jawaban:

17

Perl, 55 54 byte

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

Membaca sumber program dari stdin dan menulis ke stdout.

Hasil menjalankannya sendiri:

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

__END__

__DNE__

;a$esrever ralacs,a$tnirp;"n\__DNE__n\".><=a$;/$fednu
Greg Hewgill
sumber
+1 karena tidak menggunakan komentar
3
Saya suka itu menandai omong kosong yang tampak di bagian bawah dengan "DNE" - singkatan untuk "Do Not Erase" yang digunakan untuk menandai sesuatu di papan tulis / papan tulis sehingga orang tidak mengira mereka melakukan coretan yang tidak penting dan menghapusnya.
anaximander
bagaimana cara kerjanya, saya tidak tahu perl, lebih khusus bagaimana quine (dapatkan garis bahwa itu terbalik)?
Cruncher
2
1+ Bekerja dalam banyak kasus kecuali ketika program berakhir dengan __DATA__yang dibaca .. mis. print while(<DATA>);\n__DATA__akan mengubah perilaku.
Sylwester
1
@Sylwester: Benar. Ini berfungsi untuk bagian dari skrip Perl yang tidak digunakan __DATA__. :)
Greg Hewgill
11

Java, 225 byte

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

Keluaran pada dirinya sendiri (saat dipraisifikasi sebelumnya):

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
sumber
1
Masalah jika komentar diakhiri dengan *. Lihat komentar
edc65
10

Python 2, 68 byte

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

Tidak berfungsi jika dijalankan dari IDLE, karena Anda perlu membuat karakter EOF untuk menghentikan program dari menunggu input.

Output saat dijalankan dengan sendirinya:

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

Terima kasih kepada Greg Hewgill untuk membantu mengatasi masalah dan golf.

Justin
sumber
Kerja bagus, mengalahkan upaya Python saya yang agak lumpuh.
Greg Hewgill
1
@GregHewgill Saya lebih suka upvote bagus untuk komentar yang bagus ;-)
Justin
1
Ok oke ... Saya biasanya tidak memilih melawan diri saya sendiri. :)
Greg Hewgill
5
@GregHewgill Aku suara "melawan" sendiri banyak . Saya memilih jawaban berdasarkan kemampuan mereka, bukan berdasarkan apakah saya menjawab atau tidak.
Justin
8

GolfScript, 10 9 byte

"
}"+.-1%

Cukup mirip dengan solusi minitech , tetapi bekerja dengan baik pada baris baru. Itu bergantung pada tingkah laku GolfScript yang lucu (dan tidak berdokumen) untuk mengabaikan yang tak tertandingi (dan tidak diberi komentar) }, serta semua yang mengikutinya.

Ini akan gagal jika input berisi yang tidak cocok {, tetapi itu secara teknis akan merupakan kesalahan sintaksis.

Bagaimana itu bekerja

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

Contoh

$ 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
sumber
Coba 1\n2#( \nakan menjadi karakter baris baru yang sebenarnya) sebagai masukan Anda.
Justin
1
@ Quincunx: Komentar sial ... Baris baru sebelum braket keriting harus memperbaikinya.
Dennis
Sebelum dan sesudah. Perlu tetap menjadi palindrome.
Justin
@ Quincunx: Tentu saja. Itu seharusnya bekerja sekarang.
Dennis
5

kode mesin x86 pada DOS ( .comfile) - 70 byte

Berurusan dengan file .COM, membuat palyndrome mudah - karena COM "loader" hanya menempatkan konten file di alamat 100h dan melompat ke sana, program harus sudah meng-hardcode akhirnya entah bagaimana dan mengabaikan semuanya setelahnya, jadi kita bisa menambahkannya kebalikan dari byte pertama N-1 (hanya peringatan: jika program entah bagaimana mencoba melakukan trik dengan panjang file semuanya rusak).

Berikut ini adalah hex dump my .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..|

Dibutuhkan file input pada baris perintah, dan menulis output pada stdout; penggunaan yang diharapkan adalah sesuatu seperticompalyn source.com > out.com .

Majelis yang dikomentari:

    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

Diuji pada dirinya sendiri dan solusi untuk pertanyaan sebelumnya tampaknya bekerja dengan baik di DosBox, beberapa pengujian yang lebih luas pada executable DOS "kanonik" akan mengikuti.

Matteo Italia
sumber
3

GolfScript, 8

.-1%'#'\

Tidak menangani baris baru, tetapi tidak ada yang menggunakan yang ada di GolfScript.

Ry-
sumber
6
Menggunakan baris baru dalam string literal dapat digunakan cukup sering ;-)
Howard
2

Bash + coreutils, 39 byte

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

Membaca dari STDIN dan output ke 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
sumber
@ user23013 Tampaknya berfungsi dengan baik. Setidaknya seperti tes sederhana ( echo 'Hello, World!' ). cukup banyak mengabaikan semuanya setelah exit.
Trauma Digital
2

Javascript ( ES6 ) Multi-line - 71

Agak sorta mencuri metode komentar Quincunx di sini:

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

Baris tunggal - 49

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

C ++, 214 209 byte

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

Hasil menjalankannya sendiri:

#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
sumber
Gagal ketika lanjutan char '\' digunakan. Coba [ ideone.com/TCZHr9]
edc65
@ edc65: Ya, saya memikirkannya nanti. Satu-satunya cara jelas yang bisa saya pikirkan untuk menangani itu adalah membuka lipatan garis yang dilipat terlebih dahulu.
Greg Hewgill
dapat dilakukan dengan biaya kecil - se jawaban C saya
edc65
2

Brainfuck, 749 tanpa spasi putih (tidak golf)

Ini menghasilkan program-program brainfuck yang mencerminkan palindrom, yaitu mereka adalah bayangan cermin dari diri mereka sendiri.

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

Diberikan sebuah program, hasilnya

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

dengan PROGRAMdan MIRRORdiganti oleh program (tanpa karakter non-brainfuck) dan gambar cerminnya.

kotak kardus
sumber
2

C 168 175

Benar menangani baris baru yang lolos di dalam kode sumber

Edit 1 bug tetap ketika baris baru terakhir hilang
Edit 2 bug tetap ketika baris di dalam komentar berakhir dengan *: tambahkan tab tab sebelum //komentar
(dan pindahkan lebih lanjut)

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 Standar, kode yang valid, banyak peringatan

Tidak disatukan

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
sumber
1
ada sedikit bug di dalamnya. coba/* *<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()));}}

Input tes:

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

Hasil tes:

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
sumber
Saya pikir Anda mungkin salah paham tentang salah satu instruksinya. Program Anda harus dapat mengambil program apa pun sebagai input, dan menulis program palindrom yang melakukan hal yang sama dengan program aslinya.
Greg Hewgill
Itu bisa .. Jika saya memasukkan kode C ++ dari jawaban Anda, itu mengembalikan apa yang Anda miliki.
jzm
Semua program Anda lakukan adalah membalikkan inputnya. Output dari program Anda bukan program palindrom lengkap.
Greg Hewgill
Oh ya, aku mengerti. Diperbarui - lebih baik sekarang?
jzm
2
Yup, itu dia. Hasil tes Anda harus memiliki //di akhir setiap baris sekarang.
Greg Hewgill
0

PHP, 96 byte

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

Penggunaan sampel:

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

Ini tidak ada yang pintar. Itu hanya sepotong kode sederhana yang berfungsi ... Aku sedang ingin bermain. Saya tahu bahwa kode ini penuh dengan praktik pemrograman yang buruk!

Akhirnya, saya dengan senang hati akan menerima kritik dan suntingan untuk kode ini!

Kepala suku
sumber
Selamat datang di Golf Code. Ini adalah fungsi, bukan program. Lihat jawaban lain, mereka memberikan contoh yang baik.
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#/'
Suram
sumber
0

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

Tidak disatukan (tapi masih sangat penting):

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

Keluaran saat diberi versi yang tidak dikoleksi sebagai masukan:

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