2024 π Daylatest newsbuy art
Twenty — minutes — maybe — more.Naomichoose four wordsmore quotes
very clickable
data + munging

The Perl Journal

Volumes 1–6 (1996–2002)

Code tarballs available for issues 1–21.

I reformatted the CD-ROM contents. Some things may still be a little wonky — oh, why hello there <FONT> tag. Syntax highlighting is iffy. Please report any glaring issues.

The Perl Journal
#14
Summer 1999
vol 4
num 2
Perl News
What's new in the Perl community.
What Is Truth?
Truth and falsehood aren't black and white.
Downloading Web Pages Through A Proxy Server
How LWP can cope with firewalls.
Seven Useful Uses of local
Some rare occasions when my won't do.
On-the-Fly Web Plots Made Easy
Using Gnuplot to graph web logs
E-mail with Attachments
Using MIME to send images, audio, and more.
Review of Perl: The Programmer's Companion
A Perl book for experienced programmers.
Perl/Tk Menus: Past, Present, and Future
Creating menubars in Perl/Tk 4 and Perl/Tk 8.
Manipulating Images with Perl and the Gimp
Creating plug-ins for a free alternative to Adobe's Photoshop.
Review of Learning Perl/Tk
An introductory text for graphics programming with Perl/Tk.
Building A Better Hash
How a problem was solved with a homebrew data structure.
Using Databases with DBI: What Not To Do
Speeding up your database connections.
Sending mail without sendmail
Sending mail from Perl in a portable way.
International Sorting with sort
Grappling with "funny" letters? Bi-level sorting can help.
The Solitaire 500 Results
The fastest card players from last issue's contest.
The Fourth Annual Obfuscated Perl Contest
Confuse us and win a prize.
The Perl Journal One Liners
David Nicol (1999) The Solitaire 500 Results. The Perl Journal, vol 4(2), issue #14, Summer 1999.

The Solitaire 500 Results

The fastest card players from last issue's contest.

David Nicol


On May 1, 1999, an air-conditioned room deep within the University of Missouri Kansas City's Computing Services department was transformed for a brief eight hours into the mission control center for what may very well have been the first ever programming contest of its kind: the Solitaire 500, described in TPJ (#13).

As you might recall, all programs entered in the Solitaire 500 ran simultaneously on the same computer. They had to make network connections to a server running on a different computer and solve an identical series of five hundred problems presented by the server. The first to complete the series of problems won

Nineteen entries reached the contest's e-mail inbox before the morning of May first.

ID Name
1 Theo Van Dinter
2 Joseph A. Diverdi
3 Steven W. McDougall
4 Eero Pajarre
5 Mark Kvale
6 Dave Shield
7 Andreas Gross
8 James P. Williams
9 David Brandt
10 Stephen M. Moraco
11 John Whitmore
12 Edward M. Perry
13 Jack Applin
14 Robert Au
15 Ira Joseph Woodhead
16 Erle Schuyler
17 Yanick Champoux
18 Jeff Norden
19 Peter J. Jones

Seventeen qualified for the competition.

The winner was (#4) Eero Pajarre's entry, which averaged only 9.7 rounds per deck in the qualifying trial and earned Eero $100 plus a two year extension on his TPJ subscription. His entry re-optimized for speed in the main contest, and won with an average time per deck of slightly more than three seconds. Developing with precompiled binaries of ActiveState Perl and GNU Emacs under Microsoft Windows 95, Pajarre optimized pickup order for most discards available next round with the help of a precompiled table of eight and twelve card situations. Then with the help of the Benchmark module, he realized that switching to string representations would save time

His canonic() subroutine converts decks represented as strings of card rank letters into patterns for the pre-solved table:

sub canonic ($) {
  my ($d)   = @_;
  my ($res) = "";
  my ($ind) = "";
  my ($c, $i);

  for ($i = 0; $i < length($d); $i++){
      $c="substr($d," $i, 1);
      if ( 0 > index($ind,$c) ) {
          $ind .= $c;
      }
      $res .= chr( ord('0') + index($ind, $c) );
      }

  return $res;
}

Steven W. McDougall's entry (#3), a completely commentless six page program that nevertheless reads like a chess match, came in second, taking the $50 prize and a one-year extension to TPJ. By using arrays and array references for his internal representations, McDougall's program was able to generate workable long solutions faster than the next four finishers could generate short solutions. His Partition() subroutine uses bitmasks to determine if the lengths of arrays are divisible by four, to quickly choose good restack orders.

sub Partition {
   my ($stacks, $block4) = @_;
   my $s1 = scalar @{$Tab[$stacks->[1]]};
   my $s2 = scalar @{$Tab[$stacks->[2]]};
   my $s3 = scalar @{$Tab[$stacks->[3]]};
   $block4               & 3 or return @$stacks;
   ($block4 + $s1)       & 3 or return @$stacks[1, 0, 2, 3];
   ($block4 + $s2)       & 3 or return @$stacks[2, 0, 1, 3];
   ($block4 + $s1 + $s2) & 3 or return @$stacks[1, 2, 0, 3];
   ($block4 + $s3)       & 3 or return @$stacks[3, 0, 1, 2];
   ($block4 + $s1 + $s3) & 3 or return @$stacks[1, 3, 0, 2];
   ($block4 + $s2 + $s3) & 3 or return @$stacks[2, 3, 0, 1];
   ($block4 + $s1 + $s2 + $s3) 
                         & 3 or return @$stacks[1, 2, 3, 0];
}

