Skip to content

Instantly share code, notes, and snippets.

@mattboehm
Last active December 7, 2016 04:52
Show Gist options
  • Save mattboehm/c7b51d2e6cda0c868d66cfa97b47fb3a to your computer and use it in GitHub Desktop.
Save mattboehm/c7b51d2e6cda0c868d66cfa97b47fb3a to your computer and use it in GitHub Desktop.
//Please excuse the horrible comments. Maybe when my head works again I'll clean this up. Tested at https://sange.fi/esoteric/brainfuck/impl/interp/i.html
// {x} {y} {tmp0=0} {tmp1=0} {dir = 0 to 3} {num}
// ^
//{tmp1}
, //read L/R
[
---------------------------------------------------------------------------- //subtract 76 to make L 0
[ //if it's not 0 (It was an R)
> //{tmp2(0)}
++ //{add 2 to dir}
<[-] //{tmp1=0}
]
>- //{dir} sub1
// if dir is 4 make it 0
---- //subtract 4 from dir
[<+<+>>-] //move dir to tmp0 and tmp1 (dir dir (0))
<<[>>+<<-]+ // move tmp0 to dir and make tmp0=1 ((1) dir dir)
>[<->[-]] //if tmp1 clear tmp0 then clear tmp1 dir==0: (1 (0) dir) dir == 1: (0 (0) dir)
<[ //if tmp0 is nonzero then it wasn't cleared and dir was nonzero
>>---- //subtract 4 more from dir
<<-] //clear tmp0
>>++++ //add 4 to dir
// if dir is neg1 make it 3
+ //add 1 to dir
[<+<+>>-] //move dir to tmp0 and tmp1 (dir dir (0))
<<[>>+<<-]+ // move tmp0 to dir and make tmp0=1 ((1) dir dir)
>[<->[-]] //if tmp1 clear tmp0 then clear tmp1 dir==0: (1 (0) dir) dir == 1: (0 (0) dir)
<[ //if tmp0 is nonzero then it wasn't cleared and dir was nonzero
>>++++ //add 4 to dir
<<-] //clear tmp0
>>- //subtract 1 from dir
> //goto num
// Read digits from input until a comma is reached; converting to ascii to decimal
// Modified from Urban Muller's algorithm
[-]>[-]+ // Clear sum
[[-] // Begin loop on first temp
>[-], // Clear the inp buffer to detect leave on eof and input
[
+[ // Check for minus one on eof
---------------------------------------------[ // Check for comma
---- // Subtract 4 to get the char in zero to nine
<<[->>++++++++++<<] // Multiply the existing value by ten
>>[-<<+>>] // and add in the new char
<+>]
]
]
<]
<
//num is the number
< //back to dir
// if dir is 0 move north
//subtract 0 from dir
[<+<+>>-] //move dir to tmp0 and tmp1 (dir dir (0))
<<[>>+<<-]+ // move tmp0 to dir and make tmp0=1 ((1) dir dir)
>[<->[-]] //if tmp1 clear tmp0 then clear tmp1 dir==0: (1 (0) dir) dir == 1: (0 (0) dir)
<[ //if tmp0 is nonzero then it wasn't cleared and dir was nonzero
>>> //back to num
[-<<<<+>>>>] //add num to y (destructive)
<<<-] //clear tmp0
>> //back to dir
// if dir is 1 move east
- //subtract 1 from dir
[<+<+>>-] //move dir to tmp0 and tmp1 (dir dir (0))
<<[>>+<<-]+ // move tmp0 to dir and make tmp0=1 ((1) dir dir)
>[<->[-]] //if tmp1 clear tmp0 then clear tmp1 dir==0: (1 (0) dir) dir == 1: (0 (0) dir)
<[ //if tmp0 is nonzero then it wasn't cleared and dir was nonzero
>>> //back to num
[-<<<<<+>>>>>] //add num to x (destructive)
<<<-] //clear tmp0
>>+ //add 1 to o dir
// if dir is 2 move south
-- //subtract 2 from dir
[<+<+>>-] //move dir to tmp0 and tmp1 (dir dir (0))
<<[>>+<<-]+ // move tmp0 to dir and make tmp0=1 ((1) dir dir)
>[<->[-]] //if tmp1 clear tmp0 then clear tmp1 dir==0: (1 (0) dir) dir == 1: (0 (0) dir)
<[ //if tmp0 is nonzero then it wasn't cleared and dir was nonzero
>>> //back to num
[-<<<<->>>>] //subtract num from y (destructive)
<<<-] //clear tmp0
>>++ //add 2 to dir
// if dir is 3 move west
--- //subtract 3 from dir
[<+<+>>-] //move dir to tmp0 and tmp1 (dir dir (0))
<<[>>+<<-]+ // move tmp0 to dir and make tmp0=1 ((1) dir dir)
>[<->[-]] //if tmp1 clear tmp0 then clear tmp1 dir==0: (1 (0) dir) dir == 1: (0 (0) dir)
<[ //if tmp0 is nonzero then it wasn't cleared and dir was nonzero
>>> //back to num
[-<<<<<->>>>>] //subtract num from x (destructive)
<<<-] //clear tmp0
>>+++ //add 3 to dir
<,,] //eat space and read the next character into tmp1
<<< 0 0 0 0 0 (x) y 0
t1 t0 x1 x0 neg (x) y num
move to x0/x1/t0
[<<+<+<+>>>>-]
move t0 to to x
<<<<[>>>>+<<<<-]
t0 cleared
>>[ while x0 nonzero
<+ inc x1
//if x1 reached 0 first
[<+<+>>-] //move x1 to t0 and t1 (x1 x1 (0))
<<[>>+<<-]+ // move t1 to x1 and make t1=1 ((1) x1 x1)
>[<->[-]] //if t0 clear t1 then clear t0 x1==0: (1 (0) x1) x1 == 1: (0 (0) x1)
<[ //if t1 is nonzero then it wasn't cleared and x1 was zero
>>>>+ //neg=1
<<<<
-] //clear t1
>>> //back to x0
- dec x0
]
<[-] clear x1
>> neg
[ if neg subtract x from num (clearing x)
> x
[>>+<<+]
< - //clear neg
]
> x
[>>+<<-] // move x to num
> y
t1 t0 y1 y0 neg (y) num
move to y0/y1/t0
[<<+<+<+>>>>-]
move t0 to to y
<<<<[>>>>+<<<<-]
t0 cleared
>>[ while y0 nonzero
<+ inc y1
//if y1 reached 0 first
[<+<+>>-] //move y1 to t0 and t1 (y1 y1 (0))
<<[>>+<<-]+ // move t1 to x1 and make t1=1 ((1) y1 y1)
>[<->[-]] //if t0 clear t1 then clear t0 y1==0: (1 (0) y1) y1 == 1: (0 (0) y1)
<[ //if t1 is nonzero then it wasn't cleared and y1 was zero
>>>>+ //neg=1
<<<<
-] //clear t1
>>> //back to y0
- dec y0
]
<[-] clear y1
>> neg
[ if neg subtract y from num (clearing y)
> y
[>+<+]
< - //clear neg
]
> y
[>+<-] // move y to num
> num
>>[-]<< clear a cell that still has data in it
convert decimal to ascii and print (from "Print value of cell x as number for ANY sized cell")
[>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]
++++++++[<++++++>-]>[<<+>>-]>[<<+>>-]<<]>]<[->>++++++++[<++++++>-]]<[.[-]<]<
@mattboehm
Copy link
Author

Some parts of this code have been adapted from https://esolangs.org/wiki/Brainfuck_algorithms#if_.28x.29_.7B_code1_.7D_else_.7B_code2_.7D and other examples on that page

@mattboehm
Copy link
Author

Note that this will produce the wrong answer if the final x/y coordinates exceed values representable by a signed byte. One could use a bf interpreter with a bigger variable size, but as the algorithm has many places where it wraps-around, this would be very slow (and indeed freezes the interpreter I tried it on.)

@mattboehm
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment