- Common Loki Misconfigurations
- Iterating Through a List in Ink
- Debugging Misconfigured Container Networks
- Minimum Viable EC2 in Terraform
- Storylets in Ink
- Interactive Fiction Tooling Overview
- In-Place Resizing for Digitalocean Droplets
- Unity Demonstrates the Importance of FOSS
- Target Labels in Prometheus
- My View of AI is the Same
- Verify DNS Ownership with TXT Records
- Sane Droplet Defaults
- Editing Made Easy with Vim
- Gatsby Gotchas
- Concatinating Default AWS Tags in Terraform
- Easily Updating the Default Github Branch
- Lifetimes in Rust
- Checking for Bad Links
- Maybe TypeScript and React is Bad
- Static Asset Management in React
- Bundler Down Time
- Using React Context for Localization
- JS Implementation of a Sticky Footer
- Custom Aliases
- Trying Out the 7drl Challenge
- Trash Opinions
- Building Your First Program in Rust
- Fixing mongod reports errors related to opening a socket
- Improving Open Source Maintenance
- Technical Interviewing Tips
- Housekeeping Note
- Dynamic Programming Basics
- The Oddity of Naming Conventions in Programming Languages
- An Experiment Using Machine Learning, Part 3
- Debugging with grep
- An Experiment Using Machine Learning, Part 2
- An Experiment Using Machine Learning, Part 1
- The Value of while
- National Day of Civic Hacking
- OpenAI and the Future of Humanity
- Creating a Whiteboard App in Django
- Creating Meaningful, Organized Information
- Towards A Critique of Social Media Feeds
- Setting up Routes in Django
- Developing a Messaging Component for Code for SF
- Dream Stream 2.0
- Keyed Collections in Javascript: Maps and Sets
- Blog Soft Relaunch
- Scraping with Puppeteer
- Looking Ahead to Dream Stream 2.0
- Solving West of Loathing's Soupstock Lode Puzzle
- Installing Ubuntu
- Interview with David Jickling Evaluation
- Compare Text Evaluation
- Dream Stream Evaluation
Solving West of Loathing's Soupstock Lode Puzzle
West of Loathing is a computer role playing game by Asymmetric Publications. It has a mystical American Wild West setting, but more importantly it also has very clever, funny writing. That cleverness of the writing also extends into some of the game’s puzzles. For example, there’s a math puzzle in West of Loathing that looks like this:
The three bolts you can manipulate add different quantities of weight. The first option (the #3 bolt) adds 411 lbs., the second option (the #5 bolt) adds 295 lbs., and the final option (the #7 bolt) adds 161 lbs. If you add up enough weight that it exceeds 3200 lbs. then it resets to zero, and crucially you cannot undo weights you have added nor can you reset to zero on your own. This is a disincentive to randomly guessing to try and find a solution because working your way through guesses is very tedious. Instead I tabbed out of the game and wrote a quick script to reach the solution.
The first step I take is to figure out what I’m trying to solve. Luckily, that part is straightforward.
(x * 411) + (y * 295) + (z * 161) = 3200
In solving for x, y, and z it is also helpful to have an idea of the possible range of variables. 3200 divided by 161 is approximately 19.8. Therefore we know that the possible answers for x, y, and z are between 0 and 19, with the lower end of the spectrum being more likely. Finally, we can also observe that x and y have to add up to a number divisible by 5. We know that because it is impossible to arrive at the value of 3200 if the #3 and #7 bolts are combined in such a way that the value of the weight ends with a digit like 3. There are other observations that could be made about the problem, but I felt like that was enough information to tackle the problem.
When writing a function that performs a lot of different things, I first like to articulate in plain English what I’m trying to do so I don’t get lost in the weeds. This is what I came up with:
- Take a sum of x and z that is divisible by 5.
- Evaluate all possible permutations of that sum to x and z (5x, 0z), (4x, 1z), (3x, 2z), etc.
- For each instance, perform the (x411) + (y295) + (z*161) formula in a loop where y is incrementing.
- If it is equal to 3200 print the values of x y and z.
When described that way, writing a function doesn’t seem too complicated.
- You have a parameter that is the sum of x and y.
- There is a loop that assigns different values to x and z.
- Nested in that loop is an additional loop that increments y.
- There is an if condition that executes when the value of the formula is equal to 3200.
With all of that in mind this is what I came up with:
function solveProblem(xzSum) {
for (let i=xzSum; i >= 0; i--) {
let x = i;
let z = xzSum - i;
for (let j=0; j < 11; j++) {
let y = j;
let formula = (x*411) + (y * 295) + (z * 161);
if (formula === 3200) {
console.log("The answer is: " + x, y, z);
}
}
}
}
solveProblem(5);
solveProblem(10);
solveProblem(15);
Sure enough, if you run this you get this output:
The answer is: 4 2 6
And if you double check that on a calculator, the math checks out. This is a brute force solution to solving the problem, and there are some inefficiencies involved. For example, in the 2nd loop I let it run 11 times with the reasoning that 295*10.8 is approximately equal to 3200. But that means there will be plenty of instances of checking solutions that clearly exceed scope. If this were a more complex problem that involved evaluating a much larger range for its possibility space that would be a problem, and I would think more carefully about what I’m trying to evaluate. But for finding the solution to a puzzle with a relatively small range of numbers to evaluate for a game that I was looking forward to getting back to, this was an approach that I was happy to live with!