Entwicklergolf bei //SEIBERT/MEDIA: Alle Programmierer sind eingeladen

1. Dezember 2008 von Matthias Rauer

Gesucht: Der schlankeste Code

Wenn sich die Weihnachtszeit nähert, wird natürlich auch den Entwicklern von //SEIBERT/MEDIA warm ums Herz. Doch anstatt nach Plätzchen- und Glühweinrezepten zu googeln und feierliche Dekoideen zu recherchieren, haben sie ein weihnachtliches Golfturnier ausgetragen – allerdings eine Variante, für die kein Schlägerarsenal und kein Caddy, sondern Kreativität und ausgezeichnete Programmierkenntnisse nötig sind.

Beim Golf auf dem Rasen gewinnt der Spieler, der die wenigsten Schläge zum Einlochen benötigt. Daran orientiert sich auch der Golfwettbewerb unter Entwicklern: Ziel ist es, eine bestimmte Programmieraufgabe mit möglichst wenig Aufwand zu erledigen. Schnelligkeit und selbst Schönheitspreise spielen dabei untergeordnete Rollen, vielmehr zählen Kreativität und technologisches Know-how. Sieger des Wettbewerbs ist in der Regel der Teilnehmer mit dem schlankesten Code und damit derjenige, der die höchste Effizienz und Effektivität an den Tag legt. (siehe auch Golf [Programmierung] bei Wikipedia.de)

Beim Entwicklergolfturnier der //SEIBERT/MEDIA-Programmierer ging es nun stilecht darum, mit einem Programm in einer beliebigen Sprache (wobei möglichst viele verschiedene gewünscht waren) einen ASCII-Weihnachtsbaum auszugeben. Unsere Technologies-Abteilung ließ sich nicht lange bitten, bot sich über Wochen hinweg im //SEIBERT/MEDIA-Wiki einen anregenden und inspirierenden Wettstreit und geizte nicht mit Kommentaren – natürlich mit einer gehörigen Portion Augenzwinkern.

Unser Aufruf: Machen Sie mit und posten Sie eigene Vorschläge als Kommentare

An dieser Stelle laden wir alle Programmierer herzlich ein, sich am Entwicklergolfturnier von //SEIBERT/MEDIA zu beteiligen und eigene Vorschläge einzubringen:

Posten Sie bis zum 31.12.2008 einfach Ihren eigenen Code als Kommentar zu diesem Artikel und gewinnen Sie einen nagelneuen iPod Shuffle!

Den Sieger küren wir nach bestem Wissen und Gewissen per Losentscheid. Welche Programmiersprache Sie verwenden, überlassen wir ganz Ihnen. Der Code muss aber funktionieren.

Gewinnen können Sie natürlich auch, wenn Sie kein Programmierer sind und einfach einen netten Kommentar zu diesem Artikel bzw. zu unserem Blog hinterlassen. In diesem Fall setzen wir Ihre Chancen bei der Auslosung allerdings etwas geringer an. Der Gewinner wird im Januar im //SEIBERT/MEDIA-Weblog bekannt gegeben. Wir sind gespannt auf Ihre guten Ideen und Ihren Input!

In diesem Zusammenhang möchten wir Sie gerne darauf hinweisen, dass wirklich gute Entwickler bei //SEIBERT/MEDIA stets willkommen sind und legen erfahrenen Internet- und Perl-Programmierern unsere ausführliche Stellenbeschreibung wärmstens ans Herz. Bewerben Sie sich!

Effizient und kreativ: Unsere internen Ergebnisse

Nun ist es an der Zeit, den internen Sieger zu küren. Wir gratulieren dem Gewinner Christian zu seinem Vorschlag in Perl 5.10 mit -E Switch:

Darüber hinaus möchten wir Ihnen einige weitere hochwertige und kreative Ideen nicht vorenthalten. Mit diesem Vorschlag in Groovy musste sich Micha knapp geschlagen geben:

Eine ebenfalls sehr schlanke Lösung hat Dennis in Python erarbeitet:

Ein Code in Python

Einige andere Kollegen nahmen es mit dem Code-Umfang wiederum nicht ganz genau, müssten aber eigentlich mit Ehrenpreisen für die kreativsten Ergebnisse bedacht werden. Diesen Schneewald hat Armin in C++ umgesetzt:

Um diese Perl-Weihnachtsbäume zu generieren, sucht das Script von Joachim via Google-Suche ein Zufallsbild aus:

Lösungen wurden unter anderem in den Programmiersprachen Perl, Haskell, (N)ASM, Brainfuck, Vim, Python, Erlang, Groovy, Java, C, C++, C# .net, TCL, Python, XSLT, SVG, SQL, PHP und Ruby eingereicht.

Die rege Betiligung am Entwicklergolfturnier und die durchweg sehr guten Ergebnisse verdanken wir Jonas, Dennis, Micha, Manuel, Tobias, Sven, Maik, Benjamin, Christian, Armin, Joachim, Michael und – außer Konkurrenz – Martin Seibert. Dieser wollte den Technologies-Experten weismachen, dass es offenbar ungeahnte Möglichkeiten hinsichtlich der Ausgabe in ASCII gibt. Den Code ist er allerdings bislang schuldig geblieben. ;-)

