[HN Gopher] Qlock - A JavaScript Quine Clock
       ___________________________________________________________________
        
       Qlock - A JavaScript Quine Clock
        
       Author : ayoreis
       Score  : 141 points
       Date   : 2024-05-29 09:50 UTC (13 hours ago)
        
 (HTM) web link (aem1k.com)
 (TXT) w3m dump (aem1k.com)
        
       | wonger_ wrote:
       | The author has a bunch of other neat projects like:
       | https://aem1k.com/world/
       | 
       | And he explains some of the code golfing in this talk:
       | https://m.youtube.com/watch?v=RTxtiLp1C8Y
        
         | undefined_user6 wrote:
         | The Mandelbrot one is really cool too (click to start)
         | 
         | https://aem1k.com/mandelcode/
        
       | Waterluvian wrote:
       | If I want to roll it by hand and not use a minifier, is there a
       | code golf dictionary of patterns for javascript?
        
         | lifthrasiir wrote:
         | Of course, search for "js code golf tips" to start. Many tips
         | equally apply to C and JS due to the syntatic similarity,
         | though JS-specific idioms like x|0 exist as well.
        
         | juliusgeo wrote:
         | best place is the code.golf wiki:
         | https://code.golf/wiki/langs/javascript. They also have tips
         | for other languages.
        
           | Waterluvian wrote:
           | Aha this is exactly what I had hoped for. Thank you!
        
       | schneems wrote:
       | One of my fave Quine talks
       | https://m.youtube.com/watch?v=IgF75PjxHHA
       | 
       | And he made a Quine for the conf
       | https://m.youtube.com/watch?v=4DfhAK8xVWI
        
       | d3w3y wrote:
       | I have no clue what a Quine clock is, but I think it would be
       | easier to read if the diagonal stroke on the front of the 1s only
       | extended to the second row of characters from the top, instead of
       | the third.
       | 
       | I noticed this because it was just 11:11 in my time zone >:)
        
         | vitiral wrote:
         | a quine is where the full source is reprinted in the display.
         | 
         | So in this case, the code to create this clock in your website
         | is
         | 
         | <script>
         | 
         | (r=n=>setInterval(t=>{for(j=o="\n",y=5;y--;document.body['inne'
         | +'rHTML']="<pre>&lt"+(S="script>\n")+o+"\n\n&lt/"+S)for(x=-001;
         | x++<63;o+=`(r=${r})()`[j++].fontcolor(c?'#FF0':"#444"))c=x/2%4<
         | 3&&[31599,19812,14479,31207,23524,29411,29679,30866,31727,31719
         | ,1040][(D=Date()[16+(x/8|0)])<10?D:10]&1<<(x/2|0)%4+3*y},100))(
         | )
         | 
         | </script>
         | 
         | which is also what is the clockface.
        
           | moritzwarhier wrote:
           | Also, adding the snippet will get rid of other content in the
           | body element that might annoyingly distract from this
           | beautiful clock :)
        
         | lifthrasiir wrote:
         | Change 19812 to 19748 (or 9874) to apply your suggestion, if
         | you wonder. It's a simple bitmap encoding.
        
       | moritzwarhier wrote:
       | This is mind-blowing to me, how the shapes of the digits are
       | encoded in the ten numbers, the sheer brevity of that script.
       | 
       | Wow
        
         | lifthrasiir wrote:
         | Partly because it is not exactly a "proper" quine, which is not
         | allowed to access its own source code in any way. This program
         | uses the fact that JS requires `Function.prototype.toString()`
         | to return something that resembles the original JS source code
         | [1], which can be regarded as reading its own source code (a
         | more precise statement would be that it relies on an
         | implementation-defined behavior though). A proper quine in
         | comparison tends to be longer because it has to repeat itself
         | twice in general.
         | 
         | [1] https://tc39.es/ecma262/#sec-function.prototype.tostring
        
           | moritzwarhier wrote:
           | I get what you are saying about using
           | Function.prototype.toString, I am more fascinated by the
           | coloring according to the datetime string, than by the quine
           | aspect. If it were only about the latter, I agree that it
           | wouldn't be very interesting (or not even a proper quine)
        
       | lukeschaefer wrote:
       | Since I'm bored - here's a quick run down of how this works,
       | split into chunks.
       | 
       | #1 - Function Wrapper:                  (r = n => setInterval(t
       | => {             ...         }, 100))()
       | 
       | Here a number of things are done:
       | 
       | - set `r` to the function that runs the whole quine.
       | 
       | - when r is called (inline immediately at the end) it sets an
       | interval to call the body every 100ms.
       | 
       | - `n` is unused, and is there for spacing instead of using `()`
       | to indicate no params.
       | 
       | #2 - Row Looper:                   for (j = o = "\n", y = 5; y--;
       | document.body['innerHTML'] = "<pre>&lt" + (S = "script>\n") + o +
       | "\n\n&lt/" + S)
       | 
       | - create a loop that will occur 5 times (one for each row of the
       | output).
       | 
       | - initialize some variables `j` and `o` to newlines. `o` will
       | contain our rendered output, `j` will soon become an incrementor.
       | 
       | - after each loop, put the contents of 'o' between two strings of
       | "<script>".
       | 
       | - the `S = "script>\n"` portion helps with spacing and S is no
       | longer needed after this line.
       | 
       | #3 - Column Looper:                   for (x = -001; x++ < 63; o
       | += `(r=${r})()`[j++].fontcolor(c ? '#FF0' : "#444"))
       | 
       | - loop through the 64 columns, incrementing x and j.
       | 
       | - x keeps track of the column, j keeps track of the character
       | within the Function `r`.
       | 
       | - each loop, `o` adds a letter from `r`. (In Javascript,
       | functions can be converted to strings which contain their
       | source).
       | 
       | - Also add the `)()` to the end of `r`, which the implicit
       | Function.toString() will not have.
       | 
       | - Set the fontcolor on that string based on `c` -
       | String.fontcolor() is an old deprecated method which wraps your
       | string in a `<font>` tag.
       | 
       | #4 - Renderer:                   c = x / 2 % 4 < 3 && [31599,
       | 19812, 14479, 31207, 23524, 29411, 29679, 30866, 31727, 31719,
       | 1040][(D = Date()[16 + (x / 8 | 0)]) < 10 ? D : 10] & 1 << (x / 2
       | | 0) % 4 + 3 * y
       | 
       | - The array of numbers is essentially a font, defining the
       | numbers 0..9 and lastly ":"
       | 
       | - We pick which character of this font to render based on a
       | Substring of Date(). Either a number, or ":".
       | 
       | - Date()[16] is where the Time string starts, and chars are
       | rendered 8 blocks wide.
       | 
       | - With the beginning `x / 2 % 4 < 3` we render 2 spaces of dark
       | characters between numbers.
       | 
       | - At the end, render our `font` with the x and y coords
       | 
       | - x is divided by two, so all pixels in this font are two
       | characters wide.
       | 
       | - font glyphs are 3x5, and thus defined as 15 bits.
       | 
       | - for example, the glyph for '0' is:                  111
       | 101        101        101        111           - which results in
       | 0b111101101101111 and therefor 31599        - To render these
       | characters, we bit shift (<<) the number by the row & col*width
       | and see what value is in the `1` place.
       | 
       | #5 - Coming together
       | 
       | Now just travel the last few steps back up the chain again, and
       | you can see how these characters are placed in `o` - and if `c`
       | is true (we hit a character) it is rendered yellow. `o` is put
       | between a "<script>" and that resulting string is put in
       | document.innerHTML every 100 milliseconds.
        
       | debo_ wrote:
       | In my third year of university, we had a professor give us an
       | assignment where writing a quine was the final exercise.
       | 
       | For 3 hours, I was cursing his name. Then I got it and I loved
       | him for it. It was such a great feeling!
       | 
       | A quine was something I never would have come up with on my own,
       | and transitioning from "that must be impossible" to "oh, ok it's
       | just ugly" (I did it in Perl iirc) to seeing some elegant ones
       | from classmates was terrific experience.
        
       | cyco130 wrote:
       | I once used the word "quine" in Scrabble. We had a house rule
       | that allowed all English words on English Wiktionary if you could
       | give a more or less correct definition. I gave the computer
       | science definition but it turns out it had a more interesting
       | meaning that immediately caught on in that particular friend
       | group: "To deny the existence or significance of something
       | obviously real or important".
       | 
       | [1] https://en.wiktionary.org/wiki/quine#Verb
        
       | jdthedisciple wrote:
       | How does one even go about implementing quines like this?
       | 
       | Is there a certain iterative kind of method that people use to
       | achieve these?
        
       ___________________________________________________________________
       (page generated 2024-05-29 23:01 UTC)