www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: Mimic Javascript for the 'The Nine Billion Names of God'

  1. #1
    Join Date
    Apr 2009
    Posts
    7

    Mimic Javascript for the 'The Nine Billion Names of God'

    I did read the other day an amazing tale from Arthur C.Clarke, The Nine Billion Names of God about Tibetan monks looking to write down all the possible 9 letters combination of the Tibetan alphabet, so the real name of God is finally spelled, and the whole purpose of the human race is fulfilled.

    For that purpose, and after centuries doing it manually, they finally rent a computer.

    I liked the tale and wanted to mimic it using my own laptop. I already wrote a Basic program to swap nine ASCII characters. But my ultimate goal is to post a javascript in my blog so readers can see it working while they read along.

    Dmboyd helped me to set this code ahead:

    Code:
    var n = 41;
    var letra = new Array();
    for (var i = 0; i < n; ++i)
        letra.push(String.fromCharCode(i + 0x0f40));
    for (var p1 = 0; p1 < n; ++p1)
        for (var p2 = 0; p2 < n; ++p2)
            for (var p3 = 0; p3 < n; ++p3)
                for (var p4 = 0; p4 < n; ++p4)
                    for (var p5 = 0; p5 < n; ++p5)
                        for (var p6 = 0; p6 < n; ++p6)
                            for (var p7 = 0; p7 < n; ++p7)
                                for (var p8 = 0; p8 < n; ++p8)
                                    for (var p9 = 0; p9 < n; ++p9)
                                        document.writeln(letra[p1]
                                                         + letra[p2]
                                                         + letra[p3]
                                                         + letra[p4]
                                                         + letra[p5]
                                                         + letra[p6]
                                                         + letra[p7]
                                                         + letra[p8]
                                                         + letra[p9]
                                                         + "<br>");
    Unfortunately, there still exist two small problems:

    MISSING CODE POINT
    Tibetan letters start at U+0F40 and end at U+0F6C, but the last 3 don't show up in Arial, so I limited the alphabet to the first 41 letters. Besides, code point U+0F48 is missing (go figure why) so the alphabet feeding iteration should skip this number.

    How could we do that?

    MEMORY OVERRUN
    The printout ends after 10256 lines due to memory shortage. The current

    Code:
    document.writeln(letra[p1]
    must be replaced by some in-place or batch printing or cleaning the memory so no limits affect the iterations within the design boundaries.

    Do you have any idea how to do that?

    Many thanks for any hint!

  2. #2
    Join Date
    Sep 2008
    Location
    On the Interweb
    Posts
    125
    Stop now! Learn a lesson from the ill-fated protagonists of the story! If you succeed, the universe will cease to exist! Ahhhhh!

    He he he

  3. #3
    Join Date
    Feb 2006
    Posts
    2,927
    Despite the title, you are not testing 9 billion unique names, but 9^41,
    or 1330279464729113300000000000000000000000.
    (1.3302794647291133e+39).

    unicode tibetan allocates 2 bytes per character, or 18 per name, plus 2 more for a comma and a space.
    Multiply the names times 20 bytes.

    How big is your hard drive?

  4. #4
    Join Date
    Mar 2009
    Posts
    96
    Quote Originally Posted by mrhoo View Post
    Despite the title, you are not testing 9 billion unique names, but 9^41,
    or 1330279464729113300000000000000000000000.
    (1.3302794647291133e+39).

    unicode tibetan allocates 2 bytes per character, or 18 per name, plus 2 more for a comma and a space.
    Multiply the names times 20 bytes.

    How big is your hard drive?
    That would result in
    • 24197642500969110366800103144 TiB of space used (according to the OS), or
    • 26605589294582266196894977837 TB of space used (according to hard drive manufacturers).
    This means that you would need a very large hard drive!

    Disclaimer: The large numbers contained within this post were generated using the Python programming language, and in no way is the author of this post responsible for what may happen to your computer should you attempt to complete the task described by the OP.

  5. #5
    Join Date
    Mar 2005
    Location
    Sydney, Australia
    Posts
    7,974
    If you place an order for all the hard drives that can be built over the next few thousand years then at the end of that time you should have enough hard drive space to at least be able to add more drive space along the way before the script reaches the point of needing it.

  6. #6
    Join Date
    Apr 2009
    Posts
    7
    Hehe...

    My 1st question was how to skip a single letter 0x0f48 in the feeding loop

    Code:
    var n = 41;
    var letra = new Array();
    for (var i = 0; i < n; ++i)
        letra.push(String.fromCharCode(i + 0x0f40));
    Any idea?

    The 2nd question was how to write all the results in a single line, nothing saved, nothing stored. Just the fun of seeing the swapping letters. So writeln is not the right one.

    Code:
    document.writeln(letra[p1]
    wite command doesn't seem to make any difference, listing combinations in a single ever growing webpage.

    Any idea?

  7. #7
    Join Date
    Mar 2009
    Posts
    96
    The answer to the first question is easy. Just use enclose the letra.push line inside an if block and modify the for loop to include n:
    Code:
    for (var i = 0; i <= n; ++i)
        if (i != 8)
            letra.push(String.fromCharCode(i + 0x0f40));
    The answer to the second question is a bit more difficult. The obvious solution is to use the DOM to replace the text of an HTML element with the necessary code. However, with the current code structure, I can't seem to figure out how to delay things to allow the browser to NOT freeze, much less display the results. There are a few improvements to JavaScript that Mozilla has done in version 1.7, but they only work in Firefox 2.x and beyond (not sure about Seamonkey, Camino, etc. versions). The generator-iterator combination would solve the problem easily. If you can live with that, then that's great. Otherwise, your code will need some re-factoring.

    Edit: Here is some code that uses the generator-iterator bits:
    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    	  "http://www.w3.org/TR/html4/strict.dtd">
    <html>
      <head>
        <title>The Nine Billion Names of God</title>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
      </head>
      <body onload="startNameChange()">
        <div id="PageContainer">
          <p id="CurrentName">
    	Your browser doesn't support JavaScript.  Please turn it on or
    	try a different browser.
          </p>
        </div>
        <script type="application/javascript;version=1.7"
                src="names.js"></script>
      </body>
    </html>
    Code:
    // names.js
    function startNameChange() {
        var textNode = document.getElementById('CurrentName').firstChild;
        var d = doNameChange();
        textNode.nodeValue = '';
        setInterval(function() { textNode.nodeValue = d.next(); }, 500);
    }
    
    function doNameChange() {
        var n = 41;
        var letra = new Array();
        for (var i = 0; i <= n; ++i)
    	if (i != 8)
    	    letra.push(String.fromCharCode(i + 0x0f40));
        for (var p1 = 0; p1 < n; ++p1) {
    	for (var p2 = 0; p2 < n; ++p2) {
    	    for (var p3 = 0; p3 < n; ++p3) {
    		for (var p4 = 0; p4 < n; ++p4) {
    		    for (var p5 = 0; p5 < n; ++p5) {
    			for (var p6 = 0; p6 < n; ++p6) {
    			    for (var p7 = 0; p7 < n; ++p7) {
    				for (var p8 = 0; p8 < n; ++p8) {
    				    for (var p9 = 0; p9 < n; ++p9) {
    					yield (letra[p1]
    					       + letra[p2]
    					       + letra[p3]
    					       + letra[p4]
    					       + letra[p5]
    					       + letra[p6]
    					       + letra[p7]
    					       + letra[p8]
    					       + letra[p9]);
    				    }
    				}
    			    }
    			}
    		    }
    		}
    	    }
    	}
        }
    }
    Last edited by dmboyd; 04-07-2009 at 04:07 PM. Reason: Added more exposition and example code...

  8. #8
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    i played a while with the function i posted here and i made this:
    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>limit chars</title>
        <script type="text/javascript">
        function nineBillionNamesOfGod()
        {
          if (num<variations && !paused)
          {
            for (var i=k; i>0; i-=1)
            {
              word=String.fromCharCode(Math.floor(num/Math.pow(n,k-i))&#37;n+0x41)+word;
            }        
            target.innerHTML=word;
            word="";
            num+=1;
            timeout=setTimeout(function(){nineBillionNamesOfGod();}, 10);
          }
        }
        function init()
        {
          target=document.getElementById("target_div");
          document.getElementById("btn_start").onclick=function()
          {
            clearTimeout(timeout);
            document.getElementById("btn_pause").value="pause";
            num=0;
            paused=false;
            nineBillionNamesOfGod();
          }
          document.getElementById("btn_pause").onclick=function()
          {
            if (num!==0)
            {
              if (!paused)
              {
                clearTimeout(timeout);
                paused=true;
                this.value="continue";
                target.innerHTML+=" is the "+num+". name of God"
              } else
                {
                  paused=false;
                  this.value="pause";
                  nineBillionNamesOfGod();
                }
            }
          }
        }
        var n=41, k=9, num=0, paused, target, timeout, variations=Math.pow(n,k), word="";
        window.onload=init;
        </script>
      </head>
      <body>
       <div id="target_div"></div>
       <p>
          <input id="btn_start" type="button" value="start">
          <input id="btn_pause" type="button" value="pause">
        </p>
      </body>
    </html>
    it calculates the word using its sequential number. however already Math.pow(10,9) gives me wrong value, so i can never get to Math.pow(41,9), which should be around 10^39. the Number.MAX_VALUE is approx. 10^308, so it should work. when i do:
    Code:
    variations=1000000000000000000000000000000000000000; //39 zeros
    alert(variations);
    it displays 1+e39, right as it should. does anyone know what's wrong with the Math.pow() function?

    also, how can i display the damn tibethian letters? if i do fromCharCode(0x0f40) or bigger, i only see empty squares.

  9. #9
    Join Date
    Mar 2009
    Posts
    96
    Do you have a Unicode font installed? Is your browser's encoding set to UTF-8 when you view that page?

  10. #10
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    haha. i'm stupid. default font was set to regular Arial, so it doesn't have these. when i added
    Code:
    <style type="text/css">
      body {font-family: Arial Unicode MS;}
    </style>
    suddenly the funny-looking characters appeared but any guesses about the large numbers?

  11. #11
    Join Date
    Mar 2009
    Posts
    96
    327381934393961 = Math.pow(41, 9)

    I don't know what's wrong with yours, but using Firefox 3.1b3 in Windows XP, it displays things perfectly fine.

    Edit: Windows XP's Calculator gives the same result.

    Edit 2: Math.pow(10, 14.515054710477619) is approximately equal to Math.pow(41,9):
    Code:
    327381934393960.75 = Math.pow(10, 14.515054710477619)
    327381934393961.00 = Math.pow(41, 9)
    Last edited by dmboyd; 04-10-2009 at 11:02 AM.

  12. #12
    Join Date
    Apr 2009
    Posts
    7
    I am pretty OK with splitting the code and host the js file separately. I already uploaded it to http://www.filefactory.com/file/aga7dab/n/names_js, indeed.

    Normaly, I don't like that because then I need to keep a separate control on both the main page and the js hosting, to prevent dead links. Anyway, I guess I could live with it.

    A problem I got, though, is that I am planning to host the main file in my blog at blogger, so I can't place the <body onload="startNameChange()"> part of your code for an individual post.

    I would rather place a form somewhere with a button inside to launch names.js instead. Any sample of such a form?

    Ah... On using a variations function instead of the nested loops, it's a nice and elegant option, but I sincerely think it will obscure what we are doing, and probably slow down the program.

  13. #13
    Join Date
    Aug 2007
    Posts
    3,767
    Quote Originally Posted by mrhoo View Post
    Despite the title, you are not testing 9 billion unique names, but 9^41,
    or 1330279464729113300000000000000000000000.
    (1.3302794647291133e+39).
    You mixed up the order there, it's the amount of possible letters to the power of the length of the word.
    There are 1.27e14 nine letter words with each letter different, and 3.27e14 if the same letter is allowed more than once.

  14. #14
    Join Date
    Mar 2009
    Location
    Wherever i lay my hat
    Posts
    180
    Quote Originally Posted by dmboyd View Post
    I don't know what's wrong with yours, but using Firefox 3.1b3 in Windows XP, it displays things perfectly fine.
    my bad again. there is nothing wrong with the code. i just used win calc to compare the results and of course i calculated 9^41 instead of 41^9...
    Quote Originally Posted by diegorodriguez View Post
    I can't place the <body onload="startNameChange()"> part of your code for an individual post. I would rather place a form somewhere with a button inside to launch names.js instead.
    you can do what i did in my version. simply at the end of the names.js file assign the startNameChange as a callback function for window.onload:
    Code:
    window.onload=startNameChange; //no parentheses
    shame that clarke didn't describe all the criteria for the god names in his story. we will never know how did he come up with the number 9 billion. according to this page (search for "billion"), tibetan alphabet has 56 different characters, that would make 5.4e+15 different words. so either the rules were much more strict than we think (the only one mentioned in the story is that there can't be more than 3 same consecutive characters) or they didn't use all the letters...

  15. #15
    Join Date
    Apr 2009
    Posts
    7
    Sorry, I don't undetstand the mechanics of it. First, I add
    Code:
    window.onload=startNameChange; //no parentheses
    at the end of the js file, and then I place a button inside a form to launch the js file, right?

    Any simple sample on a form with a button inside to launch the js?

    Thanks!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles