ottogal: Verschachtelte for-Schleifen

Hallo in die Runde,

habe Null Erfahrung mit Javascript und probiere gerade an einer kleinen Farbtafel, die ich nur lokal verwende (also keine valide Seite, nicht schimpfen!). Folgendes funktioniert wie gewünscht, um die 216 Farben der Form #xxyyzz anzuzeigen:

<html>
<head></head>
<body style="font-family: courier, monospace;">
<script language="javascript">
t="";
c=new Array("00","33","66","99","cc","ff");

for(i=0;i<6;i++)
{
t+="<table width=100%>";
for(j=0;j<6;j++)
{
  t+="<tr>";
  for(k=0;k<6;k++)
  {
   L=c[i]+c[j]+c[k];
   t+="<td bgcolor="+L+">&nbsp;&nbsp;&nbsp;<span style=&qout;color:#ffffff&quot;>"+L+"</span>&nbsp;&nbsp;<span style=&qout;color:#000000&quot;>"+L+"</span></td>";
  }
  t+="</tr>";
}
t+="</table>";
};
with(document)
{
write(t);
void(close());
}
</script>
</body>
</html>

Nun wollte ich das Skript so modifizieren, dass auch Zwischenfarben der Form #uvwxyz zu sehen sind (also alle). Das Array bekommt also die einzelnen Hexwerte "0" bis "f", und der Farbstring besteht aus 6 Summanden, die ihre Werte in 6 verschachtelten for-Schleifen bekommen.

Dass das ein Bisschen viel ist, war mir schon klar - es geht natürlich nicht. Was mich aber nun interessiert, ist, woran es scheitert: An der Zahl der for-Ebenen? An der Größe der erzeugten Tabelle? Oder der Länge der erzeugten Tabellenzeilen? Usw.

Weiß wer was?
Es ist übrigens überhaupt nicht wichtig oder eilig - deshalb keine Großbuchstaben. Mich interessierts bloß.

