将程序转换为回文程序


15

回文是一个字符串,它是相同的向前和向后,如“赛车”。

用某种语言L编写一个程序,该程序以语言L中的任何程序P1作为输入,并输出语言L中的回文程序P2,该程序执行与P1相同的操作。

您无需担心处理语法错误的输入程序。

这是代码高尔夫,因此以字节数最少的解决方案为准。


我们可以定义语言L吗?
Greg Hewgill 2014年

1
@GregHewgill是的。L是您选择的语言来编写程序。
贾斯汀

在某些语言中,这很难做到。
贾斯汀

3
使用完整的Python子集,这是一个有效的条目:x=input();print(x+'#'+x[::-1])。子集是不包含换行符的所有程序的集合。
贾斯汀

Answers:


17

Perl,55 54字节

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

从stdin读取程序源并将其写入stdout。

自行运行的结果:

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

__END__

__DNE__

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

+1不使用评论

3
我喜欢这样,它在底部用“ DNE”标记了明显的乱语,“ DNE”是“请勿擦除”的常用缩写,用于标记黑板/白板上的东西,以便人们不要将它们误认为是不重要的涂写并擦掉。
anaximander 2014年

它是如何工作的,我不知道perl,更具体地说,它是如何quine的(得到要反转的行)?
Cruncher 2014年

2
1+在大多数情况下都有效,除非__DATA__读取程序结尾。print while(<DATA>);\n__DATA__会改变行为。
Sylwester 2014年

1
@Sylwester:是的。这适用于不使用的Perl脚本的子集__DATA__。:)
Greg Hewgill 2014年

11

Java,225个字节

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

本身的输出(预先指定时):

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
如果注释以*结尾,则出现问题。查看评论
edc65 2014年

10

Python 2,68个字节

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

如果从IDLE运行,则不起作用,因为您需要生成一个EOF字符来阻止程序等待输入。

自行运行时的输出:

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

感谢Greg Hewgill帮助解决问题和打高尔夫球。


做得好,击败了我有点la脚的Python尝试。
Greg Hewgill 2014年

1
@GregHewgill我更喜欢发表评论,而不是发表评论;-)
贾斯汀

1
好吧好吧...我通常不投票反对自己。:)
Greg Hewgill 2014年

5
@GregHewgill我对自己投了很多票。我根据答案的优劣而不是根据我是否回答来投票。
贾斯汀2014年

8

GolfScript,10 9个字节

"
}"+.-1%

minitech的解决方案非常相似,但与换行符配合使用效果很好。它依靠GolfScript的有趣(和未记录)的行为来忽略不匹配(和未注释)}以及它后面的所有内容。

如果输入包含不匹配{,它将失败,但是从技术上讲,这将构成语法错误。

怎么运行的

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

$ 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

尝试1\n2#\n将是实际的换行符)作为输入。
贾斯汀

1
@Quincunx:讨厌的评论...大括号前的换行符可以解决此问题。
丹尼斯

之前之后。需要保持回文。
贾斯汀2014年

@Quincunx:当然可以。现在应该可以工作了。
丹尼斯

5

DOS上的x86机器代码(.com文件)-70个字节

处理.COM文件,创建自动程序很容易-因为COM“加载程序”只是将文件的内容放在地址100h并跳转到该地址,所以程序必须已经以某种方式对末尾进行了硬编码并忽略了它之后的所有内容,因此我们可以追加与前N-1个字节相反(仅警告:如果程序以某种方式尝试对文件长度进行欺骗,则所有内容都会中断)。

这是我的.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..|

它在命令行上获取输入文件,并将输出写入stdout;预期的用法类似于compalyn source.com > out.com

评论程序集:

    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

在DosBox中对其自身进行测试,并且可以解决上一个问题的解决方案,随后将对“规范” DOS可执行文件进行更广泛的测试。


3

GolfScript,8岁

.-1%'#'\

不处理换行符,但是没有人在GolfScript中使用换行符。


6
可以在字符串文字中经常使用换行符;-)
Howard

2

Bash + coreutils,39个字节

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

从STDIN读取并输出到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似乎工作正常。至少是一个简单的测试( echo 'Hello, World!' )。bash几乎忽略了之后的一切exit
Digital Trauma

2

Javascript(ES6)多行-71

Kinda sorta 在这里偷了Quincunx的注释方法:

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

单线-49

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

2

C ++,214个 209字节

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

自行运行的结果:

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

使用连续字符'\'时失败。尝试[ ideone.com/TCZHr9]
edc65 2014年

@ edc65:是的,我稍后考虑过。我能想到的唯一显而易见的方法是先展开折线。
格雷格·休吉尔

可以以
较低的

2

Brainfuck,749,不带空格(不打高尔夫球)

这产生了反映回文的大脑操程序,即它们是它们自身的镜像。

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

给定一个程序,它输出

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

PROGRAMMIRROR由程序(没有非brainfuck字符),而其镜像置换。


2

C 168 175

正确处理源代码中的转义换行符

当缺少最后一个换行符时,编辑1个已修复的bug;当注释内的行结尾为:时,则
编辑2个已修复的bug *:在//注释 之前添加一个制表符
(并添加更多内容)

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标准,有效代码,许多警告

不打高尔夫球

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
其中有一个小错误。尝试/* *<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()));}}

测试输入:

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

测试输出:

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

我认为您可能误解了其中一项说明。您的程序应该能够将任何程序作为输入,并写出一个回文程序,该程序的功能与原始程序相同。
Greg Hewgill 2014年

如果我从您的答案中输入了C ++代码,它将返回您所拥有的内容。
jzm 2014年

您的程序所做的只是反转其输入。程序的输出不是完整的回文程序。
Greg Hewgill 2014年

哦,是的,我明白了。更新-现在更好了吗?
jzm 2014年

2
是的,就是这样。不过,您的测试输出现在应该//在每行的末尾。
Greg Hewgill 2014年

0

PHP,96字节

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

样品用法:

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

这没什么聪明的。只是完成工作的一段简单代码...我很想玩。我确实知道此代码充斥着不良的编程习惯!

最后,我很乐意接受对此代码的任何批评和编辑!


欢迎来到Code Golf。这是一个功能,而不是程序。请参阅其他答案,它们提供了很好的示例。
AL

0

眼镜蛇-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

球拍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)))))

松散(但仍然非常必要):

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

给定非高尔夫版本作为输入时的输出:

(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(
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.