3
\$\begingroup\$

Background

Joe is working on his new Brainfuck answer on Codegolf. The algorithm he's using to solve the challenge is a bit complicated, so Joe came up with idea of simplifying his Brainfuck notation to make programming easier and faster.

The challenge

Let's look at snippet written by Joe a moment ago:

0+++++1+++++0[3+0-]+1[3-2+1-]2[1+2-]3[0-3[-]]

This program was meant to check for equality of #0 and #1 cells in memory. Your task is to create a preprocessor for Joe, that will replace single digits from input with '>' and '<' characters, so the memory pointer will slide to cell specified.

Input

You may take input from any source - function parameter, standard input, or any other device. The input might be in form of a stream, string, or a byte array.

The input may contain characters from all over the ASCII range, but can't contain brainfuck memory pointer instructions (< & >).

All the digits you see in the input are expected to be placed here just for your program.

Output

As Joe didn't write his preprocessor yet, he had to make the code interpretable by hand. That's the result he got:

+++++>+++++<[>>>+<<<-]+>[>>-<+<-]>[<+>-]>[<<<->>>[-]]

There are pretty much no restrictions on output - if the input has braces unbalanced, just copy them over in unbalanced amount to the output.

Bonus tasks

If you think the challenge is too boring in current form, you might want to complete these tasks aswell for slight byte count reduction, and more fun obviously:

  • Optimize out nonsense related to memory operations, like digits at the end of input or clustered digits (just take the last one) - 20% of byte amount when completed

  • Minify Brainfuck output (remove clustered +-, ><, non-brainfuck, comments and other kind of stuff) - 20% of byte amount when completed

Rules

  • Standard loopholes are forbidden by default
  • Default I/O rules apply
  • Programs are scored by their size in bytes.
  • Solving additional tasks reduces the score.
  • If anything is unclear, please let me know down in the comments
  • Scoring of bonus tasks may increase (but not decrease!) in the future.

Opening bid - C, 144 bytes

p,c,x;void g(v){x=v?'<':'>';if(v<0)v*=-1;while(v--)putchar(x);}main(){while((c=getchar())!=-1)if(isdigit(c)){c-=48;g(c-p);p=c;}else putchar(c);}

This program should make pretty much everything clear on the input and output side of this challenge, it doesn't implement any bonus tasks though.

\$\endgroup\$
0

9 Answers 9

3
\$\begingroup\$

Jelly, 18 bytes

V©_¥®N,$Ø<xµ¹e?ØD)

A full program. Assumes (like everyone else has) that no actual Brainfuck evaluation has to be made (no balancing of unbalanced brackets)

Try it online!

How?

V©_¥®N,$Ø<xµ¹e?ØD) - Main Link: list of characters, s
                 ) - for each character, c, in s:
               ØD  -   digits = "0123456789"
              ?    -   if...
             e     -   ...condition: (c) exists in? (digits)
           µ       -   ...then: monadic link:
    ®              -            recall from register (initially 0) 
   ¥               -            last two links as a dyad i.e. f(c, ®):
V                  -              evaluate (c)
 ©                 -              (copy to the register)
  _                -              subtract (®)  i.e. x = value(c) - register
       $           -            last two links as a monad i.e. f(x):
     N             -              negate (x)
      ,            -              pair with (x)  -> [-x,x]
        Ø<         -            list of characters = "<>"
          x        -            repeat (vectorises) - negatives act like 0
            ¹      -   ...else: identity - i.e. f(c) -> c
                   - implicit (smashing) print
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 63 bytes

s=>s.replace(/\d/g,n=>'<>'[+(p<n)].repeat(p<n?n-p:p-n,p=n),p=0)

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ This is black magic. I assume there's a closure of some kind over p, but I just can't understand this! \$\endgroup\$
    – wizzwizz4
    Aug 18, 2019 at 16:35
  • \$\begingroup\$ @wizzwizz4 p is defined in the global scope and initialized in the 3rd dummy parameter of replace, before it starts doing its job. \$\endgroup\$
    – Arnauld
    Aug 18, 2019 at 16:41
  • \$\begingroup\$ Could you use the RegEx (or function) as the initial value for p to save a couple of bytes? \$\endgroup\$
    – Shaggy
    Aug 18, 2019 at 16:50
  • \$\begingroup\$ @Shaggy I don't think so. That would fail if the first referenced cell is not \$0\$ and there's no reason why it should always be \$0\$. \$\endgroup\$
    – Arnauld
    Aug 18, 2019 at 16:54
  • \$\begingroup\$ What about s=>s.replace(p=/\d/g,n=>'<'.repeat(p)+'>'.repeat(p=n))? \$\endgroup\$
    – tsh
    Aug 19, 2019 at 7:03