Danke im Voraus
ottogal

  1. Nun wollte ich das Skript so modifizieren, dass auch Zwischenfarben der Form #uvwxyz zu sehen sind (also alle).

    ottogal,
    Du hast eine ungefähre Vorstellung, wie viele das sind?

    Das Array bekommt also die einzelnen Hexwerte "0" bis "f", und der Farbstring besteht aus 6 Summanden, die ihre Werte in 6 verschachtelten for-Schleifen bekommen.

    Und warum so kompliziert? Warum zählst du nicht in einer Schleife von 0 bis 0xFFFFFF?

    Gunnar

    --
    „Solang wir noch tanzen können
    und richtig echte Tränen flennen,
    ist noch alles offen,
    ist noch alles drin.“
    (Gundermann)
  2. 你好 ottogal,

    ich habe nicht so recht verstanden, was du eigentlich tust, aber warum
    machst du das nicht einfach so?:

    function dez2hex(d) {
      max = Math.pow(16,8);
      var z = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
      var x = "";
      var i = 1, v = d, r = 0;
      while(v > 15) {
        v = Math.floor(v / 16); i++;
      }
      v = d;
      for(j=i;j>=1;j--) {
        x = x + z[Math.floor(v / Math.pow(16,j-1))];
        v = v - (Math.floor(v / Math.pow(16,j-1)) * Math.pow(16,j-1));
      }

    return x;
    }

    for(i=0;i<256;++i) {
      for(j=0;j<256;++j) {
        for(k=0;k<256;++k) {
          document.write("<td>#" + dez2hex(i) + dez2hex(j) + dez2hex(k) + "</td>");
        }
      }
    }

    再见,
     CK

    --
    Mensch zu Mathematiker: "Ich finde Ihre Arbeit ziemlich monoton". Mathematiker: "Mag sein! Dafür ist sie aber stetig und unbeschränkt."
    http://wwwtech.de/
    1. Hallo,

      ich habe nicht so recht verstanden, was du eigentlich tust, aber warum
      machst du das nicht einfach so?:

      function dez2hex(d) {
        ...

      ... oder einfach so:

      function dez2hex(d) {
        return d.toString(16).toUpperCase();
      }

      MfG, Thomas

      1. 你好 Thomas,

        ... oder einfach so:

        function dez2hex(d) {
          return d.toString(16).toUpperCase();
        }

        Hehe, das war mir unbekannt, danke.

        再见,
         CK

        --
        Der Verstand ist der Hausherr, der Koerper sein Gast.
        http://wwwtech.de/
        1. Hallo Christian,

          function dez2hex(d) {
            return d.toString(16).toUpperCase();
          }

          Dann könnte man ja eigentlich auch mal das kleine Helferlein vereinfachen.

          Auf diese Weise habe ich jetzt auch festgestellt, jenseits welcher Zahl bei meinem Rechner die Unendlichkeit beginnt:

          255 mal die Ziffer F, ab da ist Sense:

          javascript:alert(0x
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFFFFFFF
          FFFFFFFFFFFFFFF.toString(10))

          Ob das wohl bei allen Rechnern gleich ist?

          Gruß Gernot

      2. function dez2hex(d) {
          return d.toString(16).toUpperCase();
        }

        Hi Thomas,
        Hätte ja fast wieder geklappt, wenn ich nicht noch mehr geschrieben hätte. ;-)

        Biste dir deines „Noes“ sicher?
        Gunnar

        --
        „Solang wir noch tanzen können
        und richtig echte Tränen flennen,
        ist noch alles offen,
        ist noch alles drin.“
        (Gundermann)
        1. Hallo,

          Hätte ja fast wieder geklappt, wenn ich nicht noch mehr geschrieben hätte. ;-)

          Dann ueberlege ich mir das naechste Posting nicht 3x, sondern (3*3*3)x ;-).

          Biste dir deines „Noes“ sicher?

          Noe, also !Noe ;-)

          BTW:
          Ich finde die 3-Schleifen-Loesung des OP auch durchaus intuitiv und habe das vor einiger Zeit aehnlich mit SVG umgesetzt und nochmal analog fuer die 4096 #RGB-Kombinationen. Die in einem davor entstandenen Beispiel verwendete Variante mit toString(16) haette es auch getan -- aber man ist ja flexibel ...

          MfG, Thomas

    2. ich habe nicht so recht verstanden, was du eigentlich tust, aber warum
      machst du das nicht einfach so?:

      function dez2hex(d) {
        max = Math.pow(16,8);
        var z = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
        var x = "";
        var i = 1, v = d, r = 0;
        while(v > 15) {
          v = Math.floor(v / 16); i++;
        }
        v = d;
        for(j=i;j>=1;j--) {
          x = x + z[Math.floor(v / Math.pow(16,j-1))];
          v = v - (Math.floor(v / Math.pow(16,j-1)) * Math.pow(16,j-1));
        }

      return x;
      }

      Christian,
      ich habe zwar verstanden, was du eigentlich tust, aber warum machst du das nicht einfach so:

      function dez2hex(d) {
        return d.toString(16);
      }

      Du bist dir bewusst, dass bei Argumenten kleiner als 16 keine führende 0 da ist? Hm, sieht nicht so aus: ;-)

      for(i=0;i<256;++i) {
        for(j=0;j<256;++j) {
          for(k=0;k<256;++k) {
            document.write("<td>#" + dez2hex(i) + dez2hex(j) + dez2hex(k) + "</td>");
          }
        }
      }

      Und wozu die dreifache Schleife?

      for (i = 0; i < 0x1000000; ++i) {
        s = i.toString(16);
        while (s.length < 6)
          s = "0" + s;
        document.write ("<td>#" + s + "</td>");
      }

      Gunnar

      --
      „Solang wir noch tanzen können
      und richtig echte Tränen flennen,
      ist noch alles offen,
      ist noch alles drin.“
      (Gundermann)
      1. 你好 Gunnar,

        ich habe zwar verstanden, was du eigentlich tust, aber warum machst du
        das nicht einfach so:

        function dez2hex(d) {
          return d.toString(16);
        }

        Siehe meine Antwort an Thomas Meinike, mir war nicht bewusst, dass das
        geht.

        Du bist dir bewusst, dass bei Argumenten kleiner als 16 keine
        führende 0 da ist? Hm, sieht nicht so aus: ;-)

        Doch, deshalb habe ich ja extra kein bgcolor oder sowas gesetzt :)

        for(i=0;i<256;++i) {
          for(j=0;j<256;++j) {
            for(k=0;k<256;++k) {
              document.write("<td>#" + dez2hex(i) + dez2hex(j) + dez2hex(k) + "</td>");
            }
          }
        }

        Und wozu die dreifache Schleife?

        Damit es deutlicher und klarer wird.

        再见,
         CK

        --
        No Shoes On Mat!
        http://wwwtech.de/
        1. Und wozu die dreifache Schleife?

          Damit es deutlicher und klarer wird.

          ??

          Wir zählen bis tausend:

          for(i=0; i<10; ++i)
            for(j=0; j<10; ++j)
              for(k=0; k<10; ++k)
                document.write(100*i + 10*j + k, "<br>");

          ;-)
          Gunnar

          --
          „Solang wir noch tanzen können
          und richtig echte Tränen flennen,
          ist noch alles offen,
          ist noch alles drin.“
          (Gundermann)
          1. 你好 Gunnar,

            Und wozu die dreifache Schleife?

            Damit es deutlicher und klarer wird.

            ??

            Wir zählen bis tausend:
            [...]

            Eine Farb-Angabe im RGB-Modell von CSS besteht aus 3 * 8 Bit. Das wollte ich
            klarer machen, deshalb die 3-fache Schleife. Dass man die 3*8 Bit auch
            direkt hintereinander schreiben kann macht den Mechanismus nicht klarer.

            再见,
             CK

            --
            Zu wissen, was wir nicht wissen, ist die Quelle der Weisheit.
            http://wwwtech.de/
  3. Hallo ottogal,

    Nun wollte ich das Skript so modifizieren, dass auch Zwischenfarben der Form #uvwxyz zu sehen sind (also alle).

    wenn es Dir um die Farben geht - wenig sinnvoll. Wenn es Dir um die Programmiertechnik geht, sind Farben ein dankbarer Gegenstand zum Üben.

    Dass das ein Bisschen viel ist, war mir schon klar - es geht natürlich nicht. Was mich aber nun interessiert, ist, woran es scheitert: An der Zahl der for-Ebenen? An der Größe der erzeugten Tabelle? Oder der Länge der erzeugten Tabellenzeilen? Usw.

    was geht denn nicht? bekommst Du eine endlose Uhr oder geht es wirklich nicht?

    Es ist übrigens überhaupt nicht [...] eilig

    das darf es bei diesem Ansinnen auch nicht sein ;-)
    Das schreiben mit JS (document.write) ist sehr langsam - das rechnen geht eigentlich.

    Ich habe Dein Script mal gemessen (nur die Ausgabe) - dauert bei mir eine gute halbe Sekunde für 216 Zellen. Was Du ausgeben willst hat über 16 Mio Zellen. Das würde umgerechnet bei mir ca. 11 Stunden dauern...

    Gruß, Andreas

    --
    SELFFORUM - hier werden Sie geholfen,
    auch in Fragen zu richtiges Deutsch
    1. Hallo Andreas,

      was geht denn nicht? bekommst Du eine endlose Uhr oder geht es wirklich nicht?

      Es wurde keine Uhr angezeigt, schien aber stillzustehen. Abbrechen wirkte nicht, nur das Schließen des Browserfensters bzw. Tabs (Firefox 1.0).

      Ich habe Dein Script mal gemessen (nur die Ausgabe) - dauert bei mir eine gute halbe Sekunde für 216 Zellen. Was Du ausgeben willst hat über 16 Mio Zellen. Das würde umgerechnet bei mir ca. 11 Stunden dauern...

      Nun, dass das ein törichter Gedanke war, _alle_ 16 Mio Farben zeigen zu wollen, ist offensichtlich. Ich habe versucht, nur die Werte 0, 3, 6, 9, c und f zu nehmen, was also 6^6 = 46656 Farben ergibt:
      Das ist auch noch zu viel. Schränkt man eine der Zählvariablen auf nur einen Wert ein (siehe den Code unten, Zeile  for (j=0;j<1;j++) ...), klappt es noch: Es dauert bei mir gut 6 Sekunden, und die 6^5 Farben stehen da. Dann müsste es bei (j=0;j<6;j++) doch eigentlich auch nur etwa 36 Sekunden dauern. Aber es tut sich nichts.

      -----------------------------
      <html>
      <head></head>
      <body style="font-family: monospace; color: #ffffff;">
      <script language="javascript">
      t="";
      s=new Array("0","3","6","9","c","f");
      for(i=0;i<6;i++) {
        t+="<table width=100%>";
        for (j=0;j<1;j++) {
          for (k=0;k<6;k++) {
            for (l=0;l<6;l++) {
              t+="<tr height=60px width=100%>";
              for (m=0;m<6;m++) {
                for (n=0;n<6;n++) {
                  C=s[i]+s[j]+s[k]+s[l]+s[m]+s[n];
                  t+="<td width=60px bgcolor="+C+">"+C+"<br><span style=&qout;color:#000000&quot;>"+C+"</span></td>";
                }
                t+="<td>&nbsp;</td>";
              }
              t+="</tr>";
            }
            t+="<tr><td>&nbsp;</td></tr>";
          }
        }
      };
      t+="</table>";

      with(document)
      {
      write(t);
      void(close());
      }
      </script>
      </body></html>
      -----------------------------

      Übrigens denke ich, dass die verschachtelten For-Schleifen wirklich den Überblick erhöhen; andererseits braucht man sie auch um die Tabellen optisch zu gliedern (vgl. die leeren Zellen).

      Wirklich praktisch ist ja diese Funktion toString(16), die mir auch neu war.

      Dank an alle, die geantwortet haben.
      ottogal

      1. mir scheint, daß die Brauser beim Schreiben immer was zwischenspeichern und wenn das zu viel ist, läuft der Speicher über oder so. Aber zu solchen Details mußt Du mal CK oder so fragen.

        Jedenfalls machen die Brauser bei mir verschieden viel: FF habe ich bis j<3 bekommen, OP bis j<4 (weiter habe ich nicht getestet). IE kackt schon bei j<1 ab. Wenn man allerdings statt t+=... in der Schleife immer direkt schon ein  document.write schreibt schafft er auch ein Stückchen.

        Gruß, Andreas

        --
        SELFFORUM - hier werden Sie geholfen,
        auch in Fragen zu richtiges Deutsch
      2. Hi,

        Nun, dass das ein törichter Gedanke war, _alle_ 16 Mio Farben zeigen zu wollen, ist offensichtlich. Ich habe versucht, nur die Werte 0, 3, 6, 9, c und f zu nehmen, was also 6^6 = 46656 Farben ergibt:

        Nicht nur, daß Du 16 Millionen Tabellenzellen erzeugen wolltest, Du hast die Zellen nicht direkt erzeugt, sondern erstmal in einen String zwischengespeichert.
        Pro Zelle hast Du ca. 120 Zeichen (geschätzt, nicht gezählt) angehängt, also etwa 2 Milliarden Zeichen = 2 Giga Zeichen.

        Da muß dann immer mal wieder, wenn der neue Inhalt nicht mehr in den vorhandenen Platz paßt, der ganze String noch in neuen größeren Platz umkopiert werden, bis irgendwann der Speicher ausgeht ...

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
        1. Hallo,

          Da muß dann immer mal wieder, wenn der neue Inhalt nicht mehr in den vorhandenen Platz paßt, der ganze String noch in neuen größeren Platz umkopiert werden, bis irgendwann der Speicher ausgeht ...

          Das leuchtet ein - danke!

          Weils mir bei dem Ganzen tatsächlich nicht nur um eine Programmierübung ging, sondern um eine Nachschlagetabelle für Farben: Noch der Hinweis, dass man eine vernünftigere Auswahl bekommt, wenn man für jeden Farbkanal nur Zwillingswerte 00 bis ff zulässt, aber alle 16. Das ergibt dann 16^3=2^12=4096 einigermaßen vernünftig abgestufte Farben.
          Der Code sieht dann also so aus (und dann hör ich auf):

          --------------------------------

          <html><head></head><body style="font-family: monospace; color: #ffffff;">
          <script language="javascript">
          t="";
          s=new Array("00","11","22","33","44","55","66","77","88","99","aa","bb","cc","dd","ee","ff");
          for(i=0;i<16;i++) {
            t+="<table width=100%>";
            for(j=0;j<16;j++) {
              t+="<tr height=60px width=100%>";
              for(k=0;k<16;k++) {
                C=s[i]+s[j]+s[k];
                t+="<td width=60px bgcolor="+C+">"+C+"<br><span style=&qout;color:#000000&quot;>"+C+"</span></td>";
              }
              t+="<td>&nbsp;</td>";
              t+="</tr>";
            }
            t+="</table>";
          };
          with(document) {
          write(t);
          void(close());
          }
          </script>
          </body></html>

          --------------------------------

          Ciao
          ottogal