Skip to content

Euclidian Algorithm Piet Implementation #448

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@
- Ken Power
- PaddyKe
- nic-hartley
- Thijs Raymakers
- crafter312
4 changes: 4 additions & 0 deletions book.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@
{
"lang": "lolcode",
"name": "LOLCODE"
},
{
"lang": "piet",
"name": "Piet"
}
]
}
Expand Down
146 changes: 146 additions & 0 deletions contents/euclidean_algorithm/code/piet/euclidian_algorithm.piet
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
This file describes the path that the Piet program takes in a more human readable form.
Two functions are implemented:
- GCD with subtraction
- GCD with the modulo operator

-------------------
SUBTRACTION
-------------------

Pseudo code:

function gcd(a, b)
while a ≠ b
if a > b
a := a − b;
else
b := b − a;
return a;


Piet code:

COMMAND STATE OF STACK
in(number) A // Take A as an input
duplicate AA // Start to take the absolute value of A
push 1 1AA
duplicate 11AA
subtract 0AA
greater 0/1A // 1 if A > 0, 0 if A <= 0
not 1/0A // 0 if A > 0, 1 if A <= 0
push 1 1 1/0 A
push 3 31 1/0 A
subtract -2 1/0 A
multiply -2/0 A
push 1 1 -2/0 A
add -1/1 A
multiply A // A should now be an absolute value

in(number) BA // Take B as an input
duplicate BBA // Start to take the absolute value of B
push 1 1BBA
duplicate 11BBA
subtract 0BBA
greater 0/1BA // 1 if B > 0, 0 if B <= 0
not 1/0BA // 0 if B > 0, 1 if B <= 0
push 1 1 1/0 BA
push 3 31 1/0 BA
subtract -2 1/0 BA
multiply -2/0 BA
push 1 1 -2/0 BA
add -1/1 BA
multiply BA // B should now be an absolute value

// Start of the main loop while a ≠ b
duplicate BBA
push 3 3BBA
push 2 23BBA
roll ABB
duplicate AABB
push 4 4AABB
push 1 14AABB
roll ABBA
subtract 0/x BA
not 1/0 BA // 1 if a = b and 0 if a ≠ b
not 0/1 BA // 1 if a ≠ b and 0 if a = b
pointer BA // If a ≠ b, the DP should change one clockwise, otherwise, go straight ahead.

// Go left if a ≠ b (DP changed one clockwise)
duplicate BBA
push 3 3BBA
push 2 23BBA
roll ABB
duplicate AABB
push 4 4AABB
push 1 14AABB
roll ABBA
push 2 2ABBA
push 1 12ABBA
roll BABA
greater 0/1 BA // A > B; 1 if true; 0 if false
pointer BA // If A > B, DP goes one clockwise, otherwise, DP stays the same.

// If A > B (DP has changed 1 clockwise)
duplicate BBA
push 3 3BBA
push 1 13BBA
roll BAB
subtract AB // A = A - B
push 2 2AB
push 1 12AB
roll BA
// Go back to start of loop

// If B > A (DP stayed the same)
push 2 2BA
push 1 12BA
roll AB
duplicate AAB
push 3 3AAB
push 1 13AAB
roll ABA
subtract BA // B = B - A
// Go back to start of loop

// Go down if a = b (end of while loop)
pop A
out(number) - // Print out A when done.

---------------------------------------------------------------------------

-------------------
MODULO
-------------------

Pseudo code:

function gcd(a, b)
while b ≠ 0
t := b;
b := a mod b;
a := t;
return a;

Piet code:

COMMAND STATE OF STACK
in(number) A
in(number) BA

// Start of loop
duplicate BBA
not 0/1 BA
not 1/0 BA
pointer BA

// Go down if b ≠ 0
duplicate TBA
push 3 3TBA
push 1 13TBA
roll BAT
mod BA // b = a mod b; a = t
// Go back to the start of the loop

// Go right if b = 0
pop A
out(number) - // Print out A when done.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions contents/euclidean_algorithm/euclidean_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -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="piet" %}
> ![](code/piet/subtract/euclidian_algorithm_subtract_large.png) ![](code/piet/subtract/euclidian_algorithm_subtract.png)
{% 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:
Expand Down Expand Up @@ -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="piet" %}
> ![](code/piet/mod/euclidian_algorithm_mod_large.png) ![](code/piet/mod/euclidian_algorithm_mod.png)
{% 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:
Expand Down Expand Up @@ -209,6 +213,17 @@ and modulo method:
[import, lang="LOLCODE"](code/lolcode/euclid.lol)
{% sample lang="bash" %}
[import, lang="bash"](code/bash/euclid.bash)
{% sample lang="piet" %}
A text version of the program is provided for both versions.
#### Subtraction
> ![](code/piet/subtract/euclidian_algorithm_subtract_large.png) ![](code/piet/subtract/euclidian_algorithm_subtract.png)

[import:23-107](code/piet/euclidian_algorithm.piet)

#### Modulo
> ![](code/piet/mod/euclidian_algorithm_mod_large.png) ![](code/piet/mod/euclidian_algorithm_mod.png)

[import:126-146](code/piet/euclidian_algorithm.piet)
{% endmethod %}

<script>
Expand Down