2
\$\begingroup\$

Perl 6, 48 bytes

{$!=0;S:g{\d}=['<','>'][$/>$!]x abs +$!-($!=$/)}

Try it online!

Substitutes all digits with the appropriate character repeated the difference between the previous amount of times

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

Japt v2.0a0, 20 16 bytes

r\d@Tî< +'>pT=Xn

Try it

Saved 4 bytes porting a comment by tsh on Arnauld's solution which I've been told results in valid BF output.

r\d@Tî< +'>pT=Xn     :Implicit input of string
r                    :Replace
 \d                  :Digits (RegEx /\d/g)
   @                 :Pass each match X through a function
    Tî<              :  T (initially 0) time repeat "<"
        +            :  Append
         '>p         :  Repeat ">"
            T=Xn     :    Convert X to an integer and assign it to T for the next match
\$\endgroup\$
1
  • \$\begingroup\$ Second one is perfectly fine. \$\endgroup\$ Aug 19, 2019 at 16:15
1
\$\begingroup\$

Python 3.6, 93 90 83 79 77 bytes

p=0
for s in input():
 try:a=int(s)-p;s='>'*a+'<'*-a;p+=a
 except:0
 print(s)

Try it online

Thanks to @JonathanAllan for -2 bytes.


Old version 90 bytes:

p=0
for s in input():
 if '/'<s<':':a=int(s);print('>'*(a-p)+'<'*(p-a));p=a
 else:print(s)

Thanks to @EmbodimentofIgnorance for -3 bytes.

\$\endgroup\$
4
  • \$\begingroup\$ I don't think this would work if the input had a multidigit number \$\endgroup\$
    – Gymhgy
    Aug 18, 2019 at 19:48
  • 2
    \$\begingroup\$ @EmbodimentofIgnorance The spec says single digits. \$\endgroup\$
    – Arnauld
    Aug 18, 2019 at 19:58
  • \$\begingroup\$ '/'<s<':' instead of 46<ord(s)<58 \$\endgroup\$
    – Gymhgy
    Aug 18, 2019 at 21:06
  • \$\begingroup\$ Save two by avoiding two prints \$\endgroup\$ Aug 18, 2019 at 22:44
1
\$\begingroup\$

05AB1E, 19 18 bytes

εDdi®α„><®y©@è×]J¦

Try it online!

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

C# (Visual C# Interactive Compiler), 103 99 bytes

x=>{int i=48;foreach(var g in x)Write(g<58&g>47?new string(g-i<0?'>':'<',Math.Abs(i-(i=g))):g+"");}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ 96 bytes by rewriting a single-statement foreach loop into LINQ. This might be possible to improve with Aggregate, but I can't so far. \$\endgroup\$ Aug 19, 2019 at 9:06
  • \$\begingroup\$ Suggest g<i instead of g-i<0 \$\endgroup\$
    – ceilingcat
    Oct 24, 2020 at 5:57
0
\$\begingroup\$

Retina 0.8.2, 27 bytes

\d(\D*)
$*>$1$&$*<
+`<>|<$

Try it online! Explanation:

\d(\D*)

Match a digit and then all intervening non-digits.

$*>$1$&$*<

Slide the memory pointer to the desired cell, then after the intervening code, slide it back to the initial cell.

+`<>|<$

Cancel out any overlapping slides and delete any trailing slides.

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

Pyth, 34 bytes

VzI}N."09IÒ"p*\<Zp*\>KsN=ZK.?pN)

With unprintable string \x96\x02 between ."09I and Ò

Explained:

Vz                                  # For N in input
  I}N."09IÒ"                        # If N is in the packed string 1234567890
               p*\<Z                # Print Z * "<"
                    p*\>KsN         # K = int(N) and print ">" * K
                           =ZK      # Z = K
                              .?pN) # Else print N
\$\endgroup\$

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