\$\begingroup\$

41. brainf***, 916 bytes

# 4"16" 3//v\(@#/;\D"14"<;n4 #/*`3 afaaZ">;[77*,68*,@;'1,'1,q)(22)S# ␉␉␉␉ ( #yy␉;36!@ #`<` ␉ #=␉x #<]+<[.>-]>[ #␉< ###xR+++++[D>+++++++L+++<-][<<<]>+.---.>][ #px%>~~~+␉+~*ttt*.x #D>xU/-<+++L) #R+.----.R␉>]| #[#yy#yy0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_) #|␉ print((eval("1\x2f2")and(9)or(13 ) )-(0and 4)^1<<(65)>>(62))or'(\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1111|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/ __DATA__=1#// #.\."12"␉* ###; console.log 39 """"#// =begin␉// #*/ #define␉z sizeof 'c'-1?"38":"37" #include<stdio.h> int main() /*/ #()`#`\'*/{puts(z);}/*'`` $'main'␉// #-3o4o#$$$ <>"3"O.<␉>// # =end #// """#"#// #0]#echo 21#/(\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE) a>>> #>27.say# /7Jn~15o| #8␛dggi2␛`␉|1|6$//''25 =#print(17) ###^_^_LEintnd"3"z!]/}23!@/*///Z222999"26

␉ is a literal tab, ␛ a literal ESC character; Stack Exchange would mangle the program otherwise. I recommend copying the program from the "input" box of the TIO link below, if you want to work on it.

Try it online!

VIP Score (Versatile Integer Printer): 0.01329

Rundown

This program prints 41 in brainf***, 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. You can test Reng here and Modular SNUSP here; they output 19 and 31 respectively, as required.

The Test Driver has been updated to include the Tokenizer, finally. All the C code is stored as an argument from the Bash Script’s perspective. I also changed the output to wrap horizontally with a trailing space after each token instead of outputting vertically. This was just my preference, to make it match the Whitespace output. But anyone else can change it if they feel like it’s too confusing.

I also made a Test Driver adjustment to handle column spacing for Turtlèd’s UFT8 char in the rundown. That misalignment was driving me nuts! The “fix” is pretty hack-ish since it just looks for an è and changes the column width for that case, but it gets the job done.

Explanation

First off, I want to say how awesome @SnoringFrog’s Versatile Integer Printer Score Rundown code snippet from the last post was. I’ve been calculating answers before posting for a while, and this has re-inspired me keep it small. I think we can beat @sp3000’s answer eventually.

So I started working on this answer by trying to golf down what I could and I was pretty successful. I even had an answer in a different language with a total byte count smaller than #40. But as I tried to golf down Minimal-2D, I had to learn BF so I could better work with its derivatives and in the process I found @Primo’s record breaking Hello, World!. I fell in love the elegance.

Minimal-2D, it turned out, was not efficient enough to utilize the tape initializing technique used by @Primo, but I’m of the opinion now that it would probably be too byte heavy anyways. We are only trying to print an integer after all. But @Primo did send me down the path to learning how to multiply in BF, which I brought to the Minimal-2D’s code.

Then after all this, I re-read @SnoringFrog’s comment about how to include BF and realized that not only could I do it, but I could use much of the Minimal-2D code I had golfed down in the BF answer. So I dug in to answer with BF, and here we are.

One more thing before I get into the details. There were a couple changes I made for non-golf reasons. First, I moved the bulk of the code @SnoringFrog added to just below the 2D languages in the top several rows. To me, it is a long term strategic move to prevent 2D-langs from traversing the center of the polyglot in order to prevent future bugs where possible. The byte hit was low for this move, so I went for it.

Second, during the various re-factors I learned that the Begunges and Minkolang output a trailing space after numeric outputs and that this was the cause of the null bytes we’ve been seeing in the Test Driver for these languages. I fixed these by outputting the stack’s value as an ascii code (which did not include the trailing space feature), instead of the value directly. There was a small byte hit for this change as well, but now the Test Driver’s output is so uniform. How could I not?

SM/BF

Let’s quickly go over the basics. These are the only valid commands for SMBF and BF:

