-
-
Notifications
You must be signed in to change notification settings - Fork 359
Added brainfuck code and explanation for Euclidean Algorithm #463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
>,>,[<[>->+<[>]>[<+>-]<<[<]>-]>[-<+>]>[-<+<+>>]<]<. | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
,>,>>>+[[-]<<<<[->>>+<<<]>[->>>+<<<]>>[-<+<<+>>>]>[-<+<<+>>>]<<[->->+<[>-]>[->>]<<<]>[>]<[<<[-]>>[-<<+>>>+<]]<[<<[-]>>[-<<+>>>>+<<]]>>>+<[>-]>[<<<<.>>>>->>]<<] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,6 +63,8 @@ The algorithm is a simple way to find the *greatest common divisor* (GCD) of two | |
[import:25-40, lang="LOLCODE"](code/lolcode/euclid.lol) | ||
{% sample lang="bash" %} | ||
[import:24-38, lang="bash"](code/bash/euclid.bash) | ||
{% sample lang="bf" %} | ||
[import, lang="brainfuck"](code/brainfuck/euclidean_sub.bf) | ||
{% endmethod %} | ||
|
||
Here, we simply line the two numbers up every step and subtract the lower value from the higher one every timestep. Once the two values are equal, we call that value the greatest common divisor. A graph of `a` and `b` as they change every step would look something like this: | ||
|
@@ -132,6 +134,8 @@ Modern implementations, though, often use the modulus operator (%) like so | |
[import:9-23, lang="LOLCODE"](code/lolcode/euclid.lol) | ||
{% sample lang="bash" %} | ||
[import:10-22, lang="bash"](code/bash/euclid.bash) | ||
{% sample lang="bf" %} | ||
[import, lang="brainfuck"](code/brainfuck/euclidean_mod.bf) | ||
{% endmethod %} | ||
|
||
Here, we set `b` to be the remainder of `a%b` and `a` to be whatever `b` was last timestep. Because of how the modulus operator works, this will provide the same information as the subtraction-based implementation, but when we show `a` and `b` as they change with time, we can see that it might take many fewer steps: | ||
|
@@ -209,6 +213,114 @@ and modulo method: | |
[import, lang="LOLCODE"](code/lolcode/euclid.lol) | ||
{% sample lang="bash" %} | ||
[import, lang="bash"](code/bash/euclid.bash) | ||
{% sample lang="bf" %} | ||
#### Subtraction varient | ||
##### Code | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm happy with the code at this point. The code is as slim as it can be without having to redo the fundemantals. This leaves me with one final question, and that one is of style: What is your justification for writing your code as a one-liner and then a explanation in the md-file? We already have a brainfuck bubble sort and it is quiet different -> here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. iirc there was a discussion in the discord chat about if to combine the explanation and code, and we agreed on removing all comments in the code to make it more 'brainfuck', i see if i can find that chat There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #407 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used the "source code" then commented version with my whitespace submission. I think it's best this way. Brainfuck is a joke language and the joke is more effective without comments, but then after you see the source code you want to know more and that's when the comments are nice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just find the format we already have for the bubble sort bf more easy to read and review and it also keeps documentation and code in the same place, which I prefer. And when this PR is added we'll lose some concistency between chapters. Still, having a style guide for brainfuck code seams a bit ridiculous and if this is the way some other people already agreed on, I'm fine with that. In that case I will start reviewing the explanation part. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wait so do we want like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jiegillet prefers the first and I prefer the latter. I've asked Leios what he thinks of it, he'll look at it later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that the in-text code should be more BF-like; however, a commented version is also necessary (if possible). Both this chapter and bubble sort provide an adequate solution; however, I would argue that the bubble sort seems much easier to read when the two chapters are put side-by-side. I think this ultimately boils down to a number of factors:
With other esoteric languages (like whitespace), the code was displayed as it would be seen in actually whitespace code, and then a heavily commented / modified version was put underneath. I think this is also a fine solution, but if we do that we need to make sure that the BF code actually fits into the AAA codebox. I think the best solution is just to provide a heavily commented BF code sample with the explanation in-built. If that's not possible, the explanation at the end of the chapter is still useful, but should be rewritten (which I can help with). Sorry for all the extra work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I just rmbed why the commented code wasnt in the file |
||
[import, lang="brainfuck"](code/brainfuck/euclidean_sub.bf) | ||
##### Explanation | ||
Basic plan: get |a-b|, check if 0 | ||
|
||
So the program does something like | ||
``` | ||
a (b) 0 0 1 0 0 | ||
a b a b (0) 0 0 | ||
if(a>b) a b a-b 0 (a-b) 0 0 | ||
else a b 0 a-b (a-b) 0 0 | ||
if(a-b==0)print and break | ||
else | ||
if(a>b) a-b b 0 0 (a-b) 0 0 | ||
else a a-b 0 0 (a-b) 0 0 | ||
``` | ||
|
||
More detail: | ||
|
||
`scan a,b`: `>,>,` | ||
State: `a (b) 0 0 0 0 0` | ||
``` | ||
>>>+ | ||
[ | ||
[-]<<< | ||
<[->>>+<<<]>[->>>+<<<]>> | ||
``` | ||
State: `0 0 0 (a) b 0 0` | ||
``` | ||
[-<+<<+>>>] | ||
>[-<+<<+>>>] | ||
``` | ||
State: `a b a b (0) 0 0` | ||
``` | ||
<< | ||
[->- subtracts a from b, assuming a>b | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah that’s one of the reasons why I didn’t comment in the actual bf code, cuz .,<> are all affecting execution |
||
>[-]+ | ||
<[ | ||
>-]> | ||
[->>]<<< if a is 0, stop | ||
] | ||
``` | ||
So basically the state will either be | ||
a_b (0) 0 0 | ||
or | ||
(0) a_b 0 0 | ||
but it's hard to do when states may be different, so `>[>]` moves the pointer to cell 4 | ||
``` | ||
<[<<[-]>>[-<<+>>>+<]] | ||
<[<<[-]>>[-<<+>>>>+<<]] | ||
``` | ||
basically cell 4 will contain the difference | ||
``` | ||
>>>[-]+ | ||
>[-]<< | ||
[>-]> | ||
[<<<<.>>> testing if difference is 0, if so return | ||
>->>]<< | ||
] | ||
``` | ||
|
||
#### Modulo varient | ||
##### Code | ||
[import, lang="brainfuck"](code/brainfuck/euclidean_mod.bf) | ||
##### Explanation | ||
`scan a,b`: `>,>,` | ||
|
||
State: `0 a >b 0 0 0` | ||
|
||
`while(b!=0)`: `[` | ||
|
||
`a,b,0=0,b-a%b,a%b`: | ||
``` | ||
<[ | ||
>->+<[>] | ||
>[<+>-]< | ||
<[<]>- | ||
] | ||
``` | ||
|
||
so basically this is the modulo algorithm in brainfuck, it slowly shifts cell 2 to cell 3, while subtracting 1 from cell 1 | ||
then when cell 2 goes to 0, it shifts cell 3 to 2 and continues, this is like just constantly subtracting cell 2 from cell 1, until you cant subtract anymore then return at cell 3 | ||
|
||
State: `0 >0 b-a%b a%b 0 0` | ||
|
||
shifting: `>[-<+>]` | ||
|
||
State: `0 b-a%b >0 a%b 0 0` | ||
|
||
Currently we have a,b,0=b-a%b,0,a%b, and we need a,b,0=b,a%b,0, so we just add the third cell to the first and second cell | ||
|
||
adding thing: `>[-<+<+>>]<` | ||
|
||
State: `0 b >(a%b) 0 0 0` | ||
|
||
So now we have a,b=b,a%b, we continue the loop | ||
|
||
`]` | ||
|
||
After the second cell is 0, the loop terminates and we obtain the GCD | ||
|
||
State: `0 >GCD(a b) 0 0 0 0` | ||
|
||
Now we print the GCD | ||
|
||
print: `<.` | ||
{% endmethod %} | ||
|
||
<script> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm generally happy with this code, it did take some checking to find out that the
[>->+<[>]>[<+>-]<<[<]>-]
part, you got from here was in the public domain, but I eventually found this, so it's fine.