HNHacker News
TopNewBestAskShowJobs

palsecam

1,001 karma · joined February 7, 2008

https://paul.fragara.com/
submissionscomments
palsecam··on Ask HN: Those making $500/month on side projects in 2024 – Show and tell
If it brought you joy, then you made my day <3 Indeed Solitaire is, like chess or go, a timeless game.

It’s also a good way to spend the time, like when you are commuting. Keep in mind that https://FreeSolitaire.win works offline (after the 1st visit, using a service worker: https://developer.mozilla.org/en-US/docs/Web/API/Service_Wor...) ;-)

palsecam··on Ask HN: Those making $500/month on side projects in 2024 – Show and tell
Thank you!

Regarding reverse billing: I don’t know much. I am not myself billed by Moya, although they do bill some of their partners. Please see https://datafree.tech (that’s quite specific to Moya / South Africa carriers, I guess)

palsecam··on Ask HN: Those making $500/month on side projects in 2024 – Show and tell
“But that's minor!”: minor maybe, but that’s an issue. Yes, both the central and corner symbols (“pips”, as they are called) are almost the same size.

It’s even worse with the court cards (aka “picture cards”: jack, queen, king). Out of laziness and for space-saving, they all share the same design: their suit symbol, in big, in the center (and the two corner pips). Not easy to distinguish between them easily/quickly, especially if your sight isn’t good.

I should do something about all that, one of these days. Thank you for your feedback!

palsecam··on Ask HN: Those making $500/month on side projects in 2024 – Show and tell
Thanks!

Wrt attracting visitors: Word of mouth, mainly. Posted it on Reddit back then, things like that. It grew organically from that. And, although it’s far from being on top results on SERP (search engine result pages), some people do find it that way. But yes, the Moya thing was a big boost!

palsecam··on Ask HN: Those making $500/month on side projects in 2024 – Show and tell
https://FreeSolitaire.win brings around $500/mo in advertising revenue. It’s a Klondike Solitaire PWA (progressive web application).

I started making it in 2016 and I’ve been slowly iterating on it over time. It has stayed minimal & lightweight, on purpose. No framework, no cruft, no obtrusive ads.

