Chuyển đổi một chương trình thành một chương trình palindromic


15

Một palindrome là một chuỗi giống nhau về phía trước và phía sau, chẳng hạn như "racecar".

Viết chương trình bằng một số ngôn ngữ L, lấy bất kỳ chương trình P1 nào bằng ngôn ngữ L làm đầu vào và xuất ra chương trình palindromic P2 bằng ngôn ngữ L thực hiện tương tự như P1.

Bạn không cần phải lo lắng về việc xử lý các chương trình đầu vào có lỗi cú pháp.

Đây là mã golf , vì vậy giải pháp có số byte ít nhất sẽ thắng.


Chúng ta có thể định nghĩa ngôn ngữ L?
Greg Hewgill

1
@GregHewgill Có. L là ngôn ngữ bạn chọn để viết chương trình của mình.
Justin

Trong một số ngôn ngữ, điều này là khó khăn đáng ngạc nhiên.
Justin

3
Với một tập hợp con hoàn chỉnh của Python, đây là một mục hợp lệ : x=input();print(x+'#'+x[::-1]). Tập hợp con là tập hợp tất cả các chương trình không bao gồm các dòng mới.
Justin

Câu trả lời:


17

Perl, 55 54 byte

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

Đọc nguồn chương trình từ stdin và ghi vào thiết bị xuất chuẩn.

Kết quả của việc tự chạy:

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

__END__

__DNE__

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

+1 vì không sử dụng nhận xét

3
Tôi thích rằng nó đánh dấu sự vô nghĩa rõ ràng ở phía dưới với "DNE" - một cách viết tắt phổ biến cho "Không xóa" được sử dụng để đánh dấu những thứ trên bảng phấn / bảng trắng để mọi người không nhầm lẫn chúng với những nét vẽ nguệch ngoạc không quan trọng và xóa sạch chúng.
anaximander

Nó hoạt động như thế nào, tôi không biết perl, cụ thể hơn là nó hoạt động như thế nào (lấy dòng mà nó đảo ngược)?
Cruncher

2
1+ Hoạt động trong hầu hết các trường hợp trừ khi chương trình kết thúc với __DATA__đó được đọc .. ví dụ. print while(<DATA>);\n__DATA__sẽ thay đổi hành vi.
Sylwester

1
@Sylwester: Đúng. Điều này hoạt động cho tập hợp con của các tập lệnh Perl không sử dụng __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());}}

Đầu ra trên chính nó (khi được chỉnh sửa trước):

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
Vấn đề nếu bình luận kết thúc bằng *. Xem bình luận
edc65

10

Python 2, 68 byte

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

Không hoạt động nếu chạy từ IDLE, vì bạn cần tạo ký tự EOF để ngăn chương trình chờ vào đầu vào.

Đầu ra khi chạy trên chính nó:

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

Cảm ơn Greg Hewgill đã giúp giải quyết vấn đề và chơi gôn.


Công việc tốt, đánh bại nỗ lực Python khập khiễng của tôi.
Greg Hewgill

1
@GregHewgill Tôi thích một upvote tốt cho một nhận xét tốt đẹp ;-)
Justin

1
Ok được rồi ... tôi thường không bỏ phiếu chống lại chính mình. :)
Greg Hewgill

5
@GregHewgill Tôi bỏ phiếu "chống lại" bản thân mình rất nhiều . Tôi đưa ra câu trả lời dựa trên giá trị của họ, không dựa trên việc tôi có trả lời hay không.
Justin

8

GolfScript, 10 9 byte

"
}"+.-1%

Khá giống với giải pháp của minitech , nhưng nó hoạt động tốt với các dòng mới. Nó dựa vào hành vi hài hước (và không có giấy tờ) của GolfScript để bỏ qua một hành vi chưa từng có (và không bị thay đổi)} , cũng như mọi thứ diễn ra sau đó.

