37
\$\begingroup\$

I was reading Print your code backwards - reverse quine And I thought, this could be more interesting if your backwards code is also executable. So this challenge will have all the rules and requirements of the other, but must also be valid source once reversed (in the same or another language and still print its source backwards.

All rules and scoring from the reverse quine challenge apply, so all answers to this question will answer that one (but not score as well.)

Edit:

By request, all rules now copied here.

Rules:

  • write a program p which when executed produces output p' where p' is p backwards and p' when executed produces p.
  • No using other files (e.g. reverse.txt)
  • Minimum code length is two characters.
  • Your program cannot be a palindrome.

Scoring:

  • +50 if you use pull data from the Internet.
  • +25 if you read your own source code.
  • +1 point per character.
  • Lowest score wins.
\$\endgroup\$
10
  • \$\begingroup\$ eval(eval(eval(eval(eval(eval(eval(eval(eval(p))))))))) \$\endgroup\$ Dec 19 '13 at 1:18
  • \$\begingroup\$ I'm just saying that you'd be able to execute the output of executing the output of executing the output of [...] executing the output of p (same as any quine except for the backwards quine). \$\endgroup\$ Dec 19 '13 at 1:21
  • \$\begingroup\$ @AndrewLarsson Indeed although The proof of concept I am building p will be written in c and p' in perl. \$\endgroup\$
    – hildred
    Dec 19 '13 at 1:23
  • \$\begingroup\$ Oh, that'd be cool! \$\endgroup\$ Dec 19 '13 at 1:23
  • 1
    \$\begingroup\$ Yeah, saw that too late. Not a duplicate. \$\endgroup\$ Dec 19 '13 at 8:31
23
\$\begingroup\$

GolfScript, 46 chars

0{`".~#"+.-1%+\.!@@}.~##~.}@@!.\+%1-.+"#~."`{1

Well, this is ugly, but it works. The output equals the code reversed, and is also a valid GolfScript program which outputs the original code again.

OK, let me try to explain how I constructed it. First, I started from the quine {".~"}.~, and modified it as in this answer to reverse itself. To make the output an executable quine in itself, I made a copy of the code before reversing it, and included a # at the end of the code, so that the reversed version at the end became just a comment. Thus, we get the palindromic quine:

{`".~#"+.-1%}.~##~.}%1-.+"#~."`{

However, by the rules, palindromes are not allowed, so I needed to break the symmetry somehow. I figured the easiest way would be to include a 0 (which, in itself, is a quine in GolfScript) in the code and flip it to 1 with ! after creating the reversed copy. Most of the remaining complexity is just ugly stack manipulation to get everything in the right order.

\$\endgroup\$
3
  • \$\begingroup\$ Is it also golfscript when reversed or is it another language? \$\endgroup\$
    – hildred
    Dec 19 '13 at 3:37
  • \$\begingroup\$ Yes, it's GolfScript both ways. Indeed, except for the 0 and 1 at the beginning and end, the rest of the code is a palindrome. \$\endgroup\$ Dec 19 '13 at 3:43
  • 9
    \$\begingroup\$ Wow. Okay, I don't feel smart enough for this SE anymore :( \$\endgroup\$
    – Cruncher
    Dec 19 '13 at 14:34
21
\$\begingroup\$

Perl and C 6478 1955

#!/usr/bin/perl -i//
$_=<<'rahc';eval $_; #//
print scalar reverse "#!/usr/bin/perl -i//\n\$_=<<'rahc';eval \$_; #//\n${_}rahc\n" #//
__END__
__END__ enifed#
};)"{ = ][cn\rahcn\n\"(p
};)'n\'( rahctup) 1 == 21%b ( fi
;)d(p;)]1-b[c,",d%",)d(foezis,d( ftnirpns{)b--;b;)c(foezis=b( rof
;)c(p;]9[d rahc;b tni{)(niam diov
}};)]1-b[c(rahctup )]1-b[c(fi{)b--;b;)c(nelrts=b(rof;b tni{)c*rahc(p diov
>h.gnirts< edulcni#
>h.oidts< edulcni#
;}
,0
,53,33,74,711,511,411,74,89,501,011,74,211
,101,411,801,23,54,501,74,74,01,63,59,16
,06,06,93,411,79,401,99,93,95,101,811,79
,801,23,63,59,95,23,53,74,74,01,211,411
,501,011,611,23,511,99,79,801,79,411,23,411
,101,811,101,411,511,101,23,43,53,33,74,711
,511,411,74,89,501,011,74,211,101,411,801,23
,54,501,74,74,29,011,29,63,59,16,06,06
,93,411,79,401,99,93,95,101,811,79,801,23
,29,63,59,95,23,53,74,74,29,011,63,321
,59,521,411,79,401,99,29,011,43,23,53,74
,74,01,59,59,96,87,86,59,59,01,59,59
,96,87,86,59,59,23,101,011,501,201,101,001
,53,01,521,95,14,43,321,23,16,23,39,19
,99,011,29,411,79,401,99,011,29,011,29,43
,04,211,01,521,95,14,93,011,29,93,04,23
,411,79,401,99,611,711,211,14,23,94,23,16
,16,23,05,94,73,89,23,04,23,201,501,01
,95,14,001,04,211,95,14,39,94,54,89,19
,99,44,43,44,001,73,43,44,14,001,04,201
,111,101,221,501,511,44,001,04,23,201,611,011
,501,411,211,011,511,321,14,89,54,54,95,89
,95,14,99,04,201,111,101,221,501,511,16,89
,04,23,411,111,201,01,95,14,99,04,211,95
,39,75,19,001,23,411,79,401,99,95,89,23
,611,011,501,321,14,04,011,501,79,901,23,001
,501,111,811,01,521,521,95,14,39,94,54,89
,19,99,04,411,79,401,99,611,711,211,23,14
,39,94,54,89,19,99,04,201,501,321,14,89
,54,54,95,89,95,14,99,04,011,101,801,411
,611,511,16,89,04,411,111,201,95,89,23,611
,011,501,321,14,99,24,411,79,401,99,04,211
,23,001,501,111,811,01,26,401,64,301,011,501
,411,611,511,06,23,101,001,711,801,99,011,501
,53,01,26,401,64,111,501,001,611,511,06,23
,101,001,711,801,99,011,501,53,01,95,521,01
{ = ][c
rahc

Edit:

Brief explanation: from perl the two interesting lines are the second and the third. The second line has two statements the first of which reads the rest of the document into a string. The second evals the string. The Third line prints everything backwards. every thing else gets ignored. from the c side you have an array which has the program as a string, which gets printed as an array and a string, and the rest is a comment.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ wat. :O My head exploded. But I count 6536 characters in that... \$\endgroup\$
    – Doorknob
    Dec 19 '13 at 2:08
  • \$\begingroup\$ What...how... 0_0 \$\endgroup\$ Dec 19 '13 at 2:15
  • \$\begingroup\$ @DoorknobofSnow I counted the wrong version. But here is a shorter version. \$\endgroup\$
    – hildred
    Dec 19 '13 at 7:22
  • \$\begingroup\$ This is incredible! I think Haskell/C might be another feasible combination. \$\endgroup\$ Apr 13 '15 at 17:25
  • \$\begingroup\$ @theonlygusti, if you post it and I can compile it, I will upvote it. \$\endgroup\$
    – hildred
    Apr 13 '15 at 17:28
8
\$\begingroup\$

Ruby 145


DATA.read.tap{|a|puts a.reverse,a.tr("\x79\x59","\x59\x79")}
:y
__END__
__DNE__
Y:
})"97x\95x\","95x\97x\"(rt.a,esrever.a stup|a|{pat.daer.ATAD

The main idea is simple: just put the first half of the source code backwards after the __END__ which can be read using DATA from ruby. Then just print the reverse of this data, then print the data, and you get back the original source code

The problem is, that this becomes a palindrome (note that the first line needs an endline), so we have to break the symmetry. I just added a symbol :y to the code, and some code that will transform this symbol between lowercase and uppercase between runs, thereby reverting to the original state after two runs.

Test one: they can be executed

$ ruby rq2.rb > rq2t.rb
$ ruby rq2t.rb > rq2tt.rb

Test two: the result of two runs will return the original source

$ diff rq2.rb rq2tt.rb
$

Test three: the code is not a palindrome (the middle run is different)

$ diff rq2.rb rq2t.rb
3c3
< :y
---
> :Y
6c6
< Y:
---
> y:
\$\endgroup\$
0
4
\$\begingroup\$

Gol><>, 11 bytes

":5-}H}+5:'

A whole byte chopped off! it almost is a palindrome, but technically isn't because of the '+' and '-', haha!

Try it online!

The two below don't work, or at least they don't meet the specifications of the challenge, but the code above does.

slightly younger version, 12 bytes

"r2ssrH}+5:'

Golfed off a byte, simply by using the double quote and incrementing it by 5! And this new version looks less like a palindrome.

Try it online!

older version, 13 bytes

"r2ssrHrss7r'

There was a problem with the previous that JoKing pointed out, thank you for that, now it works, but with the price of 4 extra bytes...

Try it online!

\$\endgroup\$
0
4
\$\begingroup\$

><>, 21 19 bytes

'rd3*70.r l?!;o90.<

Try it here!

Uses the *><> interpreter for convenience, but this is valid ><> code.


If erroring out is allowed, then it can be done in 16 bytes:

'd3*}70.!r  !|o|

Try it here!

\$\endgroup\$
2
  • \$\begingroup\$ "Try it" links are dead. \$\endgroup\$ Jan 5 '20 at 4:55
  • \$\begingroup\$ @pppery thanks, fixed. \$\endgroup\$
    – Discordian
    Jun 16 at 16:24
2
\$\begingroup\$

Help, WarDoq! (27 bytes)

25 bytes added because of reading source code.

<space>q

How it works:
<space> - a comment that ends on non-space character
q - print source code reversed (q"space")

Reversed:

q<space>

How it works:
q - print source code reversed (q for now)
<space> - a comment that ends on non-space character, and add a character to beginning of q command (making "space"q)

\$\endgroup\$
2
\$\begingroup\$

Python 3.8 (pre-release), 99 bytes

forward :

a=1;exec(s:=#)]a::[
"print(('a=1;exec(s:=#)]a::[\\n%r\\n)#=:s(cexe;1-=a'%s)[::-a])"
)#=:s(cexe;1-=a

Try it online!

backward:

a=-1;exec(s:=#)
")]a-::[)s%'a=-1;exec(s:=#)n\\r%n\\[::a])#=:s(cexe;1=a'((tnirp"
[::a])#=:s(cexe;1=a

Try it online!

How it works:

I based my solution on the quine exec(s:="print('exec(s:=%r)'%s)")

  • In the forward solution, a=1 transforms the slices to have something like :
exec(s:="print('<string for the quine>'[::-1])")

which prints the backward quine

  • in the backward solution, a=-1 transforms the slice to have something like :
exec(s:=")]1::['<string for the quine in backward>'(tnirp"[::-1])

which (due to the [::-1]) gives:

exec(s:="print('<string for the quine>'[::1])")

and prints the original quine

\$\endgroup\$
1
\$\begingroup\$

JavaScript (V8), 817 bytes

I'm sure this can be golfed further. I might also try to translate this into Python.

//))""(nioj.)(esrever.])q+s+q(nioj.))53(edoCrahCmorf.gnirtS(tilps.)c,)63(edoCrahCmorf.gnirtS(ecalper.)q+c+q,)33(edoCrahCmorf.gnirtS(ecalper.))""(nioj.)(esrever.]c...[,)621(edoCrahCmorf.gnirtS(ecalper.s...[(gol.elosnoc
c=//
`console.log([...s.replace(String.fromCharCode(126),[...c].reverse().join("")).replace(String.fromCharCode(33),q+c+q).replace(String.fromCharCode(36),c).split(String.fromCharCode(35)).join(q+s+q)].reverse().join(""))//`
//=c
s=//
`~
c=//
!
//=c
s=//
#
//=s
q=String.fromCharCode(96)//
//)69(edoCrahCmorf.gnirtS=q
$`
//=s
q=String.fromCharCode(96)//
//)69(edoCrahCmorf.gnirtS=q
console.log([...s.replace(String.fromCharCode(126),[...c].reverse().join("")).replace(String.fromCharCode(33),q+c+q).replace(String.fromCharCode(36),c).split(String.fromCharCode(35)).join(q+s+q)].reverse().join(""))//

Try it online!

How?

Line comments at the end of the line comment out that line in the reversed version.

Although the entire program is not a palindrome, it is made up of several palindromic or semi-palindromic sections. These are not true palindromes, but are close enough.

// This line is the last line reversed
//))""(nioj.)(esrever.])q+s+q(nioj.))53(edoCrahCmorf.gnirtS(tilps.)c,)63(edoCrahCmorf.gnirtS(ecalper.)q+c+q,)33(edoCrahCmorf.gnirtS(ecalper.))""(nioj.)(esrever.]c...[,)621(edoCrahCmorf.gnirtS(ecalper.s...[(gol.elosnoc

// This is a palindrome (apart from the string in the middle)
c=//
`console.log([...s.replace(String.fromCharCode(126),[...c].reverse().join("")).replace(String.fromCharCode(33),q+c+q).replace(String.fromCharCode(36),c).split(String.fromCharCode(35)).join(q+s+q)].reverse().join(""))//`
//=c

// This is a palindrome (apart from the string in the middle)
s=//
`~
c=//
!
//=c
s=//
#
//=s
q=String.fromCharCode(96)//
//)69(edoCrahCmorf.gnirtS=q
$`
//=s

// This is also a palindrome
q=String.fromCharCode(96)//
//)69(edoCrahCmorf.gnirtS=q

// This line is the first line reversed
console.log([...s.replace(String.fromCharCode(126),[...c].reverse().join("")).replace(String.fromCharCode(33),q+c+q).replace(String.fromCharCode(36),c).split(String.fromCharCode(35)).join(q+s+q)].reverse().join(""))//

Apart from this, it's a pretty standard quine. Writing the code twice, once in code and once in a string, and substituting the string into itself is a common quine technique.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.