45
\$\begingroup\$

Given an input of a program written in oOo CODE, output the BF code that it represents.

Here is a short description of how oOo CODE works:

  • First, all non-alphabetic characters are removed (everything not in the range A-Za-z).

    For example, take the program PROgRam reVERsES giVeN iNPut sEqUENcE (an example given on the esolangs wiki page that does exactly what you'd expect). After this first step, we now have PROgRamreVERsESgiVeNiNPutsEqUENcE.

  • Next, divide all remaining characters into groups of 3. We now have PRO,gRa,mre,VER,sES,giV,eNi,NPu,tsE,qUE,NcE. If there is a trailing group of 1 or 2 characters, discard it.

  • Convert each group of 3 letters into a BF command based on the following table:

    ooo  >
    ooO  <
    oOo  [
    oOO  ]
    Ooo  -
    OoO  +
    OOo  .
    OOO  ,
    

    That is, if the first letter of a group is lowercase, the second is uppercase, and the third is lowercase, it would translate to the command [.

    With our example, this finally becomes the BF program ,[>,]<[.<]+, which does indeed reverse its input.

Since this is , the shortest code in bytes will win.

Test cases:

<empty string> -> <empty string>
A -> <empty string>
Ab -> <empty string>
Abc -> -
AbcD -> -
AbcDe -> -
AbcDef -> --
1A_b%c*D[]e\\\f! -> --
PROgRamreVERsESgiVeNiNPutsEqUENcE -> ,[>,]<[.<]+
\$\endgroup\$
2
  • 27
    \$\begingroup\$ I'm waiting for somebody with an answer in oOo ... \$\endgroup\$
    – Glorfindel
    Feb 28, 2016 at 19:17
  • 18
    \$\begingroup\$ @Glorfindel: Happy to oblige. \$\endgroup\$
    – nneonneo
    Feb 29, 2016 at 2:20

28 Answers 28

130
\$\begingroup\$

oOo, 1569 1515 bytes

Had to be done. Try it here.

Golfed:

oooooooooOoOoooooooooooooooOoOooooooOOOoOoooooooOoOOoOOoOOoOOoOOoOOoOOoOoOoooOOoOOoOOoOOoOOoOOoOOoOOoOoooOoooOOooOOoOooOoOoOoooooOoooOoooooOOooOooOoOOooOoOoOoooooOoOooooOoOoooooOoOooOoOOoooOoOooooooOoOOoOOoOOoOOoOoOoooOOoOOoOOoOOoOOoOoooOoooOOooOOoOOoOooOoOoOoooooOoooOoooooOOooOooOoOOooOoOoOoooooOoOooooOoOoooooOoOooOoOOoooOoOoooOoOOoOOoOOoOOoOOoOOoOooOoOoOoooooOoooOoooooOOooOooOoOOooOoOoOoooooOoOooooOoOoooooOoOooOoOOoooOoOooooooOoOOoOOoOOoOOoOoOoooOOoOOoOOoOOoOOoOoooOoooOOooOOoOOoOooOoOoOoooooOoooOoooooOOooOooOoOOooOoOoOoooooooooOoOoooOOooOooOoOOooOoOoOooooOooOooOooOooOooOooOooOooOooOooOOoOoooooooooooooooooooooooooooooooooooooooooooOoOoooOOooOooOooOooOoOOoOOooOoOoOooooooooooooOoOoooOOooOooOooOooOoOOoOOooOoOoOooooOooOooOooOooOooOooOooOooOOoOooooooooooooOoOoooooooooooooooooooooooooOoOoooOOooOooOooOooOoOOoOOooOoOoOooooooooooooOoOoooOOooOooOooOooOoOOooOooOooOooOooOooOooOoOoooooOooooooooooooooooOoOOoOOoOOoOOoOOoOoOoooOOoOOoOOoOOoOOoOOoOOoOoooOoooOOooOOoOOoOooOooOooOoOoooooOoooooOoooOOoooooOoooOOooOoOoooooooOoOOoOooOooOOoooOOooOOooooooOOooOoOooooOoOooooOooooOooooOooOOoooooOoooOOooOoOoooooooOoOooOooOOoooOOooOOoooOOooOOooooooOOooOoOooooOoOooooooooooooOoOOoOOoOOoOoOoooOOoOOoOOoOOoOoooOoooOOooOooOooOoOooooooooooOoOOoOOoOOoOOoOoOoooOOoOOoOOoOOoOOoOOoOoooOoooOOooOOoOooOoOooooOoOOoOooOooOOoooooOoooOOooOoOoOoooOOooOOooooooOOooOoOooooOoOooooOoooOOoooooOoooOOooOoOoooooooOoOOoOooOooOOoooOOooOOoooOOooOOoooOOOoOooooooooooooOOooOoOoooOOooOooOooOooOooOOooooOOooooOOoooOOoOOooooooooooooooooooooooooOoOooooooOOOoOO

Translated to Brainfuck (with linebreaks for clarity):

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

Ungolfed with explanation:

this progrAm Translates ooo codE tO brainfUCK cOde. i guesS sINcE ThE ExAMpLE
tEXt WAs SeLf-doCUmENtINg, I ShOUlD PrOBaBLy Make This SElf-DOcUmeNtInG too.

oh, I shoUld menTIon ThaT i WRotE tHe OriginAl BrainFuCk code EnTirElY By haNd.
If you waNt TO sEE tHE bRAiNfUck cODe, RUn THiS PrOGrAm wiTh itSElf AS iNPuT!

baSiCaLly, thiS proGram seTS up MemOrY As fOlLoWs: the fIrSt thrEe Bytes aRe
"ValId" FLags (V0, v1, V2), theN tHErE'S a BArRIeR (A 1) fOLlOweD bY tHree
"vaLue" bIts (b0, b1, b2). THe rEst Of THe aRrAy Is basiCaLly juSt ScratcH
sPacE. tO Save SpAce, i'm slIdINg THe POiNTeR fOrwaRD bY OnE In EAcH ItEratIon
uNTil THe POiNteR hItS the baRrieR, at whiCH poInt ThE ProGrAm Prints out tHe
ConvERteD chArACteR.

tHe ProgrAm eXteNsiVelY usEs tHe cLevEr "gReaTEr-Than" comparison operator
described by dheeraj ram aT
hTtp://sTAckOveRflOw.cOm/QUeSTioNs/6168584/BrAinfuck-comparE-2-nUmbeRS. i hAppEn
tO reAlLY lIKe tHiS iMplemEntAtiOn bEcaUse It iS boTh cOMpAct and nestablE,
wHich is critical for my bf code tO wOrk pROpeRly.

I seT up ThE ReQUisItE sTructure, then pErForm A BunCh oF neSteD cOMpaRisOns
ThaT loOk rOugHlY like tHis:

    if(in >= 65 /* capital a */) {
        if(In <= 90 /* CApITaL Z */) {
            vI = 1
            Bi = 1
        } ELsE {
            iF(in >= 97 /* lOWeRCaSE a */) {
                IF(iN <= 122 /* LoWErCAsE z */) {
                    vi = 1
                }
            }
        }
    }

At thE End OF tHEsE coMpaRisOnS, if the V (valid) Bit iS Set, the ProgRAm sTePs
the poiNtER rIghTwaRDs. if IT hiTS the barRIer, It Then gOeS into A big sEt of
nEstED condiTionALs tHaT test the AcCumUlaTEd vaLUe bITs, anD ConSTruct thE
CorReSpondInG character to pRiNT oUT. tHEn It ReseTS bACk TO tHE iNitiAl stATe.

fInaLly, It Reads anotheR iNPuT ChARaCTeR aNd goES bACk TO lOOpINg.

SO tHere You hAVe iT - An Ooo To BrainFuCK cOnvErtER writtEn in OOo (aNd
BrAinfUCk, bY ExtensiON!). siNcE i havE a Few moRe chARacterS to sPAre In This
progRaM, HeRe's A coUPle oF StrESs teST paTTernS:

0123456789ABcDefghijklmnopQRstUvWxyzABcdEfgHijKlmNopQRstuvWXyz!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 
 ~}|{`_^]\[@?>=<;:/.-,+*)('&%$#"!zyXWvutSRqPOnmlkjihgfedcbazyxwvutsrqPoNmlkjihGFEdCBa9876543210

Thanks for the interesting challenge!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ oh god... This is epic! Good job. \$\endgroup\$
    – Riker
    Feb 29, 2016 at 2:23
  • 12
    \$\begingroup\$ ... WOW. I am impressed. For the curious: goo.gl/vbh3h9 (the full Try it online link was too long for obvious reasons). \$\endgroup\$
    – Doorknob
    Feb 29, 2016 at 2:23
  • 1
    \$\begingroup\$ Golfed/optimized out a bunch of chars. New tryit link: goo.gl/ISjwLB \$\endgroup\$
    – nneonneo
    Feb 29, 2016 at 2:45
  • 8
    \$\begingroup\$ THIS IS THE BEST THING I HAVE EVER SEEN ON THIS SITE \$\endgroup\$
    – user43106
    Feb 29, 2016 at 10:03
  • 17
    \$\begingroup\$ @Texenox In that case, welcome to Programming Puzzles and Code Golf! I'm sure you'll find many more answers around that'll contend for that "best thing I have ever seen" spot in your mind :) \$\endgroup\$
    – Sp3000
    Feb 29, 2016 at 10:16
15
\$\begingroup\$

CJam, 36 35 bytes

l{el_eu-},'_f<0+3/W<2fb"><[]-+.,"f=

Test it here.

Explanation

l               e# Read input.
{el_eu-},       e# Discard all characters that don't change in a lower/upper case
                e# transformation, i.e. non-letters.
'_f<            e# Compare with '_' to determine case as 0 or 1.
0+              e# Append a zero.
3/              e# Split into chunks of 3.
W<              e# Discard last chunk.
2fb             e# Convert each chunk from base 2.
",.+-][<>"f=    e# Select the corresponding character for each chunk.
\$\endgroup\$
2
  • \$\begingroup\$ Append a value and discard last chunk: clever! \$\endgroup\$
    – Luis Mendo
    Feb 28, 2016 at 19:37
  • \$\begingroup\$ Ahh, that is really clever \$\endgroup\$
    – Adnan
    Feb 28, 2016 at 21:47
9
\$\begingroup\$

JavaScript (ES6), 94 93 91 85 84 83 bytes

Saved 1 byte thanks to @dev-null

x=>x.replace(/[a-z]/gi,c=>(a+=c<'a'|0)[2]?b+="><[]-+.,"['0b'+a-(a="")]:0,a=b="")&&b

I've tried many variants of this, but this seems to be the shortest. Also works on empty input!

How it works

First, with x.replace(/[a-z]/gi,c=>, we find take each letter c in the input. We set a and b to "" at the other end of the function call, since the function ignores any parameters past the second. a will store a binary string for determining which character we are currently making, and b will store the result.

Now for the confusing part: first, with (a+=+(c<'a')), we append a 0 to a if c is uppercase; 1 otherwise. This expression returns the new value of a, so then we can check if it has reached three chars of length with by checking if the character at index 2 exists:[2]?. If not, we simply end the function with :0.

If a is now three chars in length, it is a binary number between 000 and 111. We can convert this to a decimal number by appending "0b" to the beginning, then forcing the engine to parse it as a number with '0b'+a-0.

However, we still need to reset a to the empty string. We can't just do '0b'+(a="")-0 because that would mean the string parsed is just 0b. Fortunately, when parsed as a number, the empty string becomes 0, so we can replace the 0 with (a="").

Now we have our number, and we can just append the character at that index in "><[]-+.," to b. After the replace is done, we use &&b to return it from the function. (Well, unless the result of .replace is empty, which only happens on empty input and returns the empty string anyway.)

\$\endgroup\$
5
  • \$\begingroup\$ Nice one byte save with: '0b'+a-0 vs +`0b${a}` and +("0b"+a) \$\endgroup\$ Feb 28, 2016 at 22:53
  • \$\begingroup\$ So, replace wins after all! \$\endgroup\$
    – Neil
    Feb 29, 2016 at 0:09
  • \$\begingroup\$ @Neil Yea sorry for leading you down the match trail ... \$\endgroup\$ Feb 29, 2016 at 0:16
  • \$\begingroup\$ Latest version has problems with leading non-letters? \$\endgroup\$
    – Neil
    Feb 29, 2016 at 1:43
  • \$\begingroup\$ @Neil You're right. Fortunately, I managed to golf a byte off of the working version using a trick from the non-working one. \$\endgroup\$ Feb 29, 2016 at 1:51
8
\$\begingroup\$

05AB1E, 35 32 bytes

Code:

á0«3÷\)vyS).uïJC",.+-][<>"Sr@?)\

Using a very clever trick from Martin Büttner, from this answer. Explanation:

á0«                               # Remove all non-alphabetic characters and append a zero
   3÷\                            # Split into pieces of 3 and discard the last one
      )v                          # Wrap everything into an array and map over it
        yS).uï                    # Is uppercase? Converts AbC to [1, 0, 1]
              JC                  # Join and convert from binary to int
                ",.+-][<>"        # Push this string
                          S       # Split the string
                           r@     # Reverse the stack and get the character from that index
                             ?    # Pop and print without a newline
                              )\  # Wrap everything into an array and pop

Try it online!

Uses CP-1252 encoding.

\$\endgroup\$
8
\$\begingroup\$

Retina, 79 75 71 70 bytes

Thanks to randomra for saving 1 byte.

i`[^a-z]

M!`...
m`^
;
+`(.*);(.)
$1$1$2;
T`l
.+
$.&
T`d`_><[]\-+.,
¶

Try it online!

Explanation

i`[^a-z]

We start by removing everything that's not a letter.

M!`...

This splits the string into chunks of three characters by returning all (non-overlapping) 3-character matches. This automatically discard any incomplete trailing chunk.

m`^
;

Prepend a ; to each line. We'll use this as a marker for the base-2 conversion. Speaking of which, we'll simply treat upper-case letters as 1 and lower-case letters as 0.

+`(.*);(.)
$1$1$2;

This does a funny base-2 to unary conversion. At each step we simply double the characters left of the ; and move the ; one to the right. Why does this work? Remember we'll be interpreting lower case as 0 and upper case as 1. Whenever we process a letter, we simply double the running total (on the left) so far - double lower-case letters are just 2*0=0, so they can be completely ignored and upper-case letters represent the binary number so far, so doubling them is what we want. Then we add the current letter to that running total which represents 0 or 1 correspondingly.

T`l

Remove all lower-case letters/zeroes.

.+
$.&

Match each line and replace it with the (decimal) number of characters in that line. Due to the ; this turns the unary number into its decimal equivalent + 1.

T`d`_><[]\-+.,

Transliteration which substitutes 1-8 with the corresponding command.

Remove linefeeds.

\$\endgroup\$
4
  • \$\begingroup\$ That's a clever way to split into chunks of three chars. Have you used this before? \$\endgroup\$ Feb 29, 2016 at 2:03
  • \$\begingroup\$ @ETHproductions I think I have but I'm not sure where. I might be thinking of codegolf.stackexchange.com/a/69518/8478 \$\endgroup\$ Feb 29, 2016 at 7:12
  • \$\begingroup\$ 70 bytes and a bit less shorter with my newly added Retina ideas. \$\endgroup\$
    – randomra
    Mar 1, 2016 at 11:38
  • \$\begingroup\$ @randomra ah nice idea for the ;. I'll edit that in later. \$\endgroup\$ Mar 1, 2016 at 12:15
7
\$\begingroup\$

MATL, 38 32 bytes

'><[]-+.,'jt3Y2m)3ZCtAZ)92<!XBQ)

Try it online!

'><[]-+.,'      % push string with BF commands
j               % read input as a string
t               % duplicate
3Y2             % predefined literal: string 'A...Za...z'
m               % true for elements of input string that are letters
)               % index into input string to keep only letters
3ZC             % 2D array whose columns are non-overlapping slices of length 3.
                % The last column is padded with zeros if needed
tA              % duplicate. True for columns that don't contain zeros 
Z)              % keep those columns only. This removes padded column, if any
92<             % 1 for upper case letters, 0 for lower case letters in the 2D array
!               % transpose so each group of 3 is a row
XBQ             % convert each row from binary to decimal and add 1
)               % index into string containing the BF commands. Implicitly display
\$\endgroup\$
5
\$\begingroup\$

Japt, 37 36 bytes

Uo"%l" f'.³ £",><[]-+."gX®c ¤gJÃn2Ãq

Test it online!

How it works

Uo"%l" f'.³ £  ",><[]-+."gX®   c ¤  gJÃ n2Ã q
Uo"%l" f'.³ mX{",><[]-+."gXmZ{Zc s2 gJ} n2} q

Uo"%l"      // Get rid of all non-letter chars in U.
f'.³        // Take each set of three chars in U.
mX{      }  // Map each item X in this group to:
XmZ{     }  //  Map each letter Z in X to:
Zc s2 gJ    //   Take the char code of Z as a binary string, and take the first char.
            //   This maps each character to 1 if it's UC, or 0 if it's lc.
        n2  //  Interpret the result as a binary number.
",><[]-+."g //  Get the item at this index in this string.
q           // Concatenate the result and implicitly output.
\$\endgroup\$
0
4
\$\begingroup\$

JavaScript (ES6), 111 95 bytes

s=>s.match(/[A-Z]/gi).map(c=>+(c<'a')).join``.match(/.../g).map(g=>'><[]-+.,'['0b'+g|0]).join``

Simply removes non-letters, converts upper case letters into 1s and lower case into 0s, divides into groups of three, ignores a trailing group of 1 or 2, and decodes the groups.

Edit: Saved 16 bytes thanks to @dev-null, although the code no longer works when passed the empty string.

\$\endgroup\$
1
  • \$\begingroup\$ @dev-null Ugh, I had tried the match(/.../g).map().join approach but miscounted the number of bytes and though it didn't save me anything. Thanks for the tip on the first match though. \$\endgroup\$
    – Neil
    Feb 28, 2016 at 21:18
3
\$\begingroup\$

Pyth, 40 bytes

jkm@"><[]-+.,"id2f!%lT3cm?rId0Z1f!rIT2z3

Try it here!

Could save 2 bytes if I can output the result as list of characters instead of a string.

Explanation

Filters out all non-letters, converts uppercase to 1 and lowercase to 0, splits into chunks of 3, interprets every chunk as binary number and uses this as index into a string which contains all BF commands.

jkm@"><[]-+.,"id2f!%lT3cm?rId0Z1f!rIT2z3  # z = input

                                f     z   # filter input with T
                                 !        # logical not
                                  rIT2    # T == swapcase(T), true if T is not a letter
                        m                 # map filter result with d
                         ?rId0            # if d == toLower(d)
                              Z1          # 0 for lowercase, 1 for uppercase
                       c               3  # Split into chunks of 3, last element is shorter if needed
                 f                        # filter with T
                  !                       # logical not
                   %lT3                   # len(t) mod 3 -> keep only elements of length 3
  m                                       # map with d
              id2                         # Convert from binary to decimal
   @"><[]-+.,"                      # Get the resulting BF command
jk                                        # Join to a string
\$\endgroup\$
3
\$\begingroup\$

Jolf, 31 34 bytes

Try it here! Replace with \x10 and with \x05. Because I implemented the chop function wrong, I gain 3 bytes. :(

►ΜZeZcAAρi♣Epu1pl033d."><[]-+.,"ΙH
        ρi♣E                        remove all space in input
       A    pu1                     replace all uppercase letters with 1
      A        pl0                  replace all lowercase letters with 0
    Zc            3                 chop into groups of three
  Ze               3                keep groups of length three
 Μ                  d               map
                              ΙH   parse element as binary
                     ."><[]-=.,"    and return a member of that
►                                  join by nothing
\$\endgroup\$
0
3
\$\begingroup\$

Python 3, 91 bytes

b=1
for c in input():
 b=-~c.isalpha()*b+c.isupper()
 if b>7:print(end="><[]-+.,"[b-8]);b=1

Hmm... looks a bit long, especially the second line. b=[b,2*b+(c<'a')][c.isalpha()] is slightly worse though.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Using end like that is really smart. I've never seen that before. \$\endgroup\$ Feb 29, 2016 at 1:46
3
\$\begingroup\$

Hoon, 212 bytes

=+([v=turn c=curr q=cold k=tape] |=(t/k `k`(v (v `(list k)`(need ((unit (list k)) p:(rose (murn t (c rush alf)) (star (stun [3 3] ;~(pose (q '0' low) (q '1' hig))))))) (c scan bin)) (c snag (rip 3 '><[]-+.,')))))

Ungolfed:

|=  t/tape
^-  tape
%+  turn
  %+  turn  ^-  (list tape)
  %-  need  %-  (unit (list tape))
    =+  t=(murn t (curr rush alf))
    p:(rose t (star (stun [3 3] ;~(pose (cold '0' low) (cold '1' hig)))))
  (curr scan bin)
(curr snag (rip 3 '><[]-+.,'))
  1. use ++murn to get rid of all characters in the input that can't be parsed with "alf" (alphabet)
  2. parse the list with a combinator that outputs each 3 characters at a time to a list, replacing lowercase with '0' and uppercase with '1'
  3. Cast the result to (unit (list tape)) and forcibly unwrap it to get the furthest parsed result, to work with only multiple of threes without crashing
  4. Map over the list, parsing each group as if it were binary
  5. Use each number in the list as an index into the text '><[]-+.,', and cast the list back out to a tape.

Hoon doesn't have proper regular expressions, only a parser combinator library, so it's sadly pretty verbose. ++scan also crashes if the entire input stream isn't parsed, so I have to use ++rose, coerce it into a unit, and unwrap it for the "farthest parse" value. It also makes heavy use for currying and mapping over lists (++turn), so I alias the function names to one letter variables.

Hoon is the programming language for Urbit, a clean slate reimplementation project. It's purely functional, statically typed, vaguely lisp-like, and compiles to Nock. Nock is a combinator based VM that runs on top of a binary tree bignum memory model.

When you boot Urbit you are dropped into :dojo, the shell and Hoon repl. To run the snippet simply type:

%.  "PROgRam reVERsES giVeN iNPut sEqUENcE"

and then paste the standalone function on the next line.

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to PPCG! You answer is fairly well explained, but could you link in an interpreter or a place to try it online? \$\endgroup\$ Feb 29, 2016 at 0:07
  • \$\begingroup\$ I added a link to Urbit's github page, since building it is pretty much the only way. Is that sufficient? \$\endgroup\$ Feb 29, 2016 at 0:18
  • \$\begingroup\$ Absolutely. :D Leaving instructions on how to use this in a full program as well would be wonderful. \$\endgroup\$ Feb 29, 2016 at 0:25
3
\$\begingroup\$

Jelly, 27 bytes

=Œs¬Tịµ=Œu;0s3ṖḄ€ị“<[]-+.,>

Try it online! Note that backslashes need escaping in the input string for the second last test case.

Implicit input: string s (list of characters)

=Œs             Compare with swapcase
¬               Not - this gives 1 for letters, 0 otherwise
Tị              Take characters at truthy indices
µ               Start a new monadic chain

Input: string s' (list of letters)

=Œu             Compare with uppercase
;0              Append 0
s3              Split into chunks of length 3
Ṗ               Pop last chunk
Ḅ€              Apply convert-from-binary to each chunk
ị“<[]-+.,>      For each number, 1-based index cyclically into the string "<[]-+.,>"
\$\endgroup\$
2
\$\begingroup\$

Matlab, 98 bytes

function t(s);s=s(isletter(s));s=s(1:end-mod(end,3));r='><[]-+.,';r([4 2 1]*reshape(s<92,3,[])+1)
  1. Clean
  2. Trim
  3. reshape into a 3xn Matrix m with UC = 1, lc =0
  4. (4 2 1)*m+1 results in an index list
  5. Index to the right chars
\$\endgroup\$
2
\$\begingroup\$

Vyxal, 154 bitsv2, 19.25 bytes

Ǎvæ3ẇ'L3=;vBkTṖ»AǑ»iiṅ

Try it Online!

Ǎ                      # remove non alphabeticals
 væ                    # get the case of each char (0 for lower, 1 for upper)
   3ẇ                  # wrapped into chunks of length 3
     'L3=;             # keep only those of length 3
          vB        i  # converted from binary and indexed into
            kTṖ»AǑ»i   # the 16560th permutation of the BF instruction set
                     ṅ # join by nothing
\$\endgroup\$
1
\$\begingroup\$

Perl, 76 73 72 + 1 = 73 bytes

$a.=y+A-Z++dfor/[A-Z]/gi;print substr"><[]-+.,",oct"0b$_",1for$a=~/.../g

Requires the -n flag:

$ perl -n oOo.pl <<< 'PROgRamr{}\eVERsESgiVeNiNPutsEqUENcE'
,[>,]<[.<]+

Using the trick with base-2 conversion.

How it works:

                          # '-n' auto read first line into `$_`
            for/[A-Z]/gi; # Iterate over all letters a-z
$a.=y/A-Z//d              # Count number of uppercase letters (1 or 0)

                                  for$a=~/.../g # Split $b into hunks of 3 characters. And
                                                # remove any potential trailing characters.
      substr"><[]-+.,",oct"0b$_",1              # `oct("0b$binary")` will convert binary
                                                # to decimal.
print
\$\endgroup\$
1
\$\begingroup\$

Julia, 107 bytes

s->"><[]-+.,"[map(j->parse(Int,j,2)+1,[map(i->i<'_'?'1':'0',m)for m=matchall(r"\w{3}",filter(isalpha,s))])]

This is an anonymous function that accepts a string and returns a string. To call it, assign it to a variable.

Ungolfed:

function f(s)
    # Brainfuck commands
    bf = "><[]-+.,"

    # Filter out non-alphabetic characters from the input
    chars = filter(isalpha, s)

    # Get all non-overlapping groups of three characters
    groups = matchall(r"\w{3}", chars)

    # Construct binary strings by comparing to _
    binary = [map(i -> i < '_' ? '1' : '0', m) for m = groups]

    # Parse each binary string as an integer and add 1
    indices = map(j -> parse(Int, j, 2) + 1, binary)

    # Return the Brainfuck commands at the indices
    return bf[indices]
end
\$\endgroup\$
1
\$\begingroup\$

Lua, 120 Bytes

Big use of string.gsub() here, one more time could have allowed me to create a one character pointer on this function to gain some bytes. Also, it is my first lua program without any spaces! :D

This program takes its input via command-line argument and output a BrainFuck program, one command per line.

Edit: Saved 1 Byte thanks to @Oleg V. Volkov

arg[1]:gsub("[%A]",""):gsub("%l",0):gsub("%u",1):gsub("...",function(c)x=1+tonumber(c,2)print(("><[]-+.,"):sub(x,x))end)

Ungolf and explanations

arg[1]:gsub("[%A]","")    -- replace the non-letter character by an empty string
                          -- %A matches all the character not in %a (letters)
:gsub("%l",0)             -- replace lower case letters by 0s
:gsub("%u",1)             -- replace upper case letters by 1s
:gsub("...",function(c)   -- iterate over all groupe of 3 characters
  x=tonumber(c,2)+1       -- convert the 3-letter group from binary to decimal
  print(("><[]-+.,")      -- output the corresponding brainfuck command
             :sub(x,x))   
end)
\$\endgroup\$
3
  • \$\begingroup\$ You can save one byte on inlining b and one more on saving string.gsub to shorter var and manually folding first arguments to it: g=("").gsub g(g(g(g(arg[1],"[%A]",""),"%l",0),"%u",1),"...",function(c)x=1+tonumber(c,2)print(("><[]-+.,"):sub(x,x))end) \$\endgroup\$ Feb 29, 2016 at 19:15
  • \$\begingroup\$ ...or maybe I misread byte count on folding. Inlining still works. \$\endgroup\$ Feb 29, 2016 at 19:31
  • \$\begingroup\$ @OlegV.Volkov Saving to a shorter var costs, sadly, more, I tried the same thing ^^. And thanks for the inlining of b... I don't know why I saved it in a var... \$\endgroup\$
    – Katenkyo
    Mar 1, 2016 at 7:36
1
\$\begingroup\$

Python 2, 112 bytes

''.join('><[]-+.,'[int('%d'*3%tuple(map(str.isupper,y)),2)]for y in zip(*[iter(filter(str.isalpha,input()))]*3))

Will try to golf it more.

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

Mathematica, 192 bytes

StringJoin[FromDigits[#,2]&/@Partition[ToCharacterCode@#-48,3]&[StringDelete[#,a_/;!LetterQ[a]]~StringReplace~{_?UpperCaseQ->"1",_?LowerCaseQ->"0"}]/.Thread[0~Range~7->Characters@"><[]-+.,"]]&

Anonymous function that takes the desired string as an argument. Steps in the (pretty straightforward) algorithm:

  1. Clean the string
  2. Replace UC->"1", lc->"0"
  3. Turn the string into a binary list
  4. Partition the list into threes and interpret each chunk as a base-2 number
  5. Replace the numbers with their appropriate symbols and join back into a string.
\$\endgroup\$
1
\$\begingroup\$

Ruby 117 114 113 111 86 79 Bytes

gets.tr(?^+m='a-zA-Z','').tr(m,?0*26+?1).scan(/.../){$><<"><[]-+.,"[$&.to_i 2]}
  • tr(?^+m='a-zA-Z','') sets m to 'a-zA-Z' and removes non-letters
  • .tr(m,?0*26+?1) converts lowercase to 0, uppercase to 1
  • .scan(/.../) chunk string into groups of 3 and discard last group if it has less than 3
  • {$><<"><[]-+.,"[$&.t‌​o_i 2]} convert each binary number to a character
\$\endgroup\$
6
  • \$\begingroup\$ Can't you use tr("a-zA-Z","01")? or even tr("A-Za-z",10) \$\endgroup\$ Feb 29, 2016 at 0:12
  • \$\begingroup\$ @dev-null "AAz".tr("a-zA-Z","01") gives 111 \$\endgroup\$
    – FuzzyTree
    Feb 29, 2016 at 0:19
  • 1
    \$\begingroup\$ So much that can be done here. This is a start: gets.delete('^a-zA-Z').tr("a-z",?0).tr("^0",?1).scan(/.../){$><<"><[]-+.,"[$&.to_i 2]} (86 bytes). Changed the input from command line option to stdin; fixed the surrounding quotes in the output (but now it has no trailing newline) \$\endgroup\$
    – daniero
    Feb 29, 2016 at 6:44
  • \$\begingroup\$ @daniero thanks! made this a community answer. feel free to make changes \$\endgroup\$
    – FuzzyTree
    Mar 1, 2016 at 0:49
  • 1
    \$\begingroup\$ tr(^a-zA-Z','').tr('a-zA-Z',?0*26+?1) is shorter \$\endgroup\$ Mar 1, 2016 at 23:08
1
\$\begingroup\$

Perl 6, 81 bytes

This can probably be done better, but this is my go at it

{m:g/:i<[a..z]>/;[~] ("><[]-+.,".comb[:2[$_]]for (+(91>$_.ord)for |$/).rotor(3))}

Usage

> my &f = {m:g/:i<[a..z]>/;[~] ("><[]-+.,".comb[:2[$_]]for (+(91>$_.ord)for |$/).rotor(3))}
-> ;; $_? is raw { #`(Block|149805328) ... }
> f("PROgRamreVERsESgiVeNiNPutsEqUENcE")
,[>,]<[.<]+

Ungolfed

sub oOo ($_) {
    m:g/:i<[a..z]>/;  # Match all letters and put them in $/
    
    my @digits = (                
        for |$/ -> $c {           # For all $c in $/
            +(91>$c.ord)          # 1 if $c.ord < 91 else 0
        }
    );
    @digits.=rotor(3);            # Split the digits into chunks of 3
              
    my @chars = (
        for @digits -> @l {
            "><[]-+.,".comb[:2[@l]] # Take the character from "><[]-+.,"
                                    # at an index given by converting 
                                    # @l (a list of 3 binary digits)
                                    # from base 2 to base 10
        }
    );
    @chars.join # Join the list of chars into a string and return
}
\$\endgroup\$
1
\$\begingroup\$

C++, 173 167 bytes

Full program, golfed (reads from standard input):

#include <cstdio>
main(){for(char*a="@[`{>-[.<+],",c,o=0,t=1;(c=getchar())>0;)if(c=c>*a&&c<a[1]?2:c>a[2]&&c<a[3]?1:0){o|=c>1?t:0;t*=2;if(t>4)putchar(a[o+4]),o=0,t=1;}}

Somewhat ungolfed:

#include <cstdio>
main(){
    for(char*a="@[`{>-[.<+],",c,o=0,t=1;(c=getchar())>0;)
        if(c=c>*a&&c<a[1]?2:c>a[2]&&c<a[3]?1:0){
            o|=c>1?t:0;
            t*=2;
            if(t>4)putchar(a[o+4]),o=0,t=1;            
        }
}

Note that @A ... Z[ in ASCII, and likewise for `a ... z}.

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

Japt v2.0a0 -P, 27 bytes

r\L ò3 l3 Ëmè\A Íg"><[]-+.,

Saved 3 bytes thanks to @Shaggy

Try it

\$\endgroup\$
2
  • \$\begingroup\$ 29 bytes \$\endgroup\$
    – Shaggy
    Apr 29, 2019 at 9:23
  • \$\begingroup\$ 26 bytes \$\endgroup\$
    – Shaggy
    May 18, 2023 at 20:45
0
\$\begingroup\$

Pyke, 31 bytes, noncompetitive

Pyke is older than the challenge, but I added some features to make it more competitive - chunk function. I used the same trick as @Martin Büttner used.

#~l{)\`Lm<0+3cFb2"><[]-+.,"@)st

Try it here!

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

JavaScript, 148 bytes

function a(s){function b(c){return c.charCodeAt()&32}return (l=(s=s.replace(/[^a-z]/gi)).substr(3))?",.+-][<>"[b(s[0])*4+b(s[1])*2+b(s[2])]+a(l):""}
\$\endgroup\$
0
\$\begingroup\$

TI-BASIC, 311 288 bytes

What, no TI-BASIC answers? Time for me to fix that!

Ans→Str1:" →Str2:" →Str6:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str4:For(S,1,length(Str1:sub(Str1,S,1:If inString(Str4+"abcdefghijklmnopqrstuvwxyz",Ans:Str2+Ans→Str2:End:sub(Str2,2,length(Str2)-1→Str2:For(B,1,.1+3⁻¹length(Str2:sub(Str2,3B-2,3→Str3:1+sum({4,2,1}seq(0≠inString(Str4,sub(Str3,X,1)),X,1,3→L₁(B:End:For(C,1,.1+dim(L₁:Str6+sub("><[]-+.,",L₁(C),1→Str6:End:sub(Str6,2,length(Str6)-1→Str6

Input is the oOo code in Ans.
Output is the translated BF code.

Examples:

"AbcDef
AbcDef
prgmCDGF18
--
"PROgRam reVERsES giVeN iNPut sEqUENcE
PROgRam reVERsES giVeN iNPut sEqUENcE
prgmCDGF18
.[>,]<[.<]+
"AbcDe
AbcDe
prgmCDGF18
-

Un-golfed:
(Newlines and comments added)

Ans→Str1                                                   ;store the input in "Str1"
" →Str2                                                    ;set "Str2" and "Str6" to a
" →Str6                                                    ; space character
                                                           ; (needed b/c TI-BASIC doesn't
                                                           ;  like concatenating empty
                                                           ;  strings)

"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str4                           ;store the uppercase alphabet
                                                           ; in "Str4"
For(S,1,length(Str1                                        ;loop over the input string
sub(Str1,S,1                                               ;get the current character
If inString(Str4+"abcdefghijklmnopqrstuvwxyz",Ans          ;if the character is in either
                                                           ; the uppercase or lowercase
                                                           ; alphabet
Str2+Ans→Str2                                              ;add it to "Str2", the code
                                                           ; string
End
sub(Str2,2,length(Str2)-1→Str2                             ;remove the space added earlier
For(B,1,.1+3⁻¹length(Str2                                  ;loop over each 3-char substring
                                                           ; and skip any extra chars
                                                           ; (.1 is added to force one
                                                           ;  loop)
sub(Str2,3B-2,3→Str3                                       ;store said substring in "Ans"
1+sum({4,2,1}seq(0≠inString(Str4,sub(Str3,X,1)),X,1,3→L₁(B ;convert to the respective
                                                           ; index in "><[]-+.,"
                                                           ; (1-indexed)
End
For(C,1,.1+dim(L₁                                          ;loop over each index
                                                           ; (.1 is added to force one
                                                           ;  loop)
Str6+sub("><[]-+.,",L₁(C),1→Str6                           ;add the char to the translation
                                                           ; string
End
sub(Str6,2,length(Str6)-1→Str6                             ;remove the added space and
                                                           ; store the result in "Str6"
                                                           ; and "Ans"
                                                           ;implicit print of "Ans"

Notes:

  • TI-BASIC is a tokenized language. Character count does not equal byte count.
\$\endgroup\$
0
\$\begingroup\$

Thunno 2 J, 21 bytes

Ị³fæl3=;2ȷḋkŻ8ṗ«@ṅisi

Attempt This Online!

Port of emirps's Vyxal answer.

Explanation

Ị³fæl3=;2ȷḋkŻ8ṗ«@ṅisi  # Implicit input
Ị                      # Remove non-alphabets
 ³                     # Split into groups of length 3
  f                    # Case of each character in each group
   æ   ;               # Filtered by:
    l                  #  Length
     3=                #  Equals 3
         ȷ             # To each:
        2 ḋ            #  Convert from binary
           kŻ          # Push "[]<>-+.,"
             8ṗ        # All permutations
               «@ṅ     # Compressed integer 16560
                  i    # Index into permutations
                   si  # Index into the above
                       # Implicit output of joined list
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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