> Move the pointer to the right < Move the pointer to the left + Increment the memory cell under the pointer - Decrement the memory cell under the pointer . Output the character signified by the cell at the pointer , Input a character and store it in the cell at the pointer [ Jump past the matching ] if the cell under the pointer is 0 ] Jump back to the matching [ if the cell under the pointer is nonzero

Both languages have a memory tape where values are stored and changed. SMBF’s only difference is that whatever code is being executed is also stored on the memory tape to the left of the starting point. As @SnoringFrog pointed out, getting SMBF and BF to produce different results hinges on moving the memory pointer to the left of the origin. In Tio’s BF interpreter, the memory pointer is capable of moving left of the origin and will find 0’s instead of the Polyglot’s ascii codes that SMBF sees. Here’s an example that can be run in both SMBF and BF to exemplify the difference.

At the start of the polyglot, the Befunges require the > on the second row to run to completion and Perl6 requires that every > be preceded by a < . So SM/BF start with <> to leave the memory pointer at the origin, then hit a [ which jumps some offensive characters for both languages to the ] on the 6th row.

Next, we increment the origin memory cell for both languages and move the memory pointer to the left with +< . (For conversational convention, we’ll call the origin memory cell as cell 0, cells to the right of the origin 1, 2, ... And cells to the left -1,-2, …). Cell -1 contains the asci code of the last character in the polyglot in SMBF and 0 in BF, so when the next [ is encountered, only BF jumps to the next ] while SMBF passes into the code.

As SMBF traverses [.>-] it prints the 6 found at the end of the polyglot and then moves the memory pointer back to cell 0, setting its value back to zero to exit the ] . To review, the tapes at this pint are: SMBF’s negative cells hold the polyglot, and it’s 0 and positive cells hold zero. BF’s negative and positive cells hold zero while it’s origin cell holds 1.

Next the > moves SMBF to cell 1 and BF back to cell 0 allowing BF to enter it’s private code block: [<+++++[>++++++++++<-][<<<]>+.---.>] (I’ve removed the non-BF characters from this). Here, we move back to cell -1 and initialize our loop control variable (cell -1) to a value of 5. Then we enter the loop where we add 10 to cell 0 and decrement cell -1 five times before exiting the loop where we will be pointing at cell -1 with a value of 0.

Next we encounter [<<<] while pointing at a zero, so BF doesn’t pass through this. The purpose here is to balance a number of > ’s with preceding < ’s so Perl6 doesn’t error out.

At this point cell 0 is valued at 51. The ascii value of 4 is 52, so we move the pointer to cell 0 add 1, then print the value. And finally, we decrement cell 0 back to the ascii character 1 and print again before setting the memory pointer to cell 1 (value 0) to exit past the ] .

