kostenloser Webspace werbefrei: lima-city


String Concatenation Contest!

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    nikic

    Kostenloser Webspace von nikic, auf Homepage erstellen warten

    nikic hat kostenlosen Webspace.

    Einen schönen Abend an alle PHP-Entwickler!

    Hier mal ein kleiner Contest zum Thema String Concatenation!

    Vorweg: Was gibt es zu gewinnen? Nix. Ist nur so aus Spaß.

    Also, worum gehts?
    Ganz einfach: Man soll zwei Strings - in den Variablen $a und $b enthalten - aneinanderfügen und in eine Variable $c schreiben.

    Gut, das ist nicht sonderlich schwer, ein $c = $a . $b; und man ist fertig.

    Daher gibt es einige weitere Bedingungen:
    * Keine Punkte (.)
    * Keine Kommata (,)
    * Keine Variablen in Strings (Der Einfachkeit halber sind daher "-Strings und HEREDOC verboten, '-Strings und NOWDOC sind weiterhin erlaubt!)
    * Kein eval, sowie kein include und require [Neu dazugekommen]
    * Kein Output Buffering

    Ich bin gespannt auf Lösungen :D

    Bitte prüft, ob euer Script den Anforderungen entspricht, bevor ihr es postet
    Prüfen könnt ihr einfach indem ihr folgendes Script vor eurem Code einfügt und es laufen lässt:
    <?php
    $source = stream_get_contents(fopen(__FILE__, 'r'), -1, __COMPILER_HALT_OFFSET__);
    if (!preg_match('/[.,"]|eval|require|include|ob_|<<<(?!\')/', $source, $matches, PREG_OFFSET_CAPTURE)) {
        echo 'Script passed!';
    }
    else {
        echo 'Script did NOT pass: Unexpected "', $matches[0][0] , '" at offset ', $matches[0][1];
    }
    __halt_compiler();


    Beitrag zuletzt geändert: 24.6.2010 15:40:08 von nikic
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. <?php
    $a = 'Foo';
    $b = 'Bar';
    for( $i = 0; $i < strlen( $b ); $i++ ) {
    $a[ $i + strlen( $b ) ] = $b[ $i ];
    }
    echo $a;
    ?>

    edit: Das ganze für beliebige String Inhalte optimiert

    Beitrag zuletzt geändert: 24.6.2010 15:40:45 von nikic
  4. <?php
    $a = array();
    $a[0] = 'blablabla';
    $a[1] = 'albalbalb';
    
    $c = join($a);
    echo $c;
    
    ?>


    edit: und jetzt kommt ja nicht damit, dass keine arrays verwendet werden dürfen :shaft:

    €dit by nikic: $a = array(); hinzugefügt.

    Beitrag zuletzt geändert: 24.6.2010 15:41:04 von nikic
  5. Autor dieses Themas

    nikic

    Kostenloser Webspace von nikic, auf Homepage erstellen warten

    nikic hat kostenlosen Webspace.

    Ich hab die beiden Varianten am Anfang gelöscht, die nicht den Bedingungen entsprachen.

    @cbhp: Die HEREDOC Variante fällt auch unter den Punkt "Keine Variablen in Strings".

    @bladehunter: Ja, genau so hätte ich das auch gemacht. Ich war mir aber nicht sicher, ob PHP das Erweitern von Strings über Array Access ohne E_NOTICEs zulässt. Scheinbar tuts das :D Also erste gültige Lösung!

    @syberspace: Nachdem ich die eine Zeile in deinen Code eingefügt hab, stellt das die zweite gültige Lösung dar! Dass join/implode auch ohne den glue Parameter funktioniert wusste ich net, mal wieder was dazugelernt.

    Beitrag zuletzt geändert: 24.6.2010 15:41:38 von nikic
  6. Autor dieses Themas

    nikic

    Kostenloser Webspace von nikic, auf Homepage erstellen warten

    nikic hat kostenlosen Webspace.

    So, da poste ich mal gleich selber eine Lösung:
    <?php
        $a = 'Foo';
        $b = 'Bar';
        require urldecode('data://text/plain;base64%2CPD9waHAgJGM9JGEuJGI7');
        
        echo $c;
    ?>


    Zugegeben, damit das geht, muss man allow_url_include in der php.ini auf On setzen. Aber danach gehts ;)

    Beitrag zuletzt geändert: 23.6.2010 16:21:18 von nikic
  7. mal sehen, die aufgabe ist ja die strings irgendwie zu verbinden, ohne die verbotenen Zeichen zu benutzen, da hätte ich noch das hier anzubieten, leider kommen da aber ein paar zeichen dazu...
    <?php
    class strings {
    	public $foo = 'foo';
    	public $bar = 'bar';
    }
    $data = new strings();
    $data = http_build_query($data);
    echo( $data );
    ?>
    aber vielmehr geht bei deinen einschränkungen auch nicht mehr, zumindest nicht mit dem php-core.
  8. Jo, wie ich schon geschrieben hatte, vielmehr geht nicht, im php-core gibts keine Funktionen mehr die Strings verbinden, ohne zumindest ein Komma benutzen zu müssen, ansonsten könnte man noch lustige Sachen mit Dateihandels veranstalten, aber da braucht man ständig Kommas.
    Appropot bei einem solchen Thema wünscht man sich doch irgendwie wieder das Karma zurück, ich hätte schon 1-2 Beiträge, zu denen ich Karma gegeben hätte.
    Übrigens ist mir grade aufgefallen, dass man die Variante von @bladehunter auch noch unter den jetzigen Regeln verwenden kann, wenn man die eckigen Klammern gegen geschweifte austauscht, sollte so auch funktionieren:
    <?php
    $a = "Foo";
    $b = "Bar";
    for( $i = 0; $i < strlen( $b ); $i++ ) {
    $a{ $i + strlen( $b ) } = $b{ $i };
    }
    echo $a;
    ?>
  9. Autor dieses Themas

    nikic

    Kostenloser Webspace von nikic, auf Homepage erstellen warten

    nikic hat kostenlosen Webspace.

    Ui, hier war ja richtig Aktivität... ich habe wieder einige ungültige Versionen gelöscht und auch alle Beiträge, die keine weiteren Lösungen einsenden.

    @fabo:
    Sagtest du nicht, dass , verboten wäre? =)
    Argh. Da hast du Recht. Ich hab es jetzt so angepasst, dass statt dem Komma ein %2C da steht und ich das decodiere.
    Ebenso folgendes: Kein eval(), sowie kein include und require [Neu dazugekommen]
    Daher steht da auch "Neu dazugekommen". Das habe ich nach meiner Lösung verboten. Arrays und ArrayAccess habe ich nach bladehunters Lösung und nach dem implode() Variante aus dem Spiel genommen ;)
    Dein Script
    <?PHP
    $a = "Foo";
    $b = "Bar";
    $c = "{$a}{$b}";
    
    echo $c;
    ?>

    geht nicht, da es gegen "* Keine Variablen in Strings (damit ist etwas gemeint wie "$a". '$a' ist natürlich weiterhin erlaubt.)" verstößt.

    @thomasba:
    * Keine Arrays und kein ArrayAccess jeglicher Form [Neu dazugekommen]
    Streng genommen ist ein String doch eine Form von Array :megarofl:

    Ja, ich wusste nicht wie ich das ausdrücken sollte. Gemeint ist, dass '[' verboten ist. Deine Variante mit dem implode entspricht der Variante von syperspace, die hast du sicher übersehen ;)

    @nemoinho: Es sollten eigentlich wirklich nur die Zeichen selbst zusammengefügt werden. Aber ich lass es erstmal stehen.

    @wagnerm: Siehe thomasba.

    @ggame: Sorry, deine Variante ist leider auch ungültig, du hast da ein Komma drin beim Öffnen des File Handles. (ggames Variante findet ihr in seinem Gästebuch: http://www.lima-city.de/profile/ggamee#guestbook)

    @nemoinho: Ah ja, das ist auch nice. Das wird dann gleich das nächste Verbot :D

    Ich bin mal gespannt, ob es noch irgendwelche verrückten Lösungen gibt :D

    €dit: Ich glaube die Beschränkung keine Arrays zu nutzen ist wirklich zu hart. Ich habe die wieder aus den Regeln genommen ;) Jetzt sollten noch Lösungen möglich sein.
    Arrays sind wieder erlaubt!

    Beitrag zuletzt geändert: 23.6.2010 16:49:34 von nikic
  10. nikic: Allesamt UNGÜLTIG!

    @sektor:
    Mist! Die Idee mit der Datei hatte ich auch ...
    Dann eben in der HONK-Version:

    // init
    $a = 'fred';
    $b = 'barney';
    
    // concat
    $file = tempnam('', '');
    file_put_contents($file, $a, FILE_APPEND);
    file_put_contents($file, $b, FILE_APPEND);
    $c = file_get_contents($file);
    
    // view
    echo $c;


    str_pad():

    // init
    $a = 'fred';
    $b = 'barney';
    
    // concat
    $c = str_pad($a, strlen($a) + strlen($b), $b);
    
    // view
    echo $c;


    Output-Buffering:
    Oder ist das verboten?

    // init
    $a = 'fred';
    $b = 'barney';
    
    // concat
    ob_start();
    echo $a;
    echo $b;
    $c = ob_get_clean();
    
    // view
    echo $c;


    preg_replace_callback():

    // init
    $a = 'fred';
    $b = 'barney';
    
    // concat
    function _callback($hits) {
        return $GLOBALS['b'];
    }
    $c = preg_replace_callback('/\z/', '_callback', $a);
    
    // view
    echo $c;


    Noch schöner:

    // init
    $a = 'fred';
    $b = 'barney';
    
    // concat
    $c = implode(
        array_intersect_key(
            $GLOBALS, array_flip(preg_grep('/\A[ab]\z/', array_keys($GLOBALS)))
        )
    );
    
    // view
    echo $c;


    Beitrag zuletzt geändert: 24.6.2010 15:51:08 von nikic
  11. Autor dieses Themas

    nikic

    Kostenloser Webspace von nikic, auf Homepage erstellen warten

    nikic hat kostenlosen Webspace.

    Äh, alopex und sektor, habt ihr euch die Regeln überhaupt durchgelesen? Es geht darum eine Möglichkeit zu finden ohne Kommata und die weiteren oben genannten Zeichen.

    Da dauernd Scripts, die nicht den Regeln entsprechen gepostet werden, habe ich mal oben ein Script gepostet, um seinen Quellcode zu prüfen.

    alopex, ich behalte deinen Beitrag bei, weil die letzen beiden Varianten durchaus interessant sind - auch wenn sie zu 300% gegen obige Regeln verstoßen.
  12. Ist zwar nur eine Teillösung, aber...
    <?php
    // predefine
    $a = "123456789";
    $b = "01234";
    $subtotal = 0;
    $expo=1;
    
    for($i=1;$i<=strlen($b);$i++) $expo*=10;
    (int)$subtotal+=(int)$a*$expo+(int)$b;
    (string)$c=(string)$subtotal;
    
    echo $c;
    // check
    if($c == $a.$b) echo "\nworks for all strings (with numbers as values and a combined length of  max 14 and where the first char of the first value is a 1 or above). :p"
    ?>
    Die Komma-Regel ist echt ein wenig störend. Da würde mir sonst noch einiges witziges einfallen. ;) Ansonsten ist da denke ich nicht mehr viel heraus zu holen.

    Beitrag zuletzt geändert: 25.6.2010 23:08:38 von tplus
  13. nikic schrieb:
    Äh, alopex und sektor, habt ihr euch die Regeln überhaupt durchgelesen? Es geht darum eine Möglichkeit zu finden ohne Kommata und die weiteren oben genannten Zeichen.


    Sorry, ich hab gerne mal das Problem, dass ich zwischen dem Verfassen eines Posts und dessen Abschicken eine "Offline-Pause" einlege, und dabei das Reloaden vergesse. Bei dynamisch angepassten Regelwerken versagt diese Methode kläglich.

    Und die Komma-Regel hatte ich auch ursprünglich so interpretiert, dass man das Komma nicht zum "Concatenieren" benutzen darf, wie in sprintf('%s%s', $a, $b) oder so ...

    Das ob_-Beispiel ist nur durch Copy-N-Paste reingerutscht, eigentlich wollte ich es wieder entfernen.

    Ich war mit zu vielen Ablenkungen nebenbei beschäftigt ...


    Da dauernd Scripts, die nicht den Regeln entsprechen gepostet werden, habe ich mal oben ein Script gepostet, um seinen Quellcode zu prüfen.

    Gute Idee, aber laut dem Script ist implode()|joint() jetzt wieder erlaubt? Dann hätte ich noch folgende Idee:

    // init
    $a = 'fred';
    $b = 'barney';
    
    // concat
    $o = (object) NULL; //new Object();
    $o->a = $a;
    $o->b = $b;
    $c = implode((array)$o);
    
    // view
    echo $c;

    Fast kein Array verwendet ... ;-)

    Und dein Test-Script mokiert auch in Stringliteralen (mit einfachen Hochkommas) eingebettete Punkte und Kommas[1].
    Ist das so gewollt?


    alopex, ich behalte deinen Beitrag bei, weil die letzen beiden Varianten durchaus interessant sind - auch wenn sie zu 300% gegen obige Regeln verstoßen.

    Das ist nett.

    Ich hätte auch noch zwei Vorschläge, die ich aber mangels Zeit und Lust noch nicht komplett ausgearbeitet habe:

    1. Wenn es eine Möglichkeit gibt, per SQL zwei Strings zu verknüpfen, und es eine Datenbankerweiterung gibt, die mit prepared-Statements arbeitet, müsste man damit etwas bauen können. Prepared-Statements sind leider wegen der Komma-Regel nötig. So kann man jede der beiden Variablen mit einem Befehl ohne Komma hinzufügen.

    2. Die COM-Extension. Damit kann man beliebige externe Scripts schreiben oder PHP-Strings zu Windows-Scripting-Host-Scripts machen und dann ausführen. Man muss dem Script nur beibringen, wie es mehrere unterschiedliche Parameter entegegennimmt und zwischenspeichert. Ist ein bisschen umständlich, müsste aber funktionieren.

    Damit wird es aber immer absurder -- das Komma als Trennzeichen von Funktions-Argumenten ist nun mal ein essentieller Bestandteil der meisten Programmiersprachen und PHP lebt von der Unzahl der Funktionen seiner Standardlibrary und deren ellenlangen Parameterlisten.
    Das ist wie einhändiges Fahrradfahren -- auf die Dauer nicht gesund. ;-)

    ==
    [1] Ich weiß, der gebildete Mensch schreibt "Kommata". Aber ich sage schließlich auch Koalas und nicht Koalata. :biggrin:
  14. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!