Another Rust Solvers puzzle: Cosmic Express. Basically, it’s a routefinding puzzle. You have a train that needs a track from entrance to exit, picking up and dropping off cargo on the way.
It’s actual a relatively simple puzzle, so far as things go, but one thing that’s interesting from a solving perspective is that branching paths really don’t work great with my solver code. Paths just have a crazy branching factor when compared to (for example) playing one of a handful of cards.
But it’s still an interesting puzzle!
I recently stumbled across CodeCrafters again1. In a nutshell, they give a number of ‘Build Your Own…’ courses, each of which will automatically create a repo for you, guide you through solving the program step by step, and provide some feedback on the way.
On one hand, it’s a freemium (one problem a month is free) / paid service. I wish they had tiers. I really think their monthly fee is a bit steep for what they offer (we’ll come back to that). But on the other hand, it’s a neat tool and I’ve been wanting some more larger programming projects to learn more Rust on, so away we go!
First up, grep!
One of the problems (of a sorts) I’ve been having with my series on Rust Solvers is that, for each input puzzle, I need a way to save one or more ‘known good’ solutions so that when I change and add new functionality, I can verify that I’ve either not changed the solution or found another valid one.
Integration tests as it were.
So far, I’d been building this into each solution. While this worked perfectly fine, it’s a bit annoying to copy and paste to each binary, and then have to edit each test case with the answers.
Enter: testit:
# First run, without --db/--save for previous runs
$ testit \
--command "./target/release/golf-peaks" \
--files "data/golf-peaks/**/*.txt" \
--timeout 60
data/golf-peaks/1-1.txt: New success:
1-↗
===
data/golf-peaks/1-10.txt: New success:
1-↘ 3-↙ 2-↘
===
...
data/golf-peaks/9-8.txt: New success:
1/3-↘ 1/2-↖ 1/↗ 2/1-↖ 1/1-↗
===
data/golf-peaks/9-9.txt: New success:
1-↗ 1/↘ 1-↘ 4-↗ 3-↘ 1/1-↗
===
data/golf-peaks/Credits.txt: New success:
4-↖ 5-↗ 3-↗ 6-↘
===
Summary:
Successes: 121 (121 new)
Failures: 0
Timeouts: 0
# Later runs
$ testit \
--command "./target/release/golf-peaks" \
--files "data/golf-peaks/**/*.txt" \
--timeout 60 \
--db testit/golf-peaks.json \
--save
Summary:
Successes: 121 (0 new)
Failures: 0
Timeouts: 0
Pretty cool, I do think. 😄
Another day (week? month?), another puzzle game.
This time around, we’re going to solve Golf Peaks. I picked this up a while ago on iOS, but only recently on Steam. It’s a cute little puzzle game themed around minigolf.
Basically, you’re on a grid and you have to get the ball (in the bottom in that screenshot above) to the flag (currently at the top). You have a set list of moves you can take, styled as cards–all of which either move a certain number of tiles in a specific direction or possibly jump into the air (and fly over obstacles).
It gets more complicated from there, but hopefully you have the basic idea. 😄
Another solver that I’ve been working on, after A Good Snowman Is Hard To … Solve?. This time, we have Sokobond! It’s a Sokobon… but with chemical bonds! Yeah, that’s a really good title.
The basic idea is you have a field of elements with (chemical accurate) free electrons):
Here we have 4 hydrogens (1 bond each) and a carbon (4 bonds). It should seem pretty obvious that the carbon should end up with a hydrogen on each end. The one last bit of interest: the element with the dashed border is the one we actually control, that will never change.
This eventually gets more complicated, adding:
It’s a pretty neat puzzle game with 144 levels of increasing difficulty. Perfect to solve.
I enjoy puzzle games. I especially enjoy letting computers solve them for me 😄. Once upon a time, I set up a framework for solving random things. Let’s solve some more.
Today: A Good Snowman Is Hard To Build
It’s a Sokoban about making snowmen! You can push snowballs of three sizes around, collecting snow if you roll over it. You can push smaller snowballs onto bigger ones, stacking them. Or back off, in order to get around one another.
And that’s really it.
There are some interesting twists (multiple snowmen, the ability to leave and re-enter levels, and even a whole second ‘hard mode’), but at a basic level, it’s just pushing.
A quick follow up to Advent of Code 2023: testing and timing.
It’s been bothering me a bit that I haven’t had a generic way to run tests and timing on every problem as I’m going.
So let’s fix it!
Full solution for today (spoilers!)
Given an undirected graph, find 3 edges that split the graph into two connected components. Return the product of the component’s sizes.
Full solution for today (spoilers!)
Given a set of 3D vectors (origin + velocity), count how many times the vectors would intersect. Ignore the Z-coordinate for this part; the collisions do not have to be at the same time.