63. Brian & Chuck, 1605 bytes
#16 "(}+?23!@)-("//*\Dv;'[af2.qc]PkPPX'#)"14";n4
#/*0|7//```"` ␉['][!(>77*,;68*,@;'1,@10␉11)(22)S␉␉(1 P''53'S^'q
#>␉
# 36!@␉`
#
#_>++++.>.}+?
#`<`
#<]+<[.>-]>[
#{
#z}
#
#=x<R+++++[D>+++++++59L+++<-][pPLEASE,2<-#2DO,2SUB#1<-#52DO,2SUB#2<-#32DOREADOUT,2PLEASEGIVEUPFACiiipsddsdoh]>+.---.>][
#x%+>+=ttt Z_*.4O6O@
#D>xU/-<+++L
#R+.----\).>]|
#[#[(?2?20l0v0x1k1kMoOMoOMoOMoOMOO0l0ix0jor0h0h1d111x0eU0yx0y0moO1d0y0e0e00m1d0i0fx0g0n0n11MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOmOoMOo0moo0n0tx0t0moO0f0t0gOOM0g0f0h0j0j0i0001k1x0vx0v0l111111^_00)
[ "]56p26q[puts 59][exit]" ,'\[' ];#/s\\/;print"24";exit}}__DATA__/
#
###x<$+@+-@@@@=>+<@@@=>+<?#d>+.--.
#
'(((p\';a=a;case $argv[1]+${a:u} in *1*)echo 50;;*A)echo 54;;*)echo 58;;esac;exit;';print((eval("1\x2f2")and 9or 13)-(0and 4)^1<<(65)>>62)or"'x"or'{}{}{}{}({}<(((((()()())){}{})){}{})>){(<{}(({}){})>)}{}({}())wWWWwWWWWwvwWWwWWWwvwWWWwWWWWWWWWwWWWWwWWWWWWWwWWWWWWWW li ha '#}#(prin 45)(bye)46(8+9+9+9+9+=!)((("'3)3)3)"'
__DATA__=1#"'x"
#.;R"12"'
###;console.log 39
""""
=begin
<>{
#sseeeemPaeueewuuweeeeeeeeeeCis:ajjap*///;.int 2298589328,898451655,12,178790,1018168591,84934449,12597/*
#define p sizeof'p'-1?"38":"37"
#include<stdio.h>
main ( ){puts(p);}/*
print 61
#}
disp 49;
#{
}<>
$'main'3
#-3o4o#$$$
#<q>"3"O.s
=end
"""#"
#}
#s|o51~nJ;#:p'34'3\=#print (17)#>27.say#]#print(47)#]#echo 21# xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi xi ax fwwvwWWWwWWWWwvwWWwWWWwvwWWwWWWwvwWWwWWWwvwWWwwwwwwwwwwwWWWwWWWWWwWWWWWWWwWWWWWWWWWwWWWWWWWWWWWWWWWwWWWWWWWWWWWWwvm
# sss8␛dggi2␛`|$// ''25 16*///~-<~-<~-<<<~-^_^_X2229996
VIP score (Versatile Integer Printer): .006414 (to improve, next entry should be no more than 1681 bytes)
Rundown
This program prints 63 in Brian & Chuck, 62 in Grass 61 in S.I.L.O.S, 60 in Moorhens 2.0, 59 in Tcl, 58 in Ksh, 57 in Wise, 56 in dc, 55 in Brain-Flak Classic, 54 in Zsh, 53 in Shove, 52 in COW, 51 in Assembly, 50 in Bash, 49 in Octave, 48 in Deadfish~, 47 in Lily, 46 in Cubix, 45 in PicoLisp, 44 in alphuck, 43 in reticular, 42 in evil, 41 in brainfuck, 40 in Minimal-2D, 39 in CoffeeScript, 38 in C, 37 in C++, 36 in Labyrinth, 35 in INTERCAL, 34 in Rail, 33 in Incident, 32 in Whirl, 31 in Modular SNUSP, 30 in Whitespace, 29 in Trigger, 28 in Brain-Flak, 27 in Perl 6, 26 in 05AB1E, 25 in Pip, 24 in Thutu, 23 in Hexagony, 22 in Underload, 21 in Nim, 20 in Prelude, 19 in Reng, 18 in Cardinal, 17 in Julia, 16 in Pyth, 15 in Haystack, 14 in Turtlèd, 13 in Ruby, 12 in Fission, 11 in Befunge-98, 10 in Befunge-93, 9 in Perl 5, 8 in Retina, 7 in Japt, 6 in SMBF, 5 in Python 2, 4 in ><>, 3 in Minkolang, 2 in V/Vim, and 1 in Python 3.
Verification
Most of the languages are tested by the test driver shown above.
Reng can be tested to output 19 here.
Modular SNUSP can be tested to output 31 here.
Incident was verified to test 33 via manual balancing of tokens.
Deadfish~ was can be tested to output 48 locally, using this interpreter. Note that Deadfish~ takes the polyglot to be fed on stdin, but and prints a number of
>>
prompts to standard output, which are n unavoidable consequence of running any Deadfish~ program.Moorhens 2.0 can be tested to output 60 using this interpreter.
Brian & Chuck
Brian and Chuck are two mutually modifying, BrainF**k-like languages. Like SMBF the memory tape starts containing the polyglot. Brian’s memory pointer is Chuck’s Instruction pointer and vise versa. The polyglot is split with a triple backtick, such that the part of the polyglot prior to ```
is put on Brian’s memory tape, while Chuck gets the portion after.
Backtick is used as a string declaration for Pyth which is used to hide most of the polyglot from its parser. The first instance of such a backtick string is on line 2, and we’ve added a an empty string just prior to this to create Brian & Chuck’s delimiter here: #/*0|7//```"
The +-<>
commands for both Brian & Chuck function as you’d expect based on BrainF**k. The ,
and .
commands also function as you’d expect with the caveat that only Brian uses ,
and only Chuck uses .
.
For the more unique commands, we have the ?
, which is a no-op if the current memory cell is zero, otherwise it switches control between Brian and Chuck. Also, curly braces will repeatedly move the tape head to the right (}
) or left ({
) until the cell under the memory pointer is zero/null. And finally, all instances of _
are replaced with null bytes, which makes for a convenient landing space when using curly braces to advance the memory tape.
The program starts by reading line 1 with Brian. The first operation encountered is }
in the Hexagony capsule, and it’s here where we begin making changes. The }
advances Chuck’s pointer to the _
I added to line 6. I chose line 6 because, as an even numbered line, it’s subject to Retina’s friendlier parser, which is needed for consecutive +
’s. Second, this line leaves a buffer line between itself and Labyrinth’s code on line 4, which is needed to maintain the labyrinth walls. And third, we don’t need any spaces, and this is the final line of Whitespace’s command to end the program. This line is also located just prior to the SMBF/BF/Minimal-2D code space, and it aesthetically pleases me to keep the BrainF**k derivatives together.
With Chuck pointing at the _
, Brian advances its IP to +
which I’ve inserted in the Hexagony Capsule along with a ?
. The +
gives the null valued _
a positive value which is needed the ?
to transfer control to Chuck where we read the bulk of this answer.
So when we switch control, Chuck is pointing at the _
in #_>++++.>.}+?
. Chuck then advances it’s IP to the >
which moves Brian’s pointer to the 2
in line 1. From here, we increment the 2
up to 6
with ++++
, and then output the 6 with .
. Then we advance Brian’s pointer again with >
landing on the 3
in line 1, which we output with .
. Finally, we advance Brian’s pointer to the end of its code segment with }
, increment the null memory position with +
, and transfer control back to Brian with ?
. And from here, we let Brian advance to the end of his tape, ending the program.
It’s super easy to get lose track of who has control and where the pointers are at, so I want to share this configuration which runs Brian & Chuck with a switch for stepping through the code for debugging purposes. I’m sharing the verbose version of this debug switch which also has a @
command that only applies in debug and will terminate the program. The current solution skips over the @
in line 1, so it’s not an issue, but it is something to be aware of if this gets reworked in the future.
S.I.L.O.S.
@RohanJhunjhunwala updated Tio’s S.I.L.O.S. interpreter such that 1=61 //
threw an error, which invalidated our test case in the Test Driver. C'est la vie.
This left me with a quandary - do I update the code or the test? @RohanJhunjhunwala rightly pointed out that the =
could be replaced with a +
to address the issue, so changing the code sounded like the ideal solution, assuming it was compatible with an old enough version of the interpreter. But I ended up taking a different path that came about while I was working on adding a different language: J.
Today, I’ve kind of given up on J at this point. I think it might be possible to add if I’m willing to heavily rework the top 2 lines (and to be honest, I’m increasingly disinclined to do so). But at the time, I had come to the conclusion that J had a blocking issue with Thutu’s requirement of having a trailing //
on each line that didn’t start with a #
.
I posted to the Polyglot Development board to see if anyone had an idea to get around Thutu’s requirement and @ais523 suggested injecting Perl in Thutu’s parser so it could get past the regex syntax requirement.
Cool!
I later realized that this Thutu hack would allow S.I.L.O.S. to use a more conventional solution, which would allow the S.I.L.O.S. test to remain valid, and golf down both the S.I.L.O.S. and Thutu code. So I jumped in with both feet and gave Thutu its Perl injection and changed the S.I.L.O.S. code to print 61
.
Thutu
The Thutu hack is based on the \
command. Here's the documentation's definition:
(When the next character is punctuation) Remove any special meaning the next character might have, even if it's a slash or backslash. Removing the special meaning of a slash prevents it delimiting the end of a regexp, making it possible to write slashes within a regexp.
And this is the code snipped that @ais523 suggested (after I golfed it down and added the necessary bits to include it in the polyglot):
/s\\/;print"24";exit}}__DATA__/
So how does the injection work? Well, a quick look at the interpreter showed this line of code:
@regexps = split /(?<!\\)\//, $_, -1; # Split on / not preceded by \
Now, I’m not the Perl-y-est guy around, but fortunately the comments tell the story. This bit (\\/
) from the Thutu line of the polyglot is being parsed by Thutu’s intrepeter as escaping out both the second \
and the /
, where traditionally, we’d expect only the second \
to be escaped out.
And because we’ve formatted the line to otherwise look like a valid regex, we get past the syntax checks and arrive at this piece of the interpreter where I believe our Perl injection (;print"24";exit}}__DATA__
) gets executed:
foreach $regexp (@regexps)
{
$regexp and print "/$regexp/ $regsep "; # Guards are just Perl regexps.
}
Originally, this was intended to just allow Thutu to bypass its regex syntactical requirements on a line, but what actually happened is it little broader. Every line after the injection point stopped requiring any regex syntax. Why is that? Well, we kinda crashed the compiler. But it still produced a good result.
This raised a philosophical dilemma though, did the program run without error? It wasn’t entirely clear. so @ais523 created a metapost to answer this question. The answer came back with an unequivocal yes – the program ran without error.
Cool. So now, Thutu runs through this line:
[ "]56p26q[puts 59][exit]" ,'\[' ];#/s\\/;print"24";exit}}__DATA__/
And everything past this compiler crash point doesn’t need to conform to Thutu syntax. This means that the space between =begin
and =end
now has virtually no syntax requirement as long as you don’t cut in the middle of any existing code pieces.
Where to go from here
Ok, there is one syntax requirement between the =begin
and =end
. Any code pieces that use Brain-flak tokens (){}[]<>
without being preceded by a #
will be exposed to Brain-Flak. But there is almost certainly a way to work around this one. So where are the safe spaced to add code in here?
There are a few:
• Before or after print 61
• Before =end
• After =begin
• After <>{
• After }<>
@Luke mentioned in polyglot chat he thought he had an answer to go next, and I'd point to these locations as probably good locations.
Good Luck.
Incident Report
#<R>"3"O.s
became #<q>"3"O.s
because R
is no longer a token and this detokenizes q
$'main'
became $'main'3
In order to detokenizes ' ␊
and '3
###;console.log +39
became ###;console.log 39
Because 3
was no longer a token.
sseeeemPaeueewuuweeeeeeeeeeCisajjap
became sseeeemPaeueewuuweeeeeeeeeeCis:ajjap
Which detokenizes :
and sa
]>+.-- -. >]
became ]>+.---.>]
because --.
and .>
are no longer tokens.
1k10v
became 1k1x0v
to detokenize 10
A Couple things I forgot to mention
I golfed off the 3
at the end of the C/C++ processor directive on line 1. This was to counter the addition of characters to line 1 so I didn't have to totally rework all the 2D languages. Just most of them.
Also, I added a -
between the )
and (
on line 1 because I added a +
earlier that incremented a memory cell in BF and SMBF which I needed to decrement back to zero.