[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><"+(S="script>\n")+o+"\n\n</"+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><" + (S = "script>\n") + o +
| "\n\n</" + 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)