Live data from Hacker News

Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

alexanderpruss.blogspot.com

141–150 of 170 posts

Re: Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

#141
post #60

My first thought would be “DAWG”. That’s a smart way to represent a trie, with identical ‘tail’ ends of the trie merged into one. https://www.cs.cmu.edu/afs/cs/academic/class/15451-s06/www/l... compresses a 780k word list into 175k. That’s about 22% of the size. This accomplishes 27%. This list is a lot shorter, so there will be fewer opportunities for savings. On the other hand, all words are five letters, so the ‘i…

I tried this method today, but a huge shortcoming here is that a DAWG needs these large pointers between nodes. I based my approach on http://www.wutka.com/dawg.html and http://stevehanov.ca/blog/?id=115 . I generated a DAWG with 12,822 nodes, which means you need 14 bits for each pointer. A trie representation can be packed much smaller because you don't need to randomly jump around the graph, you can just read it o…

I ended up doing some math on a theoretical DAWG, based on: https://www.cs.put.poznan.pl/dweiss/site/publications/downlo...

With 12,822 nodes, you need 57,387 bits for the labels and the Huffman table (I'm sure you could make the Huffman table more efficient, but it's only 50 bytes, so that's not helping much).

Then, to mimic their edge reordering technique but without having to actually implement all the logic, I ordered the edges by frequency and used variable length integer encoding of size 3 (this performed the best on the data set) which required 95,988 bits.

Variable length integer encoding breaks the number into 3 bit chunks, each prefixed by 1 bit to indicate if there is another 4 bit chunk to read for that number. Since the distribution of offsets is heavily skewed, optimizing the most frequent offsets into a small package is better even if rarer ones suffer from multiple prefix bits.

This is 19,171 bytes total, or substantially worse than both the original article and Huffman tries do. This isn't even counting the flag bits needed for actually traversing the graph. So even cheating, it's not clear I can get a DAWG to be within striking distance of either other approach.

I hypothesize that the reason tries and other methods perform so well here is the relatively shallow depth. All words are only length 5, so the trie doesn't ever get really deep. This also means that suffixes generally don't actually take up that much space given common ones will also pack small with Huffman coding. The size of offsets appears to be just too great relative to how much you can save by removing shared suffixes from 5 letter words.

Would love to know if there is some trick to DAWG that I'm missing that would let me get it even smaller.

Re: Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

#142

Earlier quoted context omitted.

I tried this method today, but a huge shortcoming here is that a DAWG needs these large pointers between nodes. I based my approach on http://www.wutka.com/dawg.html and http://stevehanov.ca/blog/?id=115 . I generated a DAWG with 12,822 nodes, which means you need 14 bits for each pointer. A trie representation can be packed much smaller because you don't need to randomly jump around the graph, you can just read it o…

I feared that (“This list is a lot shorter, so there will be fewer opportunities for savings”) However, I think you can layout the tree so that no pointers point backwards. If so, can you make those offsets smaller by making them relative to the current point in the tree? Also, since the list only has five-letter words, for the last letter, you don’t even need the letters themselves, just 26 bits for what letters can…

Ah, I replied to myself with more information while you were also replying.

I also surmise that the short length of the words makes a DAWG just very heavy.

It's not clear to me that relative offsets would be notably smaller to the extent that would be needed. Even a hypothetical and cheated DAWG I came up with is ~33% bigger than alternatives. I've generally explored enough (see the paper in my other comment) that I don't feel that further investigations into a DAWG are likely to outperform other methods.

I can't see anything immediately that jumps out that the Crab game is doing that's special to save space, I think it just achieves better compression because you can compress larger files easier, and the words are longer with more overlapping sections.

I agree that you need to compare including the decompressor size, so I'm not sure which approach is better the Huffman trie or the one in the original article. I'm not familiar enough with GB programming to be able to suggest how much program memory would be needed to decode the Huffman Trie, it looks like it would be somewhat similar in complexity.

Re: Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

#143

Earlier quoted context omitted.

Man, at 11 my programs mainly consisted of INPUT, PRINT and GOTO, which I wrote on my uncle's brand new IBM XT.

My programs at 11 were just Visual Basic 6 for an IE scrapper/clicker and making HTML websites in Dreamweaver 6. Not sure why the 6 was so popular for many programs then. It was for sure Photoshop 7 era.

My guess is that it was the last version of Visual Basic before they moved over to VB.net -- it was easy and simple, and didn't aim for industrial strength.

Re: Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

#144
post #67

Earlier quoted context omitted.

I think you are thinking of a trie

No, not a trie. After throwing more words at the Google Wall, it finally allowed that what I'm thinking of is the Shortest Superstring Problem.

Nerd sniping indeed.

This morning without putting a whole lot of effort into this, I was able to winnow it down to 27.32 bits per word without any other trickery like 5bit packing. You need at most 1 bit per word to identify the real words, so that's 27.32+1 bits without the bitpacking. Doing 6 bits per letter drops that by 25%.

Now having put too much effort in, I'm around 21.6 + 1 bits per word, (17 bit packed) just by using SSP.

Re: Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

#145
Like y'all, I wanted to see how I could do. Of course, I didn't get all the way to tested code on a gameboy. But it does compress & decompress in Python.

I took the central idea of encoding deltas (or actually delta less 1, since the delta is always at least one; I'll just say delta below), but did it on the full five letter word. The largest delta was still less than 2*18 but bigger than 2*17. (I'm not sure why the blog mentions 20 bits as the biggest delta; I used the dataset from https://github.com/alex1770/wordle/commit/62520406365ca58a1a...)

I decided I wanted a variable length code in bits. Manually, I found the best break-points that I could:

    breaks = [16, 128, 512, 2**12, 2**18] 
    bitprefixes = ['0', '10', '110', '1110', '1111']
So deltas 0..15 are encoded as '0' plus a 4-bit number, deltas 16..271(=16+256-1) as '10' plus a 7-bit number, etc.

Compressed like that, my dictionary runs to 14840 bytes.

    1111000000000001010110 // aahed   4839 =    4839-      0
    1110100001101100       // aalii   2813 =    7652-   4839
    1110110100010010       // aargh   4003 =   11655-   7652
    110011000010           // aarti    339 =   11994-  11655
    1111000000001101110001 // abaca   5634 =   17628-  11994
    00111                  // abaci      8 =   17636-  17628
    00001                  // aback      2 =   17638-  17636
    00111                  // abacs      8 =   17646-  17638
    100111110              // abaft     79 =   17725-  17646
    ...
However, a non byte aligned code isn't ideal, especially on the gameboy's CPU which doesn't have variable bit shifts as far as I recall. Still, over 3000 bytes beckoning to be re-used for some other purpose. Did they put in a soundtrack yet?

Compressor & decompressor: https://gist.github.com/jepler/d502965b57fd52df0838a6def2d32...

Re: Game Boy Wordle clone: How to compress 12972 five-letter words to 17871 bytes

#146
post #122

I got nerd sniped and compressed it to under 28K, which was good enough for the goal of fitting it in a 32K NROM cartridge for the NES. On the NES, you don’t need to do better than that, because you get a separate 8K for graphics, and 4K is plenty of space to fit the code for your Wordle clone. https://www.moria.us/blog/2022/01/dictionary-compression The annoying part is that the NES only gives you four background pa…

Nice! Do you have a repo somewhere?

I’ll put one sometime relatively soon, got some other stuff on my plate. The Wordle clone is currently “mostly functional”—no pretty graphics or anything, but gameplay checks. I have a limited stamina for NES programming, but I had fun with the proof of concept.
Post reply on HN