Posted by aleda145 4 days ago
I also tried a weird idea involving popcount, but it didn't scale. My approach was to represent each possible path with 0s (don't turn) and 1s (turn), testing the same number of 0s and 1s. However, even with popcount running in O(1) with hardware support, the total number of possible paths made the idea impractical :)
- at zero events: we have one outcome, nothing
- at one event: we have two outcomes, 1X and 1Y
- at two events, each of those two outcomes have two outcomes, but one X and one Y outcome both become XY, so we have 1X^2 2XY 1Y^2.
You can continue combining this way, adding an X and Y to each term (for the two possible outcomes) — and then grouping like terms.
As stated, the choose(2n,n) solution of course works but as soon as you deviate from a square, things can get more complicated. What if it's a rectangle? An arbitrary shape? One with holes? The dynamic programming solution takes all of this in stride (assuming, of course, that the conditions of only going right and down still hold).
Pascal's triangle is, after all, a dynamic programming solution. It just so happens that there's a "closed form" solution to their entries.
I'm all for clever tricks but I also appreciate much more a solution that generalizes well and gives more insight into a class of problems.
Depending on how well you know binomial coefficients, this can also lead you to the dynamic programming solution. After all, for the rectangle case this is nothing but construction of Pascal's triangle by summing two adjacent numbers in a row to get the number below them. If you recognize this, the solution for paths on grids with holes falls out almost immediately.
And with AI the path of least (initial) effort seems to be to just ask the model to solve it. It might get it wrong and then I'll prompt it again and again. But each individual prompt is fairly low effort on my part. Whereas coming up with the right solution myself might've taken less time but the initial effort is a lot more.
Last year I used to romanticize about building at least 1 thing each month completely by hand without any LLM coding help. The last such project I worked on was 6 months ago so sadly it's not going so well.
...
...
One way you might get there is Right, right, right, down, down
Then you can rewrite this as RRRDD
You will always need 3 R's, and you will always need 2 D's. So how many unique strings can be made with this?Well let's actually consider the degenerate cases.
ABCDE
there are 5 places A can go, then 4 left B can go, then 3 left C can go, and so on, until we get 5! = 120 possible permutations of ABCDE. If you replace the B with another A to get AACDE
now there are only 60 permutations, because half of the original 120 only differed by where the A and the B were relative to one another. By that same logic, AACCE
has only 30 combinations, and AACCC
has only 10 (seeing why it's 10 and not 20 is actually the trickiest part imo, it's because there are 3! ways to arrange CDE, but only 1 to arrange CCC).AACCC is isomorphic to RRDDD, which is how we get 10 possible paths to solve the 2*3 grid. We can check this with the binomial theorem: ((2+3) choose 3) = 10.
What's nice about this step by step approach is that it generalizes not just to non-square grids, but to multiple dimensions as well! Imagine trying to get from the top of a 3 by 3 by 3 Rubik's cube to the bottom, how do you do that? Well how many ways are there to rewrite
AAABBBCCC
? The logic above would suggest 9! / (3! 3! 3!) = 1,680 unique paths. And you can just derive it by starting from the degenerate case and figuring out how to slice things up!I’m building a grid based game and engine, and I have a game replay format which is not video.
I hit a massive wall with compression, trying to compress unit pathing and was trying to solve a similar solution.
Given an NxN grid, and the 4 cardinal directions (NSEW) you can move in, plus an extra action that makes you move 2 cells instead of 1, and considering you can move 4 cells per second…
What’s the smallest worst-case raw compression artefact you can output for 1 player for a 1 minute game?
It’s an extremely fun problem to solve. I tried:
- encoding changes into bits eg using 2 bits for direction
- movement pattern batching (ie batching 2 moves into 3 bits)
- crowd patterns and movement prediction
- treating movement as a “projectile” and deriving intermediate states
And all sorts of other wild crap that I will write up about on game launch
My game is strictly deterministic, so I get bot movement for free - but the player has agency so I need to capture their deviations
That’s the tricky part! Right now I do capture input (actually just deviations) and can replay whole games, but I think I’m at the limits in terms of compression - talking bytes here not KB
But of the “smart” approaches (pre compression):
- 5 move motif over 2 bytes - best
- 2 move motif - insanely small
- 2 move motif with non linear tick delta even better
- “naive” 1 byte cardinal directions (worst)
- less-naive - byte relative direction changes (middle of the pack)
—-
But post compression with brotli the naive approach was second best and the less-naive approach was first (2-10% better than naive), I was so bummed that the better ones didn’t compress as well (about 10% worse than second best on average)
Skills do decay, I can't deny that. But even when I was still in school going back and doing an end-of-year problem for a class I took two years ago would have been harder than it was for me at the time... but it would have been easier than the first time if I warmed up properly with a bit of review and practice first, and I mean, not just three minutes glancing over things but taking some serious time for it.
Most of the first 100 problems can be solved without any understanding of the problem, should you so desire.