The Wheels game is based on a game of solitaire known as "Perpetual Motion", and some years ago, McDougall wrote a C program to play Perpetual Motion with an animated display of the game state. His second place client was based on this earlier work.

After debugging the loop avoidance strategy, McDougall's program solves approximately eighteen decks per second on his 266 MHz Pentium II PC/NT.

With an algorithm that appeared to win every hand, McDougall focused on minimizing the socket I/O by tacking the instruction to receive the next deck onto the tail of the instruction to win the current deck. At that point his program could process about three hands per second in concert with the demonstration server program.

Jim Williams's third place Expert.pm, (#8), was the only entry to have more than one file of program code, and was also the only entry to have full pod documentation. After he settled on an algorithm, Williams made extensive use of the Benchmark and Devel::DProf modules to guide his creation, inlining several pieces of code that had been separate subroutines. His %permutations hash, a hash of arrays of arrays (a HoLoL) to hold the dealt cards, allowed him to quickly construct the decks so as to choose one that would provide at least one discard the following round. Using "early pickups" to prevent missed discards, Williams's entry has the second lowest total number of moves in the contest, after Norden's (#18).

Honorable Mentions: Dave Shield's (#6) entry made extensive use of regular expressions. Mark Kvale's (#5), the winner of the qualifying round, used a two-ply search with an external database of twelve-card situations. Kvale's Simulate() subroutine provides the same functionality as Williams's array-reference based @{$Permutations{$piles}} with this verbose slice:

# create the deck after pickup
@order = split //, $perm;
@deck = ( @{$pile[$order[0]]},
          @{$pile[$order[1]]},
          @{$pile[$order[2]]},
          @{$pile[$order[3]]} );

Jeff Norden's "RACE CAR" (#18), also using a full two-ply heuristic search, achieved the best round count of the contest. However, Norden spent more CPU time than any other entry:

foreach $order (@Pickups) {
  @deck = map ( @{$_,
          @stack[@$pickup_list{$order}]} );
  play_and_score();
}

Theo Van Dinter's (#1) entry was the last of the entries that supplied multiple move commands at a time.

From Ira Joseph Woodhead (#15), we learned that $ENV{'USER'} is a more portable construction than 'whoami', and from Stephen M. Moraco (#10) we see the advantage of BEGIN { $Exporter::Verbose = 1; } as a package debugging technique.

Joseph A. DiVerdi (#2) used heuristic search to achieve the second-best move count, but his subroutine sent frequent instructions and therefore used a lot of time waiting for the server to respond.

One entry froze, and a spelling error prevented another entry from qualifying. The other seventeen entries successfully completed the qualifying round, earning their creators Perl Mongers T-shirts. The competition results:

> grep 'OK FI' competition_log
925611991entry4aaiOKFINISHEDtime1527round6653move81951
925612196entry3aacOKFINISHEDtime1732round9345move108969
925612235entry8aafOKFINISHEDtime1771round8376move72820
925612518entry11aabOKFINISHEDtime2054round8721move84869
925612702entry6aalOKFINISHEDtime2238round8105move96577
925612904entry7aajOKFINISHEDtime2440round8861move101499
925612999entry14aakOKFINISHEDtime2535round10268move141576
925614674entry19aacOKFINISHEDtime4210round27908move312841
925614893entry5aapOKFINISHEDtime4429round7208move84750
925615025entry12aaiOKFINISHEDtime4561round6725move79026
925615396entry18aaaOKFINISHEDtime4931round5566move64495
925615434entry1aahOKFINISHEDtime4970round5948move77961
925633669entry15aalOKFINISHEDtime23205round10871move91375
925634034entry10aabOKFINISHEDtime23570round9353move114787
925635423entry2aanOKFINISHEDtime24959round8932move78288
925641828entry9aanOKFINISHEDtime31364round6727move93842
925650130entry13aarOKFINISHEDtime39666round41316move317819

This is the final ps listing before Eero finished, having used the least CPU time of all the entries.

Sat May 1 21:25:00 CDT 1999
USERPID%CPU%MEMSIZERSSTTYSTATSTARTTIMECOMMAND
entry1172646.61.824161804p3R20:542:03perl entry.pl
entry2172530.6 2.025601936pdS20:540:12perl entry.pl
entry3172354.51.924641852q1R20:531:26perl entry.pl
entry4172374.42.026001984 pfR20:531:24perl entry.pl
entry5172476.42.429162320peR20:532:02perl entry.pl
entry6172454.81.925001884q0R20:531:32perl entry.pl
entry7172415.52.328242216q3R20:531:45perl entry.pl
entry8172394.71.924801860q2R20:531:30perl entry.pl
entry9172554.12.126322024q4R20:541:16perl entry.pl
entry10172660.62.429682360p4S0:540:12perl entry.pl
entry11172625.11.924241820p5R20:541:35perl entry.pl
entry12172516.51.924881872paS20:532:02perl entry.pl
entry13172590.11.925081892p7S20:540:03perl entry.pl
entry14172575.32.025561944pbR20:541:40perl entry.pl
entry15172610.32.025281920p6R20:540:06perl entry.pl
entry18172497.03.236843072p9R20:532:13perl entry.pl
entry19172434.31.824041792pcR20:531:23perl entry.pl


David Nicol (gratuitoushyphens@tipjar.com) no longer wonders what grading papers at the end of the semester must be like.

Martin Krzywinski | contact | Canada's Michael Smith Genome Sciences CentreBC Cancer Research CenterBC CancerPHSA
Google whack “vicissitudinal corporealization”
{ 10.9.234.152 }