SMBF and BF both hit the last [ on line 8 next while both are resting on a 0 value. So both jump past the remaining Minimal-2D code until the ] is encountered on line 11. But this is short lived because line 12 starts with another [ which takes both languages to almost the end of the polyglot where no further instructions are encountered.

Refactors

Minimal-2D

Minimal-2D’s re-write was mostly to save some bytes in a fashion similar to BF’s multiplication trick. Minimal-2D however doesn’t have the [ and ] characters for loop control. Instead it has these commands:

/ Skips next instruction if the data pointer is set to 0. U Tells the program to switch to the up direction of processing instructions. D Tells the program to switch to the down direction of processing instructions. L Tells the program to switch to the left direction of processing instructions. R Tells the program to switch to the right direction of processing instructions.

These can be used to produce the same logic structure, albeit in a 2D manor, as that of BF. For example, BF’s ++++++[>++++++<-]>. is equivalent to this in Minimal-2D.

Here is a simplified version of Minimal-2D’s code in the polyglot, with all the extraneous code removed and all the place holding characters replaced with # .

###################D ###R+++++[D>+++++++L ###> D>#U/-<+++L) R+.----.R

The D in line 1 sends the instruction pointer down to the L in line 8 of the polyglot which sends the pointer to the left. Here we set the loop control variable (cell 0) to 7, move the memory pointer to cell 1 and enter a loop. In loop, we add 3 to cell 1, decrement cell 0 then check if cell 0’s value is zero yet. If not, we add another 8 to cell 1 then decrement and check again. The result of this loop is cell 1’s value is set to 51 at the end of the loop (6*8+3).

We exit the loop by hopping the U , moving the memory pointer to cell 1 and going down then to the right on line 11 of the polyglot. And finally, we increment up to the ascii value for 4 then decrement down to the ascii value for 0 before running off to the right to end the program.

Retina

Retina had a lot of requirements that were difficult to work with for all the BF derivatives. It doesn’t like consecutive + ’s or mismatched () or [] . But these are really just requirements for every other line, so a lot of the work for BF, SMBF and Minimal-2D revolved around putting the bulk of the code on even numbered lines.

The one byte committed solely to Retina though is the | at the end of line 11. To quote @ais523 “most regexes ending with | will match anything”. Without this, Retina returns 0. Why this fixes it, I don’t know. I haven’t had to dig into Retina too much, probably because I’ve been avoiding the long line. But like Prelude, I’ve found I don’t need to understand it as much as I need to understand how to debug it, which in this case mostly consisted of deleting lines (in multiples of 2) until I’ve found the line that’s causing it to break. I guessed at this fix based on @ais523’s comment, and was rewarded. I’m just too cool for school I guess.

Cardinal

I happened to like @SnoringFrog’s placement of Minimal-2D relative to Cardinal’s code. It’s a good location considering Cardinal doesn’t upset Retina, and it seemed to allow some interweaving with Minimal-2D. So when I set out to transplant Minimal-2D up to 2D land, I brought Cardinal along for the ride. There were a couple cosmetic changes to Cardinal though. First, I threw a > near the beginning of its statement #p x%>~~~+ +~*ttt*.x for Minimal-2D to change memory pointers within its loop/ Second, I shifted everything one character to the right to give Minimal-2D room to exit it’s loop gracefully. The p in this sting is for this character padding.

Befunge/98

The Befunges are actually where I started out trying to golf down the polyglot, since the C++ refactor changed all the other 2D lang code, except this one. In trying to learn WTF was going on in this code, I found this in the Begunge documentation:

The . command will pop a value off the stack and output it as a decimal integer, followed by a space, somewhat like Forth. , will pop a value, interpret it as the ASCII value of a character, and output that character (not followed by a space.)

Holy moley! We can clean up the null bytes on the output. After this, it was all just a matter of figuring out how to input the larger asci values, and segregating the code. Befunge-98 had a jump code ; telling it to skip over the [77*,68*,@ in ;[77*,68*,@;'1,'1,q , which gave us the segregation.

Befunge-98 also had a command ( ' ) to take the ascii code of the next character. So, '1, takes the code asci code for the character 1 , puts it on the stack and then prints the ascii character for the top value on the stack with , . Just gotta do this twice to print 11 and drop a q to quit out gracefully.

Befunge proper is a little less convenient, but only just. Here we have to perform a calculation to put the desired code on the stack. Fortunately, our codes were easily multiplied with 7*7 and 6*8 before the same output command , . Then we quit out of Befunge with @ before its older brother’s code contaminated the output.

Minkolang

After finding a fix for the Befunge’s trailing spaces I got pretty hyped up on the idea of finding a Minkolang fix too and Minkolang’s documentation said that output command that had been used up until this point worked in the same way as the Befunge Interpreter. O happened to be documented as another output command, that wasn’t described as sharing this Begunge-ness, so I just took a shot in the dark and tried outputting the string "3" . Flawless Victory.

><>

One of the first things I looked at when moving the Minimal-2D code was verifying that I could move ><> along with it. If I was going to deal with 2D polyglot transversalism, I was going to deal with all transgressions. I basically luck sacked my way into the solution of putting ;n4 at the end of line 1 and moving the \D further back in line 1. BTW, I didn’t know that ><> could be directed down before answer 40 since it’s been so well contained. I’d like to think this could be used later to diverge ><> from another similar language.

Perl6

I’ve talked about some of Perl6’s <> balancing issues elsewhere in this answer, so I’m not going to go over it again. But I do want to point out that I moved #>27.say# to the second to last line. This doesn’t have a functional purpose in this answer. I actually made this move to satisfy a different answer that I ended up not using this round. I decided to just leave it since I plan to post that answer at my next opportunity and I didn’t want to bother undoing and re-doing it.

Bug Fixes

05as1e

05as1e definitely didn’t like the new Begunge code as much as the old version. I’d suppose it’s the , s since that’s the only revolutionary character. In any event, I had to move the " further back in line two to hide the offensive commands, and I knew that the " had to go prior to the Befunge code path since " was a yes-op in both languages. (I can just make up terms like yes-op right?) Line 2’s 2-dimentionality is pretty rigid, but I was able to displace the < prior to Begunge’s code path with the " . The < however was a requirement of Perl6. (It has to have a < preceding all > s.) I was able to drop the < in line one at a location divined by instinct and foreknowledge resolving 05ab1e and Perl6’s disagreement.

Whirl

The Befunge changes on line 2 added an extra 1 to the polyglot prior to the Incident/Whirl line. This extra 1 caused Whirl to start off pointing to the wrong instructions on the wheel. The very first 1 in the C/C++’s preprocessor directive was only a line number reference in the code, and this could just as easily be any other line number, so I arbitrarily changed this to 4 to satisfy Whirl.

Incident

The detokenizing string at the end of the polyglot is well known at this point, so I won’t go into it. I removed from the string what I could and added the new tokens that were required. There are 2 detokenizing characters that are not in this string though that I should point out. First, the second R in #R+.----.R >]| is needed here because it’s a Fusion starting point, and it was safer on this line because there was already a Fusion starting point heading in the same direction. Second, the x in #= x is to remove a token involved in a ␉␊# pattern, which has become more common.

Others

Hexagony, Whitespace, and Prelude all had the usual minor adjustments, but nothing special worth talking about.

Final Thoughts

That’s all I’ve got for this answer. For those looking for a starting point on the next answer, I’d suggest evil. It seems workable, although I haven’t looked at it too closely, but I suspect it would not be too hard to integrate. I know it has a jump command that should help skip past the bulk of the polyglot. Good luck.