Created
December 3, 2016 07:13
-
-
Save mattboehm/e7cceab6030b24fe3d2b16f885f7f196 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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") | |
[>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-] | |
++++++++[<++++++>-]>[<<+>>-]>[<<+>>-]<<]>]<[->>++++++++[<++++++>-]]<[.[-]<]< |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I slightly modified my solution for part 1, then added the set code in the middle.