Aus Linux-Magazin 12/2007

Die Gewinner des Wettbewerbs zum Snapshot-Jubiläum

© Elgin Grabe und fotolia.com, ril

Manche Leser ließen sich in die Irre führen. Das zeigte die rege Forumsdiskussion zum Perl-Programmierwettbewerb anlässlich des zehnjährigen Bestehens der Snapshot-Kolumne im Linux-Magazin 10/2007. Inzwischen hat die Jury alle Einsendungen gesichtet und bewertet – jetzt stehen die Sieger fest.

Die Preisaufgabe im vorletzten Linux-Magazin fragte nach der bedingten Wahrscheinlichkeit, mit der ein Proband eine Tux-Tux-Karte in der Hand hält, wenn er bereits eine Karte mit Tux auf der Oberseite gezogen hat. Die richtige Lösung lautet 2:3, also etwa 66 Prozent. Warum? Wenn der Proband eine Karte mit dem Tux auf der Oberseite gewählt hat, dann muss es sich entweder um die Tux-Tux- oder die Tux-Gates-Karte handeln. Beide sind allerdings nicht gleich wahrscheinlich: Die Tux-Tux-Karte kommt zweimal so häufig dran wie die Tux-Bill-Karte, denn zöge der Proband den Bill, müsste er die Karte wieder zurück in den Topf legen und das Experiment wiederholen.

Reingelegt

Rund die Hälfte der Einsendungen liefert ein falsches Ergebnis. Die Wettbewerber berechneten entweder die Wahrscheinlichkeit für die Tux-Tux-Karte lediglich im ersten Versuch (33 Prozent) oder sie zählten gezogene Bill-Karten als gültige Experimente und landeten damit bei 50 Prozent.

Aber nicht nur das richtige Ergebnis zählt. Die Aufgabe verlangt auch Perl-Code, der das Experiment simuliert. Listing 1 zeigt eine mögliche Implementierung. Eine For-Schleife rattert durch 1000 Versuchsdurchgänge, eine Redo-Anweisung wiederholt das Experiment, falls Bill auftaucht. Bei einem Tux auf der Rückseite gibt es dagegen einen Punkt. Das Ergebnis ist das Verhältnis der Punkte zur Gesamtzahl der Versuchsdurchgänge.

Listing 1:
»tuxgates«

01 #!/usr/bin/perl -w
02 
03 use strict;
04 
05 my @cards = (
06     ['tux',   'tux'],
07     ['tux',   'gates'],
08     ['gates', 'gates']
09 );
10 
11 my $hits  = 0;
12 my $total = 1000;
13 
14 for(1..$total) {
15     my $draw  = $cards[rand @cards];
16 
17     my $front_idx = int rand 2;
18     my $back_idx  = !$front_idx;
19 
20     redo if $draw->[$front_idx] ne 'tux';
21 
22     if($draw->[$back_idx] eq 'tux') {
23         $hits++;
24     }
25 }
26 
27 print $hits, " of ", $total, "n";

Dreistigkeit

Die Jury bewertete die richtigen Einsendungen nach drei Kategorien: das kürzeste, das anschaulichste und das originellste Skript. In der Kategorie “Originell” gewinnt Thomas Güttler, dessen Einsendung die Redaktion als Erste erreichte und das richtige Ergebnis lieferte. Die bass erstaunte Jury fand aber bei näherem Hinsehen, dass Thomas die Frechheit besessen hat, ein Python-Skript einzusenden, das nur notdürftig in ein Perl-Skript verpackt ist. Es sucht einen installierten Python-Interpreter und übergibt ihm den Python-Code als String zur Ausführung. Für so viel Chuzpe verleiht die Jury volle zehn Punkte, die höchste Wertung – die Goldmedaille.

Hanspeter Schmid lieferte einen Vierzeiler, in dem er “Tuxlis” aus dem Wasser (H2O) entsteigen lässt und diese mit »unpack« wieder auseinanderklaubt, das reicht für Platz zwei. Patrick Falb nutzt einen regulären Ausdruck mit Look-Ahead, um eine Karte zu ziehen. Die Platzierungen von korrekt arbeitenden Skripten mit Origininalitätscharakter zeigt die Tabelle “Gewinner”.

Beim kürzesten Skript war die Wertung relativ einfach, es zählte schlicht die Anzahl der Anschläge, das richtige Ergebnis natürlich vorausgesetzt. Dieses so genannte Perl-Golf trägt seinen Namen nach dem Golfsport, bei dem ja bekanntlich auch der Spieler mit den wenigsten Schlägen gewinnt.

Lesbares Golf

