Pythagoras Pie

(Image courtesy Tomohiro Tachi under Creative Commons license.)

Recently I came across a fun programming challenge called the Pythagoras Pie, which was described as:

At a party a pie is to be shared by 100 guests. The first guest gets 1% of the pie, the second guest gets 2% of the remaining pie, the third gets 3% of the remaining pie, the fourth gets 4% and so on.

Write a script that figures out which guest gets the largest piece of pie.

I sat down for a few minutes, and wrote the obvious code. It iterates over the list of guests. For each guest, it calculates how large a piece of pie the guest will get. All the while, it stores size of the largest piece of pie it has seen so far.

Here is a solution in Perl.

sub slice_pie {
    my $iters   = shift;
    my $pie     = 1;
    my $largest = 0;
    my $winner  = 0;
    for ( 0 .. $iters ) {
        my $iter_value = $_ * .01;
        my $portion    = ( $iter_value * $pie );
        $pie = $pie - $portion;

        if ( $portion >= $largest ) {
            $largest = $portion;
            $winner  = $_;
        }
    }
    print qq[Winner is guest # $winner with the largest portion: $largest\n];
}

slice_pie(100);

The answer, as it turns out, is that the 10th guest gets the largest piece of the pie: 0.0628156509555295, or about 6%.

Just for fun, I wrote almost the same exact code once again, except this time in Perl 6. Even though this is a straightforward translation using the same basic loop structure, it has a few nice improvements:

  • No need for argument unpacking (saves a horizontal line — vertical compactness is good)
  • Nice type annotations mean we can call an integer an Int, which also helps the compiler
  • No need for parens around the for and if checks
sub slice-pie(Int $iters) {
    my $pie = 1;
    my $largest = 0;
    my Int $winner;

    for 0 .. $iters {
        my $iter_value = $_ * .01;
        my $portion = $iter_value * $pie;
        $pie -= $portion;

        if $portion >= $largest {
            $largest = $portion;
            $winner = $_;
        }
    }
    say qq[Winner is guest number $winner with the largest portion: $largest ];
}

slice-pie(100);

Advertisements

Emacs Compilation Mode Regexp for Perl 6

Emacs Compilation Mode Regexp for Perl 6

Stick this in your .emacs if you want Perl 6 support in Emacs’ compilation mode:

  (add-to-list 'compilation-error-regexp-alist 'perl6-stack-trace)
  (add-to-list 'compilation-error-regexp-alist-alist
               '(perl6-stack-trace .
                                   ("at \\([A-Za-z-_]+\\(\.p[l6m]\\)?\\):\\([[:digit:]]+\\)"
                                    1 3)))

I don’t know if this would be a good addition to perl6-mode, or if compilation mode regexps are supposed to live elsewhere.

If you like this sort of thing, see also: flycheck-perl6.