Fun fact: because it’s so lightweight, it was included in 2020 in Moya (https://play.google.com/store/apps/details?id=nu.bi.moya), a popular messaging app in South Africa that is “data-free” for users (it does reverse-billing). Now ~40% of players are South Africans!

Discussed on HN from to time, for instance:

— https://news.ycombinator.com/item?id=42026575 (38 days ago, 19 points)

— https://news.ycombinator.com/item?id=41971887 (43 days ago, 25 points) “Quick side-note. Thank you for freesolitaire.win. It's such a beautiful implementation of solitaire. Works so well as a PWA, I can enjoy it even without proper internet connection, it's simple, does the basics, but does it perfectly. There's nothing to add to it, but more importantly... nothing to take out.” (!)

— https://news.ycombinator.com/item?id=34483398 (2023, 4 points)

Feedback always welcome, and happy to answer any question!

palsecam··on How God Plays Chess (2018)
So God plays backwards, so to say. He does what’s called retrograde analysis, “a technique employed to determine which moves were played leading up to a given position” (cf. https://en.wikipedia.org/wiki/Retrograde_analysis)

I had a vague intuition of doing the same (going backwards) to generate the winnable Solitaire card deals, but I didn’t get far with it… Does anyone have experience/ideas on that? FTR: a similar discussion on X, started recently by Jonathan Blow: https://x.com/Jonathan_Blow/status/1865520149891346634

I ended up generating totally random deals, then filtering-out those unsolvable by an algorithm of mine (described at https://FreeSolitaire.win/strategy#remarks). It’s fast & good enough to run on-the-fly, when a player starts a new game. But this isn’t an intellectually satisfying solution.

Note that “The probability of being able to win a game of Klondike with best-possible play is not known, and the inability of theoreticians to precisely calculate these odds has been referred to by mathematician Persi Diaconis as "one of the embarrassments of applied probability"” dixit https://en.wikipedia.org/wiki/Klondike_(solitaire)#Probabili...

We need another genius like Ken Thompson for Solitaire!

palsecam··on SQLite changed temp file prefix after McAfee users called devs to complain (2006)
Similar to how Daniel Stenberg (`curl` author) gets complain e-mails unrelated to `curl`, because his address end up being in the license or credits screen of plenty of software.

> Apparently, people often have problems finding an appropriate address to contact when they have issues with this app.

> This leads a disproportionate amount of them to send emails to me asking for solutions and fixes to their situations.

— https://daniel.haxx.se/blog/2024/12/03/no-need-to-email-me-a...

palsecam··on Jane Street Reaps $14.2B in First Nine Months of Trading
https://archive.is/DIywS It’s a short article.
palsecam··on Flappy Bird in 1000 lines of C
You might also like “Cramming Solitaire onto a Nintendo E-Reader card” https://mattgreer.dev/blog/cramming-solitaire-onto-a-nintend...

Discussed lately on HN: https://news.ycombinator.com/item?id=42010136

palsecam··on <dialog>: The Dialog Element
It doesn’t have to be brand new to be on the front page. Good ol’ or reference content is suitable too.

For instance, see this recent thread https://news.ycombinator.com/item?id=41967897 about the “418 I’m a teapot” HTTP status code, also linking to MDN. It was nothing new neither.

palsecam··on <dialog>: The Dialog Element
Yes, but that can be surprising.

That you cannot adjust the z-index is disturbing, especially given that you have to style <dialog> yourself if you wanna make it look any good (as others have reported here).

Also, for the record, alert() is still higher than <dialog> on the plane (see https://i.imgur.com/tzKOEF2.png).

palsecam··on <dialog>: The Dialog Element
I got an issue recently with how <dialog> interacts with AdSense “vignette” (interstitial) ads.

Vignettes set their `z-index` CSS property to the max (2147483647), but a <dialog> is still higher on the z-plane (with no way to adjust that).

So if you click a link from a <dialog>, and an interstitial gets displayed, it’s under the <dialog>. It looks like nothing happened, that clicking is broken.

Fix in my case was to close() the <dialog> onclick.

palsecam··on Dark Mode in CSS Guide
Two interesting and rarely considered points in that guide:

① “Decrease the brightness and contrast of images a bit so that it looks comfortable to the eyes when it’s against a dark background.”

② “If we simply invert a dark shadow using light colors, then we get this funky thing […] Close elements should still be lighter and distant elements should still be darker – even in a dark UI.”

Oh yes, shadows are tricky. I got ① right for the dark theme of https://FreeSolitaire.win, but I never thought of ②. Good to know!

palsecam··on Making AWS News stupid fast with smart caching
See also: the `stale-while-revalidate` and `immutable` HTTP Cache-Control directives.

Stale-while-revalidate: see https://web.dev/articles/stale-while-revalidate & https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ca...

Immutable: https://datatracker.ietf.org/doc/html/rfc8246 & https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ca...

And if, like in the article, you’re using a CDN, `s-maxage` (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ca...) is quite useful. Set it to a long time, and purge the CDN cache on deploy.

palsecam··on ChibiHash: Small, Fast 64 bit hash function
Right, Meow is not the best when it comes to small inputs.

It shines for large inputs (it’s far up the SMHasher list you linked in this case).

It offers a good compromise; it’s not bad (good, even) for both large and small inputs.

Granted, rapidhash is quite good on both fronts, too.

palsecam··on ChibiHash: Small, Fast 64 bit hash function
See also: “Meow hash” by the legendary Casey Muratori, a fast non-cryptographic hash function: https://github.com/cmuratori/meow_hash

> It’s the fastest hash function we know of, and we have benchmarked all the ones we could find. On modern Intel x64 CPUs, it hashes 16 bytes per cycle single-threaded. This means in cache it can hash at a rate of 64 gigabytes per second on a 4.2gHz machine. Out of cache, it hashes at whatever speed your main memory bus can provide to a single core, since that is usually the limiting factor on modern x64 CPUs.

> It has also now been tuned to be the fastest hash on small inputs, too. Despite the fact that it is a full 128-bit hash, it still outperforms “fast” 64-bit hashes across all input sizes.

— https://archive.is/CQOVm (originally https://mollyrocket.com/meowhash)

Discussion on HN: https://news.ycombinator.com/item?id=29038813 & https://news.ycombinator.com/item?id=18262627

palsecam··on The myth that you can’t build interactive web apps except as single page app
“There are only two hard things in Computer Science: cache invalidation and naming things.” — Phil Karlton (cf. https://www.Karlton.org/2017/12/naming-things-hard/ or https://MartinFowler.com/bliki/TwoHardThings.html)

;-)

palsecam··on The myth that you can’t build interactive web apps except as single page app
To be fair, it’s because Chrome handling of a soft reload is different from Firefox or Safari, and does not lead to revalidating (let alone refetching) assets files. See https://blog.chromium.org/2017/01/reload-reloaded-faster-and...

Quoting https://engineering.fb.com/2017/01/26/web/this-browser-tweak...:

> We began to discuss changing the behavior of the reload button with the Chrome team. […] we proposed a compromise where resources with a long max-age would never get revalidated, but that for resources with a shorter max-age the old behavior would apply. The Chrome team thought about this and decided to apply the change for all cached resources, not just the long-lived ones.

> Firefox was quick in implementing the cache-control: immutable change and rolled it out just around when Chrome was fully launching their final fixes to reload.

> Chrome and Firefox’s measures have effectively eliminated revalidation requests to us from modern version of those browsers.

palsecam··on Cloudflare.com's Robots.txt
Little-known fact: a syndication feed (RSS or Atom) can be used as a sitemap.

Quoting https://www.sitemaps.org/protocol.html#otherformats:

> The Sitemap protocol enables you to provide details about your pages to search engines, […] in addition to the XML protocol, we support RSS feeds and text files, which provide more limited information.

> You can provide an RSS (Real Simple Syndication) 2.0 or Atom 0.3 or 1.0 feed. Generally, you would use this format only if your site already has a syndication feed.

palsecam··on The myth that you can’t build interactive web apps except as single page app
Especially since the `stale-while-revalidate` and `immutable` Cache-Control directives are well supported nowadays.

Stale-while-revalidate: see https://web.dev/articles/stale-while-revalidate & https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ca...

Immutable: https://datatracker.ietf.org/doc/html/rfc8246 & https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ca...

And if using a CDN, `s-maxage` (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ca...) is quite useful. Set it to a long time, and purge the CDN cache on deploy.

palsecam··on Cloudflare.com's Robots.txt
That’s a funny one!

Anyone knows of others like that?

Here is mine: https://FreeSolitaire.win/robots.txt

palsecam··on Section 230 Immunizes OnlyFans for User-Uploaded Video–DOE vs. Fenix
In the context of US law, ICP is an acronym for Internet Content Provider [source: AI; seems OK but can’t guarantee it].
palsecam··on Section 230 Immunizes OnlyFans for User-Uploaded Video–DOE vs. Fenix
Legal reference: https://www.govinfo.gov/app/details/USCODE-2023-title47/USCO... (“47 U.S.C. § 230”).

On Wikipedia: https://en.wikipedia.org/wiki/Communications_Decency_Act#Sec...

palsecam··on Sustainable Web Interest Group Is Formed
Related:

— “The leanternet principles” <https://leanternet.com/>

— “The 250KB Club - The Web Is Doom” <https://250kb.club/>

palsecam··on Looking into the Nintendo Alarmo
Related: [Cramming Solitaire onto a] Nintendo E-Reader card : https://news.ycombinator.com/item?id=42010136 (5 days ago, 127 points)
palsecam··on Show HN: Super Simple CRC32 Implementation
FTR, an implementation in “low-level” JavaScript:

  /** Precomputed CRC-32 lookup table for half-bytes (aka “nibbles”).
   * Trade more compute time for less memory and less code to transmit.
   * @see https://create.stephan-brumme.com/crc32/#half-byte
   */
  const CRC32_NIBBLE_TABLE = new Uint32Array([
             0, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C,
    0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C, 0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C
  ]);

  /** @return {number} CRC-32 (polynomial 0x04C11DB7) of the input data.
   * @param {!BufferSource} data  The input data.
   * @param {number=} previousValue  The previous CRC value, if resuming a computation.
   * @see https://en.wikipedia.org/wiki/Cyclic_redundancy_check
   */
  function crc32(data, previousValue = 0) {
    const bytes = ArrayBuffer.isView(data)
      ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
      : new Uint8Array(data);
    let crc = ~previousValue;

    for (let i = 0; i < bytes.length; i++) {
      crc = (crc >>> 4) ^ CRC32_NIBBLE_TABLE[0x0f & (crc ^ bytes[i])];
      crc = (crc >>> 4) ^ CRC32_NIBBLE_TABLE[0x0f & (crc ^ (bytes[i] >> 4))];
    }
    return ~crc;
  }
From https://GitHub.com/PaulCapron/pwa2uwp/blob/master/src/zip.js
palsecam··on Cramming Solitaire onto a Nintendo E-Reader card
> What kind of shuffling does your program use?

The shuffling is random, but only winnable decks are generated (by default). The computer algorithm/solver is described here: https://FreeSolitaire.win/strategy

So it’s pure chance you got an easy shuffle.

> In any regard, I like your implementation.

Thanks, I’m glad you like it! If you have suggestions for improvement, I’m all ears (here or by e-mail) ;-)

palsecam··on Cramming Solitaire onto a Nintendo E-Reader card
> A single E-Reader dotstrip can store 2,192 bytes of data, which is just over 2kb. But there is some overhead with the headers […] data on the dotstrip is compressed though

> In the end I didn't need to do too much space optimization to keep Solitaire down to two dotstrips

So, a full implementation of Solitaire in ~4KiB. Count me impressed!

I like to show off that my own (as a web app: https://FreeSolitaire.win) is "only" 21KiB, but that’s small fry in comparaison!

palsecam··on Excel has a row limit of 1,048,576 rows and a column limit of 16,384 column
Ie.: max 2^20 rows, 2^14 columns.
palsecam··on 418 I’m a teapot
Oh that’s an interesting idea! Thanks Dave, had not think about that!

Regarding playing on phone: one improvement I have in mind, is to have the stock (aka reserve) and waste piles be on the right side. That would make them easier to reach for right-handed players, I guess. What do you think? (The foundations piles would inversely go to the left. They are rarely manipulated, given that one can double-tap a card to automatically send it to its foundation pile.)

Thank you again for the feedback, that’s always very appreciated!

← PreviousPage 2 of 6Next →