Nun sind gute Golf-Skripte oft schwer lesbar, daher bedienen sich Schiedsrichter im Perl-Golf spezieller Werkzeuge, die den Code automatisch lesbarer gestalten. Das Gewinnerskript, eine Gemeinschaftsarbeit von Timo Warns und Tammo Freese, schafft es in nur 58 Zeichen, das Ziehen der drei Karten aus dem Behälter zu simulieren.

Abbildung 1 zeigt die Einsendung der beiden Perl-Golfer. Das CPAN-Modul O::Deparse mit dem in Abbildung 2 gezeigten Aufruf zerlegt den Code und formatiert ihn etwas lesbarer. Die beiden Perl-Enthusiasten stellen die Vorder- und Rückseiten der im Experiment enthaltenen drei Karten in einem Array mit den Indexnummern 0 bis 5 dar, 0/1 ist die Tux-Tux-Karte, 2/3 die Tux-Bill-Karte und 4/5 die Bill-Bill-Karte.

Abbildung 1: Das Sieger-Skript unter den Golf-Lösungen im Einsatz.

Abbildung 1: Das Sieger-Skript unter den Golf-Lösungen im Einsatz.

Abbildung 2: Die mit dem O::Deparse-Modul lesbar gemachte Golf-Lösung.

Abbildung 2: Die mit dem O::Deparse-Modul lesbar gemachte Golf-Lösung.

Der Aufruf »rand(6)« liefert eine Fließkomma-Zufallszahl zwischen 0 (einschließlich) und 6 (ausschließlich), aber Perl rundet das Ergebnis auf einen Integer ab, wenn man es als Array-Index verwendet. Daraus ergeben sich gleichmäßig verteilte Integerwerte von 0 bis 5. Zeigt die Oberseite der gezogenen Karte einen Tux, erhöht sich der Zähler »$t«. Ist auch noch die Rückseite der Karte ein Tux, was bei den Zufallswerten 0 oder 1 passiert, inkrementiert sich auch noch der Zähler »$b«. Die Wahrscheinlichkeit dafür, bei einem bereits gezogenen Tux auch auf der Rückseite einen Tux zu finden, ist das Verhältnis »$b/$t«. Für die Prozentangabe multipliziert es das Skript noch mit 100.

Bei den Golf-Lösungen fiel der dreiköpfigen Jury auf, dass viele Einsender die Tux-Karten als binäre Einsen, die Gates-Karten jedoch als Nullen darstellten. Einige wiesen sogar in Kommentaren darauf hin, diese Wahl bewusst so getroffen zu haben, unerhört! Die weiteren Platzierungen zeigt Tabelle 1.

Tabelle 1:
Gewinner

 

Kategorie: Originalität

 

Name

Punkte

Thomas Güttler

10

Hanspeter Schmid

5

Felix Schumacher

5

Patrick Falb

4

Kategorie: Kürzestes Skript

 

Name

Golf-Punkte

Timo Warns/Tammo Freese

58

Christoph Buchetmann

68

Stefan Dufter

70

John E. Wulff

75

Christoph Sünderhauf

77

Felix Schumacher

87

Eric Dold

103

Matthias Bethke

105

Michael Hartmann

112

Sebastian Bober

137

Hanspeter Schmid

161

Kategorie: Anschaulichstes Skript

 

Name

Punkte

Felix Schumacher

10

Christoph Buchetmann

9

Tobias Gneist

9

Frank Störzer

9

Jörg Ogrissek

7

Stephan Völkel

7

Benjamin Weber

7

Marcel Zehnder

7

Matthias Kratzer

6

Chris Mair

6

Patrick Falb

4

In der Disziplin “Anschaulichstes Skript” waren saubere, leicht verständliche Implementierungen gefragt, die auch im harten Projektalltag einige Wartungszyklen überstehen und sich ohne Komplikationen erweitern lassen.

Es flossen die unterschiedlichsten Ideen aus der Software-Entwicklung ein: Felix Schumacher modellierte Einzelkarten in der Perl-Klasse »Card« und den Kartenstapel in einer weiteren Klasse »Cards«. Weiter lieferte er drei Regressions-Testsuiten, zwei als Modultests für die implementierten Perl-Pakete und eine weitere für den Versuchsablauf.

Abgesehen von Kleinigkeiten wie der Verwendung von »$#array+1« statt des üblichen »@array« in skalarem Kontext war das die ausgereifteste Lösung. Sie erhielt die volle Punktzahl. Die drei nächstplatzierten Christoph Buchetmann, Tobias Gneist und Frank Störzer bekamen neun Punkte, Sie lieferten allesamt sehr solide Skripte ab, aus denen die Jury hervorragende Perl-Kenntnisse ablesen konnte.

Das Linux-Magazin dankt allen Einsendern, verschickt in den nächsten Tagen die Preise und vertröstet alle, bei denen es nicht zu einem Preis gereicht hat, auf den nächsten Wettbewerb – vielleicht schon vor 2017. (jcb)

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 2 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben