Being from a musician's background as opposed to computer science, I have a bit of an inferiority complex when it comes to hard core theory such as algorithms and such. Lately I've been trying to make amends by hacking though such classics as Mastering Algorithms with Perl and Knuth's The Art of Computer Programming.

This morning I decided to write out Euclid's algorithm from page 2 of Knuth. First I wanted to do it exactly as it was written in the book:

#!/usr/bin/perl use strict; use warnings 'all'; use integer; =head1 Euclid's Algorithm Given two positive integers m and n, find their greatest common divisor. =cut sub p { my ($m, $n) = ($_[0], $_[1]); my $r; # m and n must be positive integers. if (($m < 1) || ($n < 1)) { die("Values must be positive integers."); } # E0: If m < n, exchange m and n # # As Knuth points out, this step can be avoided, # but it will force the algorithm to go through # another loop as it exchanges m and n when n is # greater. if ($m < $n) { ($m, $n) = ($n, $m); } do {{ # E1: Divide m by n and let r be the remainder $r = $m % $n; # E2: If r = 0, the algorithm terminates; $n is the answer if ($r == 0) { return $n; } # E3: Set m = n, n = r, and go back to step E1. $m = $n; $n = $r; redo; }} }
But this didn't seem nearly Pearly enough for me. Since I always seem to get paid for programming in just about anything BUT my language of choice, I am not very good with "idiomatic Perl". Thus I set out to try to write the thing as Perl-like as I could:
sub p_idiomatic { # Use a numeric sort to enforce that m is greater then n my ($m, $n) = sort { $b <=> $a } $_[0], $_[1]; # This is the same as: # my ($m, $n) = reverse sort { $a <=> $b } $_[0], $_[1]; # Holds the remainder my $r; # Insure that they are positive integers # Is their a better way to do this? if (($m < 1) || ($n < 1)) { die("Values must be positive integers."); } do {{ $r = $m % $n; $m = $n; $n = $r; }} until $r == 0; return $m; }
Then I wondered if anyone else here had done this, so I tried Super Search. That's when I found this from Tilly's Continued Fractions:
sub gcd { my ($n, $m) = @_; while ($m) { my $k = $n % $m; ($n, $m) = ($m, $k); } return $n; }
Short and sweet and very clean.

Tilly, if you are reading this somewhere, thanks! Even though you are no longer here, I've learned a lot from your posts.

()-()
 \"/
  `                                                     

In reply to Euclid's Algorithm: A Homage to Tilly by ignatz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.