From 5b1dd4066f87b91d5b3c6f4b0c9bc68b34515625 Mon Sep 17 00:00:00 2001 From: Nic Hartley Date: Thu, 4 Oct 2018 11:37:49 -0700 Subject: [PATCH 1/5] Add code --- .../code/ruby/euclidean.rb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 contents/euclidean_algorithm/code/ruby/euclidean.rb diff --git a/contents/euclidean_algorithm/code/ruby/euclidean.rb b/contents/euclidean_algorithm/code/ruby/euclidean.rb new file mode 100644 index 000000000..a87e2364f --- /dev/null +++ b/contents/euclidean_algorithm/code/ruby/euclidean.rb @@ -0,0 +1,21 @@ +def gcd_mod(a, b) + a, b = b, a%b until b.zero? + a +end + +def gcd_minus(a, b) + until a == b + if a > b + a -= b + else + b -= a + end + end + a +end + +p gcd_mod(108, 48) #=> 12 +p gcd_mod(6003, 936) #=> 9 + +p gcd_minus(108, 48) #=> 12 +p gcd_minus(6003, 936) #=> 9 From 06f010579f98552b54b426c415cf1d52ad25462a Mon Sep 17 00:00:00 2001 From: Nic Hartley Date: Thu, 4 Oct 2018 11:39:26 -0700 Subject: [PATCH 2/5] Add it to the page --- contents/euclidean_algorithm/euclidean_algorithm.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contents/euclidean_algorithm/euclidean_algorithm.md b/contents/euclidean_algorithm/euclidean_algorithm.md index 712577edb..a4246207b 100644 --- a/contents/euclidean_algorithm/euclidean_algorithm.md +++ b/contents/euclidean_algorithm/euclidean_algorithm.md @@ -43,6 +43,8 @@ The algorithm is a simple way to find the *greatest common divisor* (GCD) of two [import:1-19, lang="fortran"](code/fortran/euclidean.f90) {% sample lang="racket" %} [import:3-14, lang="lisp"](code/racket/euclidean_algorithm.rkt) +{% sample lang="ruby" %} +[import:6-15, lang="ruby"](code/ruby/euclidean.rb) {% 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: @@ -92,6 +94,8 @@ Modern implementations, though, often use the modulus operator (%) like so [import:21-34, lang="fortran"](code/fortran/euclidean.f90) {% sample lang="racket" %} [import:16-24, lang="lisp"](code/racket/euclidean_algorithm.rkt) +{% sample lang="ruby" %} +[import:1-4, lang="ruby"](code/ruby/euclidean.rb) {% 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: @@ -146,6 +150,8 @@ The Euclidean Algorithm is truly fundamental to many other algorithms throughout [import, lang="fortran"](code/fortran/euclidean.f90) {% sample lang="racket" %} [import, lang="lisp"](code/racket/euclidean_algorithm.rkt) +{% sample lang="ruby" %} +[import, lang="ruby"](code/ruby/euclidean.rb) {% endmethod %} From c4ae6d86b25110ccd9ef2b337c21bd978ed5cd3e Mon Sep 17 00:00:00 2001 From: Nic Hartley Date: Thu, 4 Oct 2018 22:15:44 -0700 Subject: [PATCH 3/5] Add absolute value, about to update .md file --- contents/euclidean_algorithm/code/ruby/euclidean.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contents/euclidean_algorithm/code/ruby/euclidean.rb b/contents/euclidean_algorithm/code/ruby/euclidean.rb index a87e2364f..0c8dc9301 100644 --- a/contents/euclidean_algorithm/code/ruby/euclidean.rb +++ b/contents/euclidean_algorithm/code/ruby/euclidean.rb @@ -1,9 +1,13 @@ def gcd_mod(a, b) + a = a.abs + b = b.abs a, b = b, a%b until b.zero? a end def gcd_minus(a, b) + a = a.abs + b = b.abs until a == b if a > b a -= b From 4bf5d730b93a4a740549c4671427e52426363d5a Mon Sep 17 00:00:00 2001 From: Nic Hartley Date: Thu, 4 Oct 2018 22:16:47 -0700 Subject: [PATCH 4/5] Updated line numbers --- contents/euclidean_algorithm/euclidean_algorithm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contents/euclidean_algorithm/euclidean_algorithm.md b/contents/euclidean_algorithm/euclidean_algorithm.md index a4246207b..ada380468 100644 --- a/contents/euclidean_algorithm/euclidean_algorithm.md +++ b/contents/euclidean_algorithm/euclidean_algorithm.md @@ -44,7 +44,7 @@ The algorithm is a simple way to find the *greatest common divisor* (GCD) of two {% sample lang="racket" %} [import:3-14, lang="lisp"](code/racket/euclidean_algorithm.rkt) {% sample lang="ruby" %} -[import:6-15, lang="ruby"](code/ruby/euclidean.rb) +[import:8-19, lang="ruby"](code/ruby/euclidean.rb) {% 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: @@ -95,7 +95,7 @@ Modern implementations, though, often use the modulus operator (%) like so {% sample lang="racket" %} [import:16-24, lang="lisp"](code/racket/euclidean_algorithm.rkt) {% sample lang="ruby" %} -[import:1-4, lang="ruby"](code/ruby/euclidean.rb) +[import:1-6, lang="ruby"](code/ruby/euclidean.rb) {% 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: From 8d0c1ee4d7360b6ff3b7dd1f0c11d4870fb64c00 Mon Sep 17 00:00:00 2001 From: Nic Hartley Date: Thu, 4 Oct 2018 22:20:02 -0700 Subject: [PATCH 5/5] Factorized arguments for clarity --- contents/euclidean_algorithm/code/ruby/euclidean.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contents/euclidean_algorithm/code/ruby/euclidean.rb b/contents/euclidean_algorithm/code/ruby/euclidean.rb index 0c8dc9301..b8667ad71 100644 --- a/contents/euclidean_algorithm/code/ruby/euclidean.rb +++ b/contents/euclidean_algorithm/code/ruby/euclidean.rb @@ -18,8 +18,8 @@ def gcd_minus(a, b) a end -p gcd_mod(108, 48) #=> 12 -p gcd_mod(6003, 936) #=> 9 - -p gcd_minus(108, 48) #=> 12 -p gcd_minus(6003, 936) #=> 9 +p gcd_mod(12 * 6, 12 * 4) #=> 12 +p gcd_mod(9 * 667, 9 * 104) #=> 9 + +p gcd_minus(12 * 6, 12 * 4) #=> 12 +p gcd_minus(9 * 667, 9 * 104) #=> 9