Lazy brainfuck programmer

1

1

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.

Krzysztof Szewczyk

Posted 2019-08-18T15:42:45.540

Reputation: 3 819

Question was closed 2019-08-19T18:10:36.077

Answers

3

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

Jonathan Allan

Posted 2019-08-18T15:42:45.540

Reputation: 67 804

2

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!

Arnauld

Posted 2019-08-18T15:42:45.540

Reputation: 111 334

This is black magic. I assume there's a closure of some kind over p, but I just can't understand this! – wizzwizz4 – 2019-08-18T16:35:52.763

@wizzwizz4 p is defined in the global scope and initialized in the 3rd dummy parameter of replace, before it starts doing its job. – Arnauld – 2019-08-18T16:41:16.207

Could you use the RegEx (or function) as the initial value for p to save a couple of bytes? – Shaggy – 2019-08-18T16:50:37.313

@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$. – Arnauld – 2019-08-18T16:54:35.390

What about s=>s.replace(p=/\d/g,n=>'<'.repeat(p)+'>'.repeat(p=n))? – tsh – 2019-08-19T07:03:31.900

2

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

Jo King

Posted 2019-08-18T15:42:45.540

Reputation: 38 234

1

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

Shaggy

Posted 2019-08-18T15:42:45.540

Reputation: 24 623

Second one is perfectly fine. – Krzysztof Szewczyk – 2019-08-19T16:15:53.340

1

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.

Alex

Posted 2019-08-18T15:42:45.540

Reputation: 417

I don't think this would work if the input had a multidigit number – Embodiment of Ignorance – 2019-08-18T19:48:16.460

2@EmbodimentofIgnorance The spec says single digits. – Arnauld – 2019-08-18T19:58:12.817

'/'<s<':' instead of 46<ord(s)<58 – Embodiment of Ignorance – 2019-08-18T21:06:18.630

Save two by avoiding two prints

– Jonathan Allan – 2019-08-18T22:44:49.833

1

05AB1E, 19 18 bytes

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

Try it online!

Grimmy

Posted 2019-08-18T15:42:45.540

Reputation: 12 521

0

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!

Embodiment of Ignorance

Posted 2019-08-18T15:42:45.540

Reputation: 7 014

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. – my pronoun is monicareinstate – 2019-08-19T09:06:28.113

0

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.

Neil

Posted 2019-08-18T15:42:45.540

Reputation: 95 035

0

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

famous1622

Posted 2019-08-18T15:42:45.540

Reputation: 451