In diesem Sinne wünschen wir allen Mitarbeitern, Kunden und Lesern eine schöne und sorgenfreie Advents- und Weihnachtszeit und freuen uns auf die weitere erfolgreiche Zusammenarbeit im kommenden Jahr!

Und nicht vergessen:

Unten kommentieren und einen iPod Shuffle gewinnen.

Weitere Informationen zu Groovy und Grails
Weitere Informationen zu Perl-Programmierung

55 Reaktionen zu diesem Beitrag

  1. Winfried Neessen

    Hier ein kleiner Perl-Beitrag:

    $n=”\e[0;40;32m”;$s=0.5;for(1..10){print”\ec$n$/”.$”x(15).”\e[1;35mY$n”.$”x15;for(1..13){print$/.$”x($b=16-$_);$p=int rand($d=2*$_);for(2..$d){$f=31+int rand(5);print($_-$p?”X”:”\e[$f;1mo$n”)}print$”x$b}print$/.$”x(14).”X”x(2);print$/.$”x(14).qq(X)x(2);print $/.$/.$”x(6).”\e[0m”.”Frohe Weihnachten!!”.$/;select $x,$m,$a,$s}


  2. Martin Seibert

    Sehr gut. Danke. Für die Auswertung, an der ja auch DAUs, wie ich beteiligt sein werden, wäre eine Ausgabe in Ascii oder ein Link zu einem Screenshot cool. Natürlich nur wenn einfach machbar.


  3. Weihnachtsgewinnspiel für Entwickler « PHvB - Wirtschaft im weitesten Sinne

    [...] Zum //S/M-Entwicklergolf [...]


  4. Winfried Neessen

    Hallo Martin,

    hier ein Screenshot: http://dl-client.getdropbox.com/u/5386/weihnacht_pl.png
    (wobei man auf dem Screenshot natuerlich nicht die tolle Animation der blinkenden Christbaumkugeln erkennen kann ;-) )


  5. Benjamin Knaus

    Die Lösung in Brainfuck würde mich auch intressieren. Wieviel tausend Zeilen wurden dabei denn benötigt?


  6. Martin Seibert

    Winfried: Das sieht schon ziemlich vielversprechend aus. :-)


  7. Maik Broemme

    Hier mal ein kleiner Beitrag in ANSI-C, das ganze laesst sich wie folgt kompilieren und ist ‘-Wall’ sicher :)

    $ gcc christmas-tree.c -o christmas-tree

    [code]
    #include
    #include
    int draw(int x, char *p) {
    if (x > strlen(p)) { printf("%*c%s%c\n", (int)strlen(p), p[0], "|", p[0]); return -1; }
    printf("%*.*s%s%.*s\n", (int)strlen(p), x, p, "|", x, p);
    return draw(x + 1, p);
    }

    int main() {
    return (draw(0, "xxxxxxxxxx")<0);
    }
    [/code]

    Die Ausgabe des wunderschoenen Baums :) sieht dann so aus:

    [code]
    |
    x|x
    xx|xx
    xxx|xxx
    xxxx|xxxx
    xxxxx|xxxxx
    xxxxxx|xxxxxx
    xxxxxxx|xxxxxxx
    xxxxxxxx|xxxxxxxx
    xxxxxxxxx|xxxxxxxxx
    xxxxxxxxxx|xxxxxxxxxx
    x|x
    [/code]


  8. Maik Broemme

    Da die Formatierung jetzt voellig verloren gegangen ist, hier mal zwei Links, der erste zu dem Quelltext und der zweite zu dem Output:

    https://babelize.org/christmas-tree.c
    https://babelize.org/christmas-tree.output

    Die Groeße des Baums ist natuerlich ueber den zweiten Parameter der Funktion draw() einstellbar. :)


  9. Matthias Rauer

    Maik, prima, danke fürs Mitmachen :-)


  10. Steffen Otte

    Aloha. Ich habe mal eben auf die Schnelle rudimentäres PHP-Knowhow aus den etwas verstaubten Tiefen des Unterbewusstseins hervorgekramt, um eine Variante zu erstellen, die vom Ergebnis her zwar wie eine der Gewinnerlösung ausschaut, letztendlich aber (leider) nur durch ein paar zusätzliche Anschläge zustande kommt ;-)

    echo ”; $i=0; while($i<40) echo str_repeat(‘x’,$i+=2).”"; echo ‘xx’;

    Bessere und effektivere PHP-Lösungen würden mich aber auf jeden Fall interessieren.


  11. Steffen Otte

    Trottel ich … klar, dass der HTML-Teil der Ausgabe nun “verschwunden” ist ;-)

    Guckst Du hier:
    http://www.netgefluester.de/xmas.php


  12. Jan Kohlhof

    Nicht unbedingt effektiver als Steffens, dafür aber ASCII art für die Konsole.
    php -r ‘while($i<42)echo($i+=2)%40?str_repeat(” “,20-$i/2%20).str_pad(“”,$i%40,”#”,2).”\n”:”";’

    anyway, PHP wasn’t made for golfing ;)


  13. Maik Broemme

    Ich hab das Beispiel von mir oben in C nochmal etwas optimiert, den folgenden Einzeiler kann man jetzt einfach ausfuehren (GCC vorausgesetzt).

    echo -e “#include \n#include \nint main() { int x; char *p = \”xxxxxxxxxx\”; for (x = 0; x < strlen(p); x++) { printf(\”%*.*s%s%.*s\\\n\”, (int)strlen(p), x, p, \”|\”, x, p); } printf(\”%*c%s%c\\\n\”, (int)strlen(p), p[0], \”|\”, p[0]); return 0; }” | gcc -x c – -o christmas-tree && ./christmas-tree

    Danach sollte eigentlich ein schoenes Baeumchen erscheinen. :)


  14. Maik Broemme

    Die Formatierung mag mich nicht. :) Also hier der Einzeiler:

    https://babelize.org/christmas-tree


  15. Arnd Koch

    kein wirklich huebscher baum, aber immerhin ;)

    perl -e ‘@”=split”,”,”H\n,”.(“\\\n,/,”x3).”^\n”;print” “x$_,pop@”for(split”",21111032)’


  16. Matthias Müller

    Hallo!

    Hier noch ein kleiner Ruby Einzeiler:

    puts (0..30).map{|x|” “*(30-x)+”XX”*x+”\n”}.join+(” “*29+”||\n”)*2

    Ergebnis hier:
    http://www.le-matt.de/blog/nerd-stuff/

    Viele Grüße und ein frohes Fest!

    Matt


  17. Nerd stuff. | le-matt.

    [...] Agentur Seibert Media hat einen kleinen Programmierer-Wettbewerb [...]


  18. linuxer

    Beim Eindampfen eines Mehrzeilers bin ich schließlich bei diesem Einzeiler angekommen:

    perl -e ‘$s=25;printf” %${s}s%-${s}s\n”, (“#”x$_)x2 for 0..$s,1,1;’


  19. Wolfgang

    Der Python-Code lässt sich noch etwas komprimieren:

    for x in range(1,20)+[1]*3: print (‘**’*x).center(42)

    Ein etwas hübscherer Baum in 136 Bytes:

    print ‘\n’.join(['\n'.join([('/%s\\' % ((' '*i if i<n else '__'*i))).center(40) for i in range(n+1)]) for n in range(4)]+[' '*19+'||'])


  20. Martin Neitzel

    Hier eine LANGE Loesung in J (angeregt durch die
    in C). Screenshot miit 1-Zeiler und Ausgabe:
    http://gaertner.de/~neitzel/mc.j.txt


  21. Martin Neitzel

    Und noch etwas schnuckeliges KURZES in J:
    http://gaertner.de/~neitzel/frame.j.txt


  22. Martin Neitzel

    Und nochn Gedicht, wie alles andere natuerlich auch
    ueber ein einziges Argument parametrisiert:
    http://gaertner.de/~neitzel/full.j.txt


  23. Fredi Hottinger

    Hier mein Beitrag, nicht ganz so kurz, aber auf das Ergebnis kommt es an…

    for($anzahl = 2; $anzahl <= 28; $anzahl += 2) {
    $text = str_repeat(“*”, $anzahl);
    echo $text . “”;
    }
    echo str_repeat(“||||||”, 3) ;


  24. Fredi Hottinger

    Entschudligt bitte, das “br” Tag wurde zweimal entfernt,
    Also nochmal mit Entitäten:

    for($anzahl = 2; $anzahl <= 28; $anzahl += 2) {
    $text = str_repeat(“*”, $anzahl);
    echo $text . “<br />”;
    }
    echo str_repeat(“||||||<br />”, 3) ;

    Hoffe jetzt passt es :-)


  25. Hubert Seidel

    program weihbaum; // Delphi 2,3,4,5,…
    {$APPTYPE CONSOLE}

    (*
    ^
    /|\
    /|||\
    /I|||I\
    /IO|||OI\
    /ION|||NOI\
    /IONº|||ºNOI\
    /IONº*|||*ºNOI\
    /IONº*%|||%*ºNOI\
    /IONº*%X|||X%*ºNOI\
    /IONº*%X+|||+X%*ºNOI\
    /IONº*%X+#|||#+X%*ºNOI\
    /IONº*%X+#S|||S#+X%*ºNOI\
    /IONº*%X+#SI|||IS#+X%*ºNOI\
    /IONº*%X+#SIO|||OIS#+X%*ºNOI\
    /IONº*%X+#SION|||NOIS#+X%*ºNOI\
    /IONº*%X+#SIONº|||ºNOIS#+X%*ºNOI\
    /IONº*%X+#SIONº*|||*ºNOIS#+X%*ºNOI\
    /IONº*%X+#SIONº*%|||%*ºNOIS#+X%*ºNOI\
    /IONº*%X+#SIONº*%X|||X%*ºNOIS#+X%*ºNOI\
    /IONº*%X+#SIONº*%X+|||+X%*ºNOIS#+X%*ºNOI\
    |||
    |||
    |||
    *)

    uses
    SysUtils;

    procedure WriteCenter(s:string);
    begin
    writeln(s:40+(Length(s) shr 1));
    end;

    const
    nadeln : array[0..9] of char =’#+X%*§NOIS’;
    stamm = ‘|||’;
    var
    i:integer;
    s:string;
    begin
    s:=’^'; WriteCenter(s);
    s:=’/|\’; WriteCenter(s);
    s:=stamm;
    i:=19;
    while (i>0) do
    begin dec(i);
    WriteCenter(‘/’+s+’\');
    insert(nadeln[i mod Length(nadeln)],
    s, Length(s) shr 1);
    insert(nadeln[i mod Length(nadeln)],
    s, Length(s) shr 1+3);
    end;
    for i:=1 to 3 do WriteCenter(stamm);
    readln;
    end.

    ===========
    Frohe Weihnachten (nachträglich)….


  26. Martin Seibert

    Unsere Kommentarfunktion ist einfach nicht richtig ASCII-fähig. Sorry dafür. :-)


  27. Hubert Seidel

    Das folgende COM-Programm mit NASM assembliert ist 97 Bytes groß :-)

    ;DOS => nasm weihbaum.asm -fbin -o weihbaum.com
    org 0100h

    section .text

    @Start: call @InitOutput
    ;==============================
    mov cx, 19
    mov byte [txt+39], ‘X’
    call @Output
    @Blp01:
    call @Expand
    call @Output
    loop @Blp01
    ;
    call @InitOutput
    mov dword [txt+38], ‘XXX’
    mov cl,3
    @Blp02: call @Output
    loop @Blp02
    ;
    ;==============================
    mov ax, 04c00h ; Exit 0
    int 021h

    @InitOutput:
    mov di, txt
    mov al, 32
    mov cl, 79
    cld
    rep stosb
    mov ax, 0a0dh
    stosw
    mov al, ‘$’
    stosb
    ret

    @Output:
    mov dx, txt
    mov ah,009h
    int 021h
    ret

    @Expand:
    mov si, txt+9
    mov di, txt+68
    mov ah, 30
    @Alp01: mov al,[si+1]
    mov [si],al
    mov al,[di]
    mov [di+1],al
    inc si
    dec di
    dec ah
    jnz @Alp01
    ret

    txt equ $

    OK, auch wenn die Darstellung hier hinkt,
    hier die (verzerrte) Ausgabe :

    X
    XXX
    XXXXX
    XXXXXXX
    XXXXXXXXX
    XXXXXXXXXXX
    XXXXXXXXXXXXX
    XXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXX
    XXX
    XXX

    mfg.
    Herby


  28. Hubert Seidel

    Hinweis zum Assembler-Programm:
    Leider wurde der Quellcode durch HTML bzw. WebServer leicht zerstört.
    Nachdem mit Copy&Paste des Quellcodes nach weihbau.asm vorgenommen wurden, alle einfachen anführungszeichen nach Shift+# (ASCII-Zeichen 39) wandeln.
    Anschließend sollte sich der Quellcode wieder ohne Fehler und/oder Warnings assemblieren lassen :)

    mfg.
    Herby


  29. Hubert Seidel

    ; ^
    ; /|\
    ; /|||\
    ; /%|||%\
    ; /%#|||#%\
    ; /%#%|||%#%\
    ; /%#%*|||*%#%\
    ; /%#%*O|||O*%#%\
    ; /%#%*OX|||XO*%#%\
    ; /%#%*OXº|||ºXO*%#%\
    ; /%#%*OXºS|||SºXO*%#%\
    ; /%#%*OXºSI|||ISºXO*%#%\
    ; /%#%*OXºSI8|||8ISºXO*%#%\
    ; /%#%*OXºSI8@|||@8ISºXO*%#%\
    ; /%#%*OXºSI8@H|||H@8ISºXO*%#%\
    ; /%#%*OXºSI8@H&|||&H@8ISºXO*%#%\
    ; /%#%*OXºSI8@H&N|||N&H@8ISºXO*%#%\
    ; /%#%*OXºSI8@H&NZ|||ZN&H@8ISºXO*%#%\
    ; /%#%*OXºSI8@H&NZ0|||0ZN&H@8ISºXO*%#%\
    ; /%#%*OXºSI8@H&NZ0º|||º0ZN&H@8ISºXO*%#%\
    ;/%#%*OXºSI8@H&NZ0º%|||%º0ZN&H@8ISºXO*%#%\
    ; |||
    ; |||
    ; |||

    ;DOS => nasm weihbaum.asm -fbin -o weihbaum.com
    org 0100h

    section .text

    jmp @Start

    @InitOutput:
    mov di, txt
    mov al, 32
    mov cl, 79
    cld
    rep stosb
    mov ax, 0a0dh
    stosw
    mov al, ‘$’
    stosb
    ret

    @Output:
    mov dx, txt
    mov ah,009h
    int 021h
    ret

    @Expand:
    mov si, txt+9
    mov di, txt+68
    mov ah, 30
    @Alp01: mov al,[si+1]
    mov [si],al
    mov al,[di]
    mov [di+1],al
    inc si
    dec di
    dec ah
    jnz @Alp01
    ret

    @Start: call @InitOutput
    ;==============================
    mov cx, 18
    mov byte [txt+39], ‘^’
    call @Output
    mov dword [txt+38], ‘/|\’
    call @Output
    mov bx, nadeln
    call @Expand
    call @Output
    @Blp01:
    call @Expand
    mov al, [bx]
    inc bx
    mov [txt+37],al
    mov [txt+41],al
    call @Output
    loop @Blp01
    ;
    call @InitOutput
    mov dword [txt+38], ‘|||’
    mov cl,3
    @Blp02: call @Output
    loop @Blp02
    ;
    xor ah,ah
    int 016h ; Warte auf Tastendruck
    ;==============================
    mov ax, 04c00h ; Exit 0
    int 021h
    nadeln db ‘%#%*OX§SI8@H&NZ0§%’
    txt equ $

    Optisch anspruchsvoller und kompatibel zu meiner Delphi-Variante, jedoch mit 152 Bytes 55 Bytes größer als die einfache Assembler-Variante… (Nach Copy&Paste nicht vergessen vor dem Assemblieren die Singlöe-Quotes anzupassen)


  30. Hubert Seidel

    Und nun noch eine dritte (ich glaube meine letzte) Assembler-Variante!
    Diesmal ist das assemblierte Programm nur noch 56 Bytes groß :-) ))

    ; XXX
    ; XXXXX
    ; XXXXXXX
    ; XXXXXXXXX
    ; XXXXXXXXXXX
    ; XXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ; XXX
    ; XXX
    ; XXX

    ;DOS => nasm weihbaum.asm -fbin -o weihbaum.com
    org 0100h

    section .text

    stamm equ 3*256+38

    @Start:
    ;==============================
    mov bx, stamm
    mov cl, 20
    @Blp01: call @Line
    add bh, 2
    dec bl
    loop @Blp01
    mov bx, stamm
    mov cl, 3
    @Blp02: call @Line
    loop @Blp02

    ;==============================
    int 020h ; Exit 0

    @Line: push bx
    mov dl, 32
    mov ah, 2
    @Clp01: int 021h
    dec bl
    jnz @Clp01
    mov dl, ‘X’
    @Clp02: int 021h
    dec bh
    jnz @Clp02
    mov dl, 13
    int 021h
    mov dl, 10
    int 021h
    pop bx
    ret


  31. Merten Falk

    #!/usr/bin/perl
    my $h=9;
    for(0..($h-3)){
    printf(“%si%s%s%s%s\n”,’ ‘x($h-3-$_),($_>1)?(‘/’x($_-1)):”,($_>0)?’|':”,($_>1)?(‘\\’x($_-1)):”,($_>0)?’i':”);
    }
    print (((‘ ‘x($h-4).’|||’).”\n”)x2);

    Ausgabe:

    i
    i|i
    i/|\i
    i//|\\i
    i///|\\\i
    i////|\\\\i
    i/////|\\\\\i
    |||
    |||


  32. Hubert Seidel

    In 266 Bytes Assembler-Quellcode mit 28 Mnemonics zu 55 bytes assembliert (für 80×25 Zeichen ASCII-Ausgabe optimiert):

    mov bx,806
    push bx
    mov cl,20
    A:call C
    add bh,2
    dec bl
    loop A
    pop bx
    mov cl,3
    B:call C
    loop B
    int 020h
    C:push bx
    mov dl,32
    mov ah,2
    D:int 021h
    dec bl
    jnz D
    mov dl,88
    E:int 021h
    dec bh
    jnz E
    mov dl,13
    int 021h
    mov dl,10
    int 021h
    pop bx
    ret

    Ein Byte kleiner als vorher :-)


  33. Hubert Seidel

    Und für die Leute die kein NASM haben und den Assembler-Tannebaum dennoch auf die Schnelle sehen wollen und im guten alten DOS noch das alte DEBUG haben, hier die Easy-DOS-Variante in drei Schritten:

    a) Den folgenden Text in eine Text-Datei namens “weihbaum.txt” speichern (ohne =====):

    =====
    nweihbaum.com
    a
    mov bx,0326
    push bx
    mov cl,14
    call 11a
    add bh,2
    dec bl
    loop 106
    pop bx
    mov cl,3
    call 11a
    loop 113
    int 20
    push bx
    mov dl,20
    mov ah,2
    int 21
    dec bl
    jnz 11f
    mov dl,58
    int 21
    dec bh
    jnz 127
    mov dl,d
    int 21
    mov dl,a
    int 21
    pop bx
    ret

    rcx
    37
    w
    q
    =====

    Ohne “=====” bedeutet: Erste Zeile enthällt “nweihbaum.com”, die letzte nur ein “q” (die Leerzeile vor rcx ist wichtig!).

    b) In der Commandozeile debug wie folgt aufrufen:
    debug < weihbaum.txt
    um weihbau,com zu erstellen

    c) Ausgabe mit Starten von weihbaum.com in der DOS-BOX:
    weihbaum.com

    :-)


  34. Hubert Seidel

    In der Assembler-Variante konnte tatsächlich noch ein byte sparen :=))
    =====
    nweihbaum.com
    a
    mov bx,326
    push bx
    mov cl,a
    call 116
    add bh,2
    dec bl
    loop 106
    pop bx
    call 116
    int 20
    call 119
    push bx
    mov dl,20
    mov ah,2
    int 21
    dec bl
    jnz 11e
    mov dl,58
    int 21
    dec bh
    jnz 126
    mov dl,d
    int 21
    mov dl,a
    int 21
    pop bx
    ret

    rcx
    36
    w
    q
    =====
    Mit nur noch 54 Bytes wird der Weihnachsbaum sogar in einer besseren Proportion dargestellt :-)
    Zudem konnte ich es ohne zusätzliche Installation auf:
    MS-DOS 3.30c, Win Me und W2k
    mit DEBUG assemblieren und laufen lassen. (XP und Vista konnte ich leider nicht testen)
    Viel Spaß!


  35. Hubert Seidel

    Hallo allerseits, da ich nun wirklich nicht mehr glaube noch etwas optimieren zu können, hier alle meine Versionen auch zum Download:
    http://www.hubert-seidel.eu/downloads/weihbaum.zip
    In den 41kb sind alle Quellcodes und Binaries für Delphi, NASM und DEBUg enthalten, sowie Build-/Run-Skripte und je eine output.txt in der die Ausgabe festgehalten wurde. Das sich mit nur [echten binären] 54 Bytes (ohne Interpreter/Laufzeitumgebung/etc) in der Console ein Tannebaum in ASCII ausgeben lässt, kann ich selber fast nicht glauben (-; obwohl ich es ja selber programmiert habe :-)


  36. LanX

    Hier mal ein etwas andere Ansatz in Perl mittels Exponentialfunktion, die aber mit dem internen Sieger mithalten können:

    Hat 2 Vorteile:
    1. Mit der Basis (hier 4) stellt man die Steigung des Baumes nahtlos ein, weil auch Brüche erlaubt sind.
    2. Ersetzen der Zahlenmuster taugen für Texturen wie Baumschmuck.

    Ich habe in den Grafiken die Leerzeichen mit . ersetzt, um sie darstellen zu können (bitte letzten Post löschen)

    ____________________

    .35Bytes: printf”%20d%d\n”,(4**$_)x2for 1..17
    .
    ………………..44
    ……………….1616
    ……………….6464
    ………………256256
    ……………..10241024
    ……………..40964096
    …………….1638416384
    …………….6553665536
    ……………262144262144
    …………..10485761048576
    …………..41943044194304
    ………….1677721616777216
    ………….6710886467108864
    …………268435456268435456
    ………..10737418241073741824
    ……………….-1-1
    ……………….-1-1
    .____________________
    .
    .35Bytes: printf’%20d%1$d’.$/,4**$_ for 1..17
    .
    ………………..44
    ……………….1616
    ……………….6464
    ………………256256
    ……………..10241024
    ……………..40964096
    …………….1638416384
    …………….6553665536
    ……………262144262144
    …………..10485761048576
    …………..41943044194304
    ………….1677721616777216
    ………….6710886467108864
    …………268435456268435456
    ………..10737418241073741824
    ……………….-1-1
    ……………….-1-1
    .____________________
    Geschmückter Baum, lässt sich noch optimieren…
    .57Bytes: ($x=4**$_)=~y/1-9/”/,printf”%22s%s\n”,($x)x2for 1..20,0,0
    .
    ………………….”"
    …………………”"”"
    …………………”"”"
    ………………..”"”"”"
    ……………….”0″”"0″”
    ……………….”0″”"0″”
    ………………”"”"”"”"”"
    ………………”"”"”"”"”"
    ……………..”"”"”"”"”"”"
    …………….”0″”"”"”0″”"”"
    …………….”"”"”0″”"”"”0″
    ……………”"”"”"”"”"”"”"”"
    ……………”"”0″”"”"”"0″”"”
    …………..”"”"”"”"”"”"”"”"”"
    ………….”0″”"”"”"”"0″”"”"”"”
    ………….”"”"”"”"”"”"”"”"”"”"
    …………”"”"”"”"”"”"”"”"”"”"”"
    …………”"”"”"”"”"”"”"”"”"”"”"
    ………..”"”"”"”0″”"”"”"”"”"0″”"”
    ……….”0″”"”"”"”"”"”0″”"”"”"”"”"
    ………………….”"
    ………………….”"
    .____________________
    .


  37. LanX

    Also Proportionalschrift ist noch ein anderes Problem …

    *TIP*
    Alle missglückten Grafiken lassen sich im Firefox einigermaßen entschlüsseln indem man sie selektiert und per Rechtsklick auf “Quelltext anzeigen” geht!


  38. Neugierig

    And the winner is?


  39. Martin Seibert

    Danke für die Nachfrage. Der Gewinner ist bereits ausgelost, informiert und nimmt den Preis auch an. Allerdings hat er angeboten, selbst einen Blog-Artikel als Gastbeitrag bei uns zu veröffentlichen und wir werden die Bekanntgabe auch im Weblog durchführen. Daher bitten wir noch um ein bisschen Geduld.


  40. Neugierig

    ausgelost ??? phh!


  41. Martin Seibert

    Ja, aus meiner Sicht gab es keinen einzigen “Einreicher”, den ich herausgenommen hätte. Anhand welcher Kriterien hätte die Auswahl stattfinden sollen? Ganz abgesehen davon, war es auch so angekündigt: “Den Sieger küren wir nach bestem Wissen und Gewissen per Losentscheid. “


  42. Neugierig

    Ok, Losentscheid sehe ich heute zum erstenmal, Golfing hört sich halt nach Minimierung der Zeichen und nicht nach Tombola an!

    In einem nachvollziehbaren Verfahren hätte man:

    1. Korrekte Ergebnisse auswählen müssen.
    2. Diese lokal nachvollzogen.
    3. Den oder die Kürzesten gekürt.
    (4. evntuell bei mehreren Gewinnern den Hauptgewinn gelost)

    Das ist zugegeben deutlich aufwändiger als Losen… zu blöd dass ich’s übersehen habe… mea culpa!


  43. Martin Seibert

    Kein Problem. Sinn der Sache war allerdings nicht den Aufwand einzusparen, auch wenn die Mitarbeiter, die den Weblog betreiben, eher weniger Programmierkenntnisse haben. :-)

    Nur Kürze finde ich nicht sinnvoll und hat auch bei uns intern nicht die coolsten Ergebnisse vorgebracht. Es geht ja um den Spass und die Originalität. Die können natürlich aus der Kürze entstehen. Aber die Lösung meines Bruders, die nach einem Zufallsbild bei Google sucht und dann in Asci einen Baum daraus generiert, fand ich schon ziemlich cool.

    Zudem gibt es Programmiersprachen, die für reine “Kürze” nicht geeignet sind. Die hätten dann gar nicht teilnehmen können, oder?

    Ich find’s okay so. :-)


  44. Neugierig

    Fürs Protokoll: Der kürzeste Code war IMHO in J, allerdings habe ich noch nie von J gehört, und wenn *jede* Sprache erlaubt ist, dann schlag ich eine 1 Byte-Lösung in XMAS vor! XMAS ist eine zu entwickelnde “Sprache” die nur einen Befehl kennt, nämlich T für “Tree” und dann einen Weihnachtsbaum zeichnet.

    > Nur Kürze finde ich nicht sinnvoll und hat auch bei uns intern nicht die coolsten Ergebnisse vorgebracht.

    Der gekürte interne Sieger war aber der kürzeste, nicht der coolste!

    > Zudem gibt es Programmiersprachen, die für reine “Kürze” nicht geeignet sind. Die hätten dann gar nicht teilnehmen können, oder?

    Die Wahl der Sprache war dem Entwickler ja auch freigestellt! Anders gefragt: die interne Pythonlösung ist die minimalst mögliche in dieser Sprache, wieso bekam sie keinen Preis “zugelost”?

    Golfing heißt laut verlinkter WP-Seite “Gewinner ist der Programmierer, der für die erfolgreiche Lösung des Problems den kleinsten Quellcode…”

    ich zitiere mal den zwoten Absatz hier:

    “Beim Golf auf dem Rasen gewinnt der Spieler, der die wenigsten Schläge zum Einlochen benötigt. Daran orientiert sich auch der Golfwettbewerb unter Entwicklern: Ziel ist es, eine bestimmte Programmieraufgabe mit möglichst wenig Aufwand zu erledigen. Schnelligkeit und selbst Schönheitspreise spielen dabei untergeordnete Rollen, vielmehr zählen Kreativität und technologisches Know-how. Sieger des Wettbewerbs ist in der Regel der Teilnehmer mit dem schlankesten Code und damit derjenige, der die höchste Effizienz und Effektivität an den Tag legt.”

    Sach mal, dein Schwerpunkt liegt eher im Verkauf als in der Technik, oder?


  45. Martin Seibert

    Jep, vollkommen richtig. :-)

    Es mag sein, dass der Text etwas missverständlich zu Beginn ist. Trotzdem haben wir von Beginn an vorgehabt zu losen, haben es so geschrieben und so gemacht.

    Mir bleibt eigentlich nur, mich auf Deine neue Programmiersprache “XMAS” zu freuen. :-D


  46. Matthias Rauer

    Zu J gibt es an dieser Stelle übrigens demnächst einen interessanten Artikel – also dranbleiben :-)


  47. Neugierig

    Da J zumindest ne Webseite und einen Wikieintrag hat, will ich mal hoffen dass Martin Neitzel ausgelost wurde…


  48. Martin Seibert

    Das darf an dieser Stelle natürlich noch nicht verraten werden. :-)


  49. Hubert Seidel

    Hallo allerseits,

    es gibt den XMAS-Compiler!
    Ich habe ihn heute programmiert und zum Download zur Verfügung gestellt:
    http://www.hubert-seidel.eu/downloads/xmasc1v00.zip
    Enthalten ist der Compiler “xmasc” bereits compiliert und natürlich incl. Delphi5-Quellcode sowie zwei xmas-Beispiele (ein HelloWorld und Minimal-Quelltext für das Entwickler-Golf => Es funktioniert prächtig!!).
    Das compilierte Programm sollte min. ab DOS3.3 (oder gar früher?) bis min. XP in der DOS-Box laufähig sein. Evtl. kann ja jemand berichten ob’s gar unter Vista läuft…

    Das Hello-World-Beispiel (Quellocde incl. Kommentare 61 bytes) id compiliert 65 Bytes groß.

    Das Minimal-Beispiel ist als Quelltext genau 1 Byte groß, und das compilierte Programm 61 Bytes.

    Das Beispiel kann unter DOS wie folgt compiliert werden:
    xmasc mini.xma
    Es wird mini.com generiert welches mit mini ausgeführt wird.

    xmasc versteht derzeit zwei Token und Kommentare #

    T gibt ein Baum aus
    ; wartet auf ein Tastendruck
    # alles danach wird ignoriert
    Die Befehle sind nicht case sensitiv.

    Der Compiler zerlegt den Quellcode in Token, schreibt anschl. ein Programm-Stub und generiert anschl. Code entsprechend der zerlegten Token.

    Viel Spaß &
    gruss
    Hubert


  50. Hubert Seidel

    Ergänzung:
    Der XMAS-Compiler selber läuft nicht unter DOS, sondern ab Win95 und höher.
    Das compilierte Programm hat als Zielplattform DOS.


  51. Entwicklergolf bei //SEIBERT/MEDIA: Weihnachtsbäume mit J | //SEIBERT/MEDIA Weblog

    [...]


  52. Matthias Rauer

    Wir haben den Preisträger ermittelt und stellen ihn und seine Ergebnisse in einem separaten Blog-Artikel vor: http://blog.seibert-media.net/2009/01/arbeitstechniken/entwicklergolf-bei-seibert-media-weihnachtsbaeume-mit-j/

    Vielen Dank allen Teilnehmern für die schönen Vorschläge :-)


  53. Martin Neitzel

    Nach 10 Tagen Luft anhalten Gruesse von mir an anderen Teilnehmer und ein paar Anmerkungen:

    Ich finde die LanX-Loesungen ganz toll! Wahres Hackertum in Reinkultur, das auch alle meine Kollegen sehr erfreut hat.

    Wenn ich alles richtig verglichen habe, ist mein J Code tatsaechlich sehr sehr kurz, aber “Auslosen” halte ich
    auch fuer ein adaequates Verfahren: So sind am meisten Leute eingeladen mitzumachen, und zwar auch mit Ansaetzen, die absehbar nicht die kuerzesten Ergebnisse leifern koennen, dafuer aber vielleicht schoen perverse.
    Vielen Dank zum Beispiel fuer die “Assembler-Quetschungen”! Es ist so lange her, dass ich selbst mal Assembler gemacht habe, dass ich gar kein Gefuehl mehr dafuer habe, wie lang sowas auf diesem Weg wird. Schoen, das mal wieder sehen zu koennen.

    Auch schoen: Die vielen Beitraege, die das bekannte Verfahren einfach nur uebernommen und andere Sprachen uebertragen haben. Das ist immer eine gute Gelegenheit, mal ein bisschen quer zu gucken und evtl. auch die Scheu zu verlieren, eine der noch unbekannten Sprachen anzugehen. So etwas geht ja IMMER irgendwie auf der Ebene “Hello World!” oder eben “Weihnachstbaum” los.

    Ich habe vom Wettbewerb uebrigens ueber eine der Newsgroups (de.comp.lang.misc?) Ende Dezember mitbekommen — vielen Dank an den Poster des Hinweises!

    Und zu guter letzt:

    Zusammen mit einem Kollegen fand ich letzte Woche einen weiteren Ansatz in J, der noch mal 4 Zeichen kuerzer ist. See you next year :-)


  54. Neugierig

    > “Ich finde die LanX-Loesungen ganz toll! Wahres Hackertum in Reinkultur, das auch alle meine Kollegen sehr erfreut hat.”

    Allerdings!

    > aber “Auslosen” halte ich
    auch fuer ein adaequates Verfahren: So sind am meisten Leute eingeladen mitzumachen, und zwar auch mit Ansaetzen, die absehbar nicht die kuerzesten Ergebnisse leifern koennen, dafuer aber vielleicht schoen perverse.

    Eine Abstimmung der Beteiligten wäre noch besser … so bleibt der schale Nachgeschmack einer Onlinemarkingaktion mit BWLer-Floskeln!


  55. Martin Seibert

    Der Vorwurf ist nicht auszuräumen. Das ganze ist eine Online-Marketing-Aktion mit BWLer-Floskeln. :-D

    Beim nächsten Mal werden wir mal schauen, ob wir einen Entwickler zur Organisation überreden können. Ansonsten müssen wieder die BWLer mit ihrem Blabla für die Orga herhalten. Ich hoffe, dass Du trotzdem dabei sein wirst.


Eine Antwort hinterlassen





//SEIBERT/MEDIA besteht aus den vier Kompetenzfeldern Consulting, Design, Technologies und Systems und gehört zu den erfahrenen und professionellen Multimedia-Agenturen in Deutschland. Wir entwickeln seit 1996 mit heute über 65 Mitarbeitern Intranets, Extranet-Systeme, Web-Portale aber auch klassische Internet-Seiten. Seit 2005 konzipiert unsere Designabteilung hochwertige Unternehmensauftritte und kommunikative Konzepte. Beratungen im Bereich Online-Marketing und Usability runden das Leistungsportfolio ab.

Zu unseren teils weltweit agierenden Kunden gehören u.a. Accor, Allianz, Atlas MTT, BAD, Deutsche Klinik für Diagnostik, Deutsche Post, Hitachi, Honda Motor, Hotel InterContinental, Institut Fresenius, Kabel Deutschland, Lufthansa, SAP, SGS AG, STA Travel, StepStone sowie viele andere große und kleine interessante Unternehmen.