Nó sẽ thất bại nếu đầu vào chứa một không khớp {, nhưng về mặt kỹ thuật sẽ tạo thành một lỗi cú pháp.

Làm thế nào nó hoạt động

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

Thí dụ

$ 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

Hãy thử 1\n2#( \nsẽ là một ký tự dòng mới thực tế) làm đầu vào của bạn.
Justin

1
@Quincunx: Nhận xét kỳ quặc ... Một dòng mới trước dấu ngoặc nhọn sẽ khắc phục điều đó.
Dennis

Trước sau. Cần duy trì một palindrom.
Justin

@Quincunx: Tất nhiên rồi. Nó nên hoạt động ngay bây giờ.
Dennis

5

mã máy x86 trên DOS (.com tệp) - 70 byte

Xử lý các tệp .COM, tạo ra một hội chứng dễ dàng - vì "trình tải" COM chỉ đặt nội dung của tệp tại địa chỉ 100h và nhảy vào đó, chương trình phải mã hóa phần cuối của nó bằng cách nào đó và bỏ qua mọi thứ sau nó, vì vậy chúng ta có thể thêm vào mặt trái của byte N-1 đầu tiên (chỉ báo trước: nếu chương trình bằng cách nào đó cố gắng thực hiện các thủ thuật với độ dài của tệp thì mọi thứ đều bị hỏng).

Đây là kết xuất hex của .COM-palyndromizing của tôi .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..|

Nó nhận tệp đầu vào trên dòng lệnh và ghi đầu ra trên thiết bị xuất chuẩn; việc sử dụng dự kiến ​​là một cái gì đó như compalyn source.com > out.com.

Nhận xét lắp ráp:

    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

Đã tự mình thử nghiệm và các giải pháp cho một câu hỏi trước có vẻ hoạt động tốt trong DosBox, một số thử nghiệm mở rộng hơn về các tệp thực thi DOS "chuẩn" sẽ tuân theo.


3

GolfScript, 8

.-1%'#'\

Không xử lý các dòng mới, nhưng không ai sử dụng những dòng này trong GolfScript.


6
Sử dụng dòng mới trong chuỗi ký tự có thể được sử dụng khá thường xuyên ;-)
Howard

2

Bash + coreutils, 39 byte

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

Đọc từ STDIN và xuất ra 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 Có vẻ hoạt động tốt. Ít nhất là một bài kiểm tra đơn giản như thế ( echo 'Hello, World!' ). bash khá nhiều bỏ qua tất cả mọi thứ sau exit.
Chấn thương kỹ thuật số

2

Javascript ( ES6 ) Đa dòng - 71

Kinda sorta đã đánh cắp phương pháp bình luận của Quincunx tại đây:

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

Dòng đơn - 49

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

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

Kết quả của việc tự chạy:

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

Lỗi khi tiếp tục char '\' được sử dụng. Hãy thử [ ideone.com/TCZHr9]
edc65

@ edc65: Vâng, tôi đã nghĩ về điều đó sau. Cách rõ ràng duy nhất tôi có thể nghĩ ra để xử lý đó là mở ra các đường gấp trước.
Greg Hewgill

có thể được thực hiện với chi phí nhỏ - câu trả lời C của tôi
edc65

2

Brainfuck, 749 không có khoảng trắng (không được đánh gôn)

Điều này tạo ra các chương trình brainfuck mà nhân đôi palindromes, tức là chúng là hình ảnh phản chiếu của chính họ.

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

Đưa ra một chương trình, nó xuất ra

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

với PROGRAMvà được MIRRORthay thế bởi chương trình (không có các ký tự không phải là brainfuck) và hình ảnh phản chiếu của nó.


2

C 168 175

Xử lý chính xác thoát dòng mới bên trong mã nguồn

Chỉnh sửa 1 lỗi cố định khi thiếu dòng mới nhất
Chỉnh sửa 2 lỗi cố định khi dòng bên trong bình luận kết thúc bằng *: thêm một tab char trước khi //nhận xét
(và đánh gôn thêm)

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

Tiêu chuẩn C99, mã hợp lệ, nhiều cảnh báo

Ung dung

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
Có một lỗi nhỏ trong đó. thử/* *<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()));}}

Kiểm tra đầu vào:

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

Đầu ra thử nghiệm:

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

Tôi nghĩ rằng bạn có thể đã hiểu nhầm một trong những hướng dẫn. Chương trình của bạn sẽ có thể lấy bất kỳ chương trình nào làm đầu vào và viết ra một chương trình palindromic thực hiện tương tự như chương trình gốc.
Greg Hewgill

Nó có thể .. Nếu tôi nhập mã C ++ từ câu trả lời của bạn, nó sẽ trả về chính xác những gì bạn có.
jzm

Tất cả chương trình của bạn làm là đảo ngược đầu vào của nó. Đầu ra của chương trình của bạn không phải là một chương trình palindromic hoàn chỉnh.
Greg Hewgill

Ồ vâng, tôi hiểu rồi Cập nhật - tốt hơn bây giờ?
jzm

2
Đúng rồi, thế đó. Đầu ra thử nghiệm của bạn nên có //ở cuối mỗi dòng ngay bây giờ.
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;");
}

Sử dụng mẫu:

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

Điều này không có gì thông minh. Đó chỉ là một đoạn mã đơn giản thực hiện công việc ... Tôi đang có tâm trạng chơi. Tôi biết rằng mã này đầy rẫy những thực tiễn lập trình xấu!

Cuối cùng, tôi sẽ sẵn sàng chấp nhận mọi lời chỉ trích và chỉnh sửa mã này!


Chào mừng bạn đến với Code Golf. Đây là một chức năng, không phải là một chương trình. Xem các câu trả lời khác, họ cung cấp các ví dụ tốt.
AL

0

Rắn hổ mang - 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

Vợt 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 (nhưng vẫn rất cấp bách):

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

Đầu ra khi được đưa ra phiên bản không được chọn làm đầu vào:

(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(
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.