kostenloser Webspace werbefrei: lima-city


Ein Rätsel für Programmierer

lima-cityForumProgrammiersprachenSonstige Programmiersprachen

  1. Autor dieses Themas

    web-mole

    web-mole hat kostenlosen Webspace.

    Hallo Zusammen,

    als ich mich mal wieder bei der arbeit durch das Web gewühlt habe um etwas zu recherchieren bin ich auf eine kleine Herausforderung gestoßen. Ich nenne es mal ein Rätsel. Die Programmiersprache ist irrelevant.

    Oftmals erstellt man eine Variable nach der anderen, auch wenn man die Alten vielleicht gar nicht mehr braucht. Nein, jede kleine Änderung wird in eine neue Variable gespeichert, die alte bleibt bestehen und sei sie noch so sinnlos (Macht nicht jeder, aber man sieht manchmal viel bei anderen)
    Nun bleiben alle diese Variablem bestehen bis das Programm endlich durchgelaufen ist, belegen den speicher, es wird langsam... in der heutigen zeit wo der Speicher auch immer weiter zunimmt, etwas worüber sihc die wenigsten Gedanken machen.

    Daher nun meine Herausforderung an Euch, das Rätsel:

    Ihr habt 2 Variablen, mit unterschiedlichem Wert. Es könnte ein INT sein, es könnte ein String sein, es könnte ein Objekt sein, was auch immer. (Ihr könnt es euch gerne aussuchen, interessanter ist natürlich eine Lösung die immer funktionieren würde ;-) )

    Das Ziel ist es, die Werte der beiden Variablen zu vertauchen ohne jedoch eine weitere Variable zu erstellen.

    Beispiel:
    $foo="wert";
    $bar="test";

    Ergebniss:
    $foo="test";
    $bar="wert";

    (Ja das ist nun php, aber ob ihr es in Java oder sonst was macht: egal!)

    So, ich hoffe das Thema passt in diesen Forum, ansonsten entschuldige ich mich ^^
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

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

  3. g****e

    Mit PHP kann man aber sehr schummeln. Du verbietest nur das anlegen einer Variable, also
    $a = 1; $b = 2;
    ob_start();
    echo $a;
    $a = $b;
    $b = ob_get_clean();

    Und die Werte sind getauscht ohne eine weitere Variable anzulegen.
    Für C++ gibt es dafür sogar funktionen:
    #include <algorithm>
    #include <iostream>
    int main(int argc, char** argv) {
     int a = 1, b = 2;
     std::cout << a << b << endl;
     std::swap(a,b);
     std::cout << a << b << endl;
    }

    In Javascript löst man das dann mittels Cookies als keine Variable, aber Speicherbereich:
    var a = 1, b = 2;
    document.cookie = a;
    a = b;
    b = document.cookie;


    Ich glaub zwar das ist stets geschummelt, aber erfüllt den Zweck ;-)

    Liebe Grüße
  4. Bei INT oder LONGINT geht das mit XOR so...

    a = a^b
    b = a^b
    a = a^b
  5. h**s

    <?php
    	list($bar,$foo) = array($foo,$bar); 
    ?>
  6. t**k

    In Python kann man sowas machen:

    Code:
    x = 0
    y = 1
     
    print 'x: ', x, ', y:', y
     
    x, y = y, x
     
    print 'x: ', x, ', y:', y


    Ausgabe:
    x:  0 , y: 1
    x:  1 , y: 0


    Das vertauscht die Werte der Variablen und ist mit allen Datentypen möglich.
  7. Ich weiß nicht, ob das funktioniert, es ist auch ein mathematisches Problem.

    a = a * b
    b = a / b
    a = (b^-1) * a


    Als erstes werden a und b in a multipliziert. Danach wird b zum Quotienten vom zuvor gebildeten Produkt a*b und b, dass b a wird.
    Danach wird in a der Kehrwert des Quotienten...

    Ach mist, funktioniert nicht. Zum Schluss ist a 1, weil b ja schon a ist... :(

    Edit:

    a = a * b
    b = a / b
    a = a / b


    Müsste klappen, habs noch nicht probiert.

    Noch ein Edit:

    Es funktioniert in PHP. Aber es funktioniert natürlich nur mit Zahlen.

    Beitrag zuletzt geändert: 12.3.2013 17:21:05 von stertingen
  8. Assembler:
    xchg eax,ebx
    Standard ist natürlich die Anwendung von XOR und in jeder Sprache, die soetwas nicht nativ unterstützt vorzuziehen.

    Ohne XOR auch in Java möglich (es sollte ja für beliebige Datentypen funktionieren):
    Object v1, v2;
    public void xchg(Object v1, Object v2) {
       this.v1 = v2;
       this.v2 = v1;
    }
    Entsprechend für beliebige Variablen (ungetestet):
    public void xchg(Integer alt1, Integer alt2) {
       tauschen(alt1, alt2, alt2);
    }
    private void tauschen(Integer alt1, Integer alt2, int neu1) {
       alt2 = alt1.intValue();
       alt1 = neu1;
    }
    
    public void main() {
       Integer v1, v2;
       // ...
       xchg(v1, v2);
    }
    Letztere Variante auf beliebige Typen zu erweitern ohne for-Schleifen zu benutzen (denn dann wird für den Programmierer sichtlich eine neue Variable erzeugt) ist allerdings etwas aufwändiger.
    In C ist diese Idee übertragbar: Für beliebige Typen müssen einfach die Zeiger z1 und z2 mit XOR behandelt werden:
    z1 = (void*)(*(void*)z1 ^ *(void*)z2)
    z2 = (void*)(*(void*)z1 ^ *(void*)z2)
    z1 = (void*)(*(void*)z1 ^ *(void*)z2)

    Ich will aber auch sagen, dass ich es nicht gutheißen kann, die Minimierung der Varaiblenanzahl als Maxime zu betrachten. Lieber habe ich eine Variable zu viel und lösche sie, sobald ich sie nicht mehr brauche, als dass ich zwei Variablen verschränke und somit unnötige Fehler entstehen. Denn das geht mathematisch sogar so weit, dass man theoretisch nur eine Variable benötigt; wobei man hier das Wort Variable ebenso im rein mathematischen Kontext gesehen werden muss. In der Praxis klappt das nur bei den wenigsten Programmiersprachen (je maschinennäher, desto unwahrscheinlicher).

    Ich hoffe alle Programmausschnitte funktionieren so, wie ich sie angegeben habe...

    Beitrag zuletzt geändert: 12.3.2013 18:30:34 von toolz
  9. Auf jeden Fall ein interessanter Thread

    web-mole schrieb:
    Oftmals erstellt man eine Variable nach der anderen, auch wenn man die Alten vielleicht gar nicht mehr braucht. Nein, jede kleine Änderung wird in eine neue Variable gespeichert, die alte bleibt bestehen und sei sie noch so sinnlos (Macht nicht jeder, aber man sieht manchmal viel bei anderen)
    Nun bleiben alle diese Variablem bestehen bis das Programm endlich durchgelaufen ist, belegen den speicher, es wird langsam... in der heutigen zeit wo der Speicher auch immer weiter zunimmt, etwas worüber sihc die wenigsten Gedanken machen.

    Hier muss man sich die Frage stellen, wie die jeweilige Programmiersprache denn funktioniert. Wenn sie beispielsweise mit einem Compiler optimiert wird, kann es durchaus sein, dass solche "vergessenen" Variablen wegoptimiert werden oder ihr Speicher überschrieben wird.

    Die LLVM Assembler Sprache (für eine abstrakte CPU-Architektur) unterstützt beispielsweise nur SSA (Single Static Assignment), so dass man "Variablen" keinen neuen Wert zuweisen kann. Der LLVM Compiler sorgt dann dafür, dass diese konstanten Variablen günstig auf physikalische Register und Speicherorte verteilt werden.


    Um auf das Rätsel einzugehen: Hier eine Lösung für Lua:
    a, b = b, a


    Beitrag zuletzt geändert: 12.3.2013 18:58:43 von bladehunter
  10. web-mole schrieb:
    Nun bleiben alle diese Variablem bestehen bis das Programm endlich durchgelaufen ist, belegen den speicher, es wird langsam... in der heutigen zeit wo der Speicher auch immer weiter zunimmt, etwas worüber sihc die wenigsten Gedanken machen.


    Nun, da unterscheiden wir ja von globalen und lokalen Variablen (ich gehe mal von Delphi aus).
    Die globalen Variablen bleiben bestehen, bis das ganze Programm fertig ist und werden dann von destruktor freigegeben.
    Lokale Variablen in Funktionen/Prozeduren werden wieder freigegeben, wenn diese Subroutine verlassen wird.

    Es gibt einfache Typen und komplexere wie Objekte. Jede Variable, die ich mit .create erzeuge, sollte ich mit .free freigeben, weil sonst tatsächlich Speicher bestehen bleibt. Aber einfache Typen werden gleich frei gegeben.

    Definierte, aber nicht benutzte Variablen werden vom Compiler wegoptimiert. Der Delphicompiler macht auch auf zugewiesene Werte aufmerksam, die in der Folge gar nicht mehr benutzt werden und ich dann selber weg machen kann, wenn ich will :)


    Das Ziel ist es, die Werte der beiden Variablen zu vertauchen ohne jedoch eine weitere Variable zu erstellen.


    Grundsätzlich muss immer der alte Wert irgendwo und -wie zwischengespeichert werden. Selbst wenn die Programmiersprache sowas wie eine Exchange-Funktion hat, läuft das für den Programmierer unsichtbar im Hintergrund ab - gerade bei komplexen Objekten ist das nur mit Zwischenspeicherung möglich (und wenn es nur die Adresse ist, wo sich das Objekt im Speicher befindet).
  11. mathesoft schrieb:
    Grundsätzlich muss immer der alte Wert irgendwo und -wie zwischengespeichert werden. Selbst wenn die Programmiersprache sowas wie eine Exchange-Funktion hat, läuft das für den Programmierer unsichtbar im Hintergrund ab - gerade bei komplexen Objekten ist das nur mit Zwischenspeicherung möglich (und wenn es nur die Adresse ist, wo sich das Objekt im Speicher befindet).
    Das ist leider nicht korrekt, es geht sehr wohl:
    staymyfriend schrieb:
    Bei INT oder LONGINT geht das mit XOR so...

    a = a^b
    b = a^b
    a = a^b
    Das selbe funktioniert insbesondere auch für Zeiger, also für alle möglichen Datentypen. In Assembler sieht man deutlich, dass auch ohne xchg keine dritte Variable benötigt wird:
    xor eax,ebx
    xor ebx,eax
    xor eax,ebx

    http://de.wikipedia.org/wiki/Dreieckstausch
    http://www.tutego.de/blog/javainsel/2012/05/inselraus-variablen-mit-xor-vertauschen/

    Beitrag zuletzt geändert: 13.3.2013 16:22:53 von toolz
  12. Perl:

    ( $foo, $bar ) = ( $bar, $foo );


    Test:
    perl -E '($foo, $bar) = qw(wert test);   ($foo, $bar ) = ($bar, $foo);   say "$foo $bar" '


    Ausgabe:
    test wert


    Ist natürlich gemogelt, unter der Haube wird eine temp. Kopie angelegt :wink:
  13. toolz schrieb:
    ]Das selbe funktioniert insbesondere auch für Zeiger, also für alle möglichen Datentypen. In Assembler sieht man deutlich, dass auch ohne xchg keine dritte Variable benötigt wird:
    xor eax,ebx
    xor ebx,eax
    xor eax,ebx


    Hm, ja... das ist interessant.

    Wie sieht es da mit den Geschwindigkeiten aus - ist ein XOR-Tausch auch schneller als mit Hilfsvariable?
    mov ecx,eax
    mov eax,ebx
    mov ebx,ecx

    Von der Codemenge ist das gleich...
    Ich müsste erst mein Assembler-Buch rauskramen, um die Zyklen zusammen zu zählen :holy:
  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!