Skip to content

Instantly share code, notes, and snippets.

@mattboehm
Created December 3, 2016 07:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattboehm/e7cceab6030b24fe3d2b16f885f7f196 to your computer and use it in GitHub Desktop.
Save mattboehm/e7cceab6030b24fe3d2b16f885f7f196 to your computer and use it in GitHub Desktop.
//advent of code 2016 part 2; will give wrong answer if x/y/distance don't fit in a signed byte
// {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
while num
[
< //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
dir
move x to head_key0
<<<<x[>>>>>>>head_key0 + <<<<<<<x -]
move y to head_key1
>y[>>>>>>>head_key1 + <<<<<<<y -]
>>>>>head_full
============================ set code ====================================={{{
Simple Set in bf
Supports single add operation which returns whether or not the cell was already in the set
This set is an array of cells that continually grows to the right
Each cell looks like this:
( full | key0 | key1 | temp0 | temp1 | temp2 | temp3)
There is a head cell with full set to 0
The key to add is copied into its key0/key1 slot
Starting on head full
move the key into temp0/temp1
>key0
[ {fcell>{fkey>>}{ftemp>>>>}}{fkey>>}+{bkey<<}{bcell{btemp<<<<}{bkey<<}<}-]
>key1
[ {fcell>{fkey>>}{ftemp>>>>}}{fkey>>}+{bkey<<}{bcell{btemp<<<<}{bkey<<}<}-]
{bkey<<} head_full {fcell>{fkey>>}{ftemp>>>>}} 1_full
[ while this cell isn't empty
temp3 = num_matched_keys = 2
>key0 {fkey>>} temp0 >>> temp3 ++
<<< temp0
check if key0 == temp0
move temp0 to temp2 and subtract from key0
temp0 [ >>temp2 + <<temp0{bkey<<}key0 - {fkey>>}temp0 - ]
move temp2 back to temp0
>> temp2 [<<temp0+ >>temp2-]
<<temp0{bkey<<}key0
key0[ if key0 != 0 then the key is different and we should dec num_matched_keys (temp3)
{fkey>>}temp0>>>temp3 -
<<<temp0{bkey<<}key0
move key0 (remainder)into temp2
[{fkey>>}temp0>>temp2 + <<temp0{bkey<<}key0 -]
]
restore key0
move remainder back from temp2 to key0
{fkey>>}temp0>>temp2 [<<temp0{bkey<<}key0 + {fkey>>}temp0>>temp2 -]
add temp0 back to key0 and move into temp2
<<temp0 [{bkey<<}key0 + {fkey>>}temp0>>temp2 + <<temp0 -]
move temp2 back into temp0
>>temp2 [<<temp0 + >>temp2 -]
<temp1
check if key1 == temp1
move temp1 to temp2 and subtract from key0
temp1 [ >temp2 + <temp1{bkey<<}key1 - {fkey>>}temp1 - ]
move temp2 back to temp1
> temp2 [<temp1+ >temp2-]
<temp1{bkey<<}key1
key1[ if key1 != 0 then the key is different and we should dec num_matched_keys (temp3)
{fkey>>}temp1>>temp3 -
<<temp1{bkey<<}key1
move key1 (remainder)into temp2
key1[{fkey>>}temp1>temp2 + <temp1{bkey<<}key1 -]
]
restore key1
move remainder back from temp2 to key1
{fkey>>}temp1>temp2 [<temp1{bkey<<}key1 + {fkey>>}temp1>temp2 -]
add temp1 back to key1 and move into temp2
<temp1 [{bkey<<}key1 + {fkey>>}temp1>temp2 + <temp1 -]
move temp2 back into temp1
>temp2 [<temp1 + >temp2 -]
temp2
check if both keys matched (if num_matched_keys(temp3) == 2)
temp2 + put marker in temp2
>temp3 -- dec temp3 by 2
temp3[ if nonzero remove temp2 marker
<temp2 - >temp3 [+]
]
<temp2 [ if temp2 marker is still there then both keys did match
[-] reset temp2 marker
>temp3 + set temp3 marker
push temp0 temp1 temp3 back to the head node
<<<temp0{bkey<<}key0<full
full[ while the node has contents move data back 1 cell
>key0{fkey>>}temp0[
{bcell{btemp<<<<}{bkey<<}<}prev_temp0 +
{fcell>{fkey>>}{ftemp>>>>}} temp0 -
]
>temp1[
{bcell{btemp<<<<}{bkey<<}<}prev_temp1 +
{fcell>{fkey>>}{ftemp>>>>}} temp1 -
]
>>temp3[
{bcell{btemp<<<<}{bkey<<}<}prev_temp3 +
{fcell>{fkey>>}{ftemp>>>>}} temp3 -
]
go to this cell's full
<<<temp0{bkey<<}<full
go back to prev cell
{bcell{btemp<<<<}{bkey<<}<}
]
>key0{fkey>>}temp0>>temp2
]
temp2
if !temp3 we need to jump forward a cell
temp2 = !temp3
temp2 +
>temp3[ <temp2- >temp3{fcell>{fkey>>}{ftemp>>>>}}next_temp3 + {bcell{btemp<<<<}{bkey<<}<}temp3 -]
{fcell>{fkey>>}{ftemp>>>>}}next_temp3[{bcell{btemp<<<<}{bkey<<}<}temp3 + {fcell>{fkey>>}{ftemp>>>>}}next_temp3 -]
{bcell{btemp<<<<}{bkey<<}<}temp3
temp3
<temp2[ if temp2: move temp0/temp1 forward a cell and jump
[-] clear temp2
<<temp0[ {fcell>{fkey>>}{ftemp>>>>}}next_temp0 + {bcell{btemp<<<<}{bkey<<}<}temp0 -]
>temp1[ {fcell>{fkey>>}{ftemp>>>>}}next_temp1 + {bcell{btemp<<<<}{bkey<<}<}temp1 -]
>temp2 {fcell>{fkey>>}{ftemp>>>>}}next_temp2
]
(temp2 | next_temp2)
<<temp0{bkey<<}key0<full
]
Either we found a match and we're back on the head cell with temp3 set
Or reached the end of the list and we're on that head cell
If temp3 is not set we need to add this key and go back to the start of the set
full>key0{fkey>>}temp0>>temp2
t2 0 t3 0 t2 0 t3 1
temp2 + t2 1 t3 0 t2 1 t3 1
>temp3 [<temp2 - >temp3 -] t2 1 t3 0 t2 0 t3 0
<temp2 [
copy temp0 to key0 (using temp3 as buffer)
<<temp0[{bkey<<}key0 + {fkey>>}temp0>>>temp3 + <<<temp0 - ]
>>>temp3[<<<temp0 + >>>temp3 -]
copy temp1 to key1 (using temp3 as buffer)
<<temp1[{bkey<<}key1 + {fkey>>}temp1>>temp3 + <<temp1 - ]
>>temp3[<<temp1 + >>temp3 -]
mark this cell as full
<<<temp0{bkey<<}key0<full
full +
move temp0/1/2 back to the head cell
full[
>key0{fkey>>}temp0[
{bcell{btemp<<<<}{bkey<<}<}prev_temp0 +
{fcell>{fkey>>}{ftemp>>>>}} temp0 -
]
>temp1[
{bcell{btemp<<<<}{bkey<<}<}prev_temp1 +
{fcell>{fkey>>}{ftemp>>>>}} temp1 -
]
>temp2[
{bcell{btemp<<<<}{bkey<<}<}prev_temp2 +
{fcell>{fkey>>}{ftemp>>>>}} temp2 -
]
go to this cell's full
<<temp0{bkey<<}<full
go back to prev cell
{bcell{btemp<<<<}{bkey<<}<}
]
>key0{fkey>>}temp0>>>temp3 -
<temp2 -
] t2 0 t3 neg1 t2 0 t3 0
>temp3 + t2 0 t3 0 t2 0 t3 1
<<<temp0[{bkey<<}key0 + {fkey>>}temp0 -] move temp0 to key0
>temp1[{bkey<<}key1 + {fkey>>}temp1 -] move temp1 to key1
temp1<temp0{bkey<<}key0<full
============================ /set code =====================================}}}
move key0 back to x
full>key0[<<<<<<<x + >>>>>>>key0-]
move key1 back to y
>key1[<<<<<<<y + >>>>>>>key1-]
if we had a match (temp3 is 1)
<key0{fkey>>}temp0>>>temp3[
clear num and eat up the rest of the input
<<<temp0{bkey<<}key0<full<num [,]
back to temp3 and clear it
>full>key0{fkey>>}temp0>>>temp3 [-]
]
<<<temp0{bkey<<}key0<full<num
] endwhilenum
<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

I slightly modified my solution for part 1, then added the set code in the middle.

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