NOTE: It appears that Replit has some join limits on Apps and that some folks haven’t been able to access the Replit workspace. I’ve reached out to support about this limit and will update when I find out more. In the meantime, I think you should be able essentially fork the VoronoiGame directory (“Remix this app”) and run it locally. I think all of the instructions should be the same if you go down this route. You just will have to submit your solution via the form instead of leaving it in the submissions
directory.
Inspired by the Fiddler on the Proof (formerly The Riddler), X’s Puzzle Corner aims to produce a weekly puzzle for readers that enjoy math, probability, and algorithms. Please submit your solution! Solutions will be accepted until 11 pm the following Sunday after the puzzle is posted (in this case 6/29/25). While it isn’t required, I encourage you to opt to have your solution shared so that we all get the chance to see how others thought about and attempted the problem! The solution and submitted responses will be posted around Wednesday at 10 am.
I make no guarantees my solutions are correct! You are all smart people so please comment if you think I made a mistake!
Last week we introduced a simple game:
The game starts with an empty unit circle. Players place a point in the circle one at a time (player 1 first, player 2 second, etc.) until each player has gone. After everyone has selected, a random point is sampled uniformly from the unit circle. The player whose point is closest to the randomly sampled point is the winner.
This week, we’re going to see who can play this game the best. That’s right, it’s X’s Puzzle Corner’s first ever competition!
Below are some detailed instructions on how you can submit your strategies for the game. Long story short, you will need to submit a Python class that implements a specific function makePlay(turn, previousPlays)
that returns the placement of your point given the points played by the players proceeding you. Your implementation must be capable of playing at least 4 turns. Strategies will be evaluated by running a game for every unique grouping of 4 strategies and every possible ordering of the 4 strategies within that grouping. The strategy that wins the largest percentage of its games wins!
This competition will definitely benefit from lots of participation so if you’ve been reading but never submitted a solution, now’s the time to start! Also, if you know anyone that might be interested, please forward this along.
Submission Instructions
Your submission with take the form of a .py
file that implements an IStrategy
interface. I’ve created a Replit workspace where folks can implement their strategy and test to see if it works. You can either leave your file in the Replit workspace in the submissions
folder or you can attach your .py
file as part of the normal solution submission form.
Regardless of which you choose, I recommend you use the Replit workspace and the tests therein to ensure your strategy can be run properly. Here are the steps I recommend everyone follow:
Navigate the
submission
folder in the Replit workspaceDuplicate the
submission_template.py
file (click the three vertical dots next to the file and select ‘Duplicate file’) and rename it to <your_name>_strategy.py
.Be sure rename the class to <
YourName>Strategy
. Implement that class with your strategy. Also, be sure to replace the class propertiessubmitter_name
andsubmitter_email
with your information.Don’t add any arguments to the constructor (i.e.
__init__
).The only method you really need to implement ismakePlay
. This method takes an integer from 0-3 representing which turn it is. Zero means you’re playing as player 1. One means your playing as player 2, etc. It also takes a history of the previous plays. The history of previous plays will be a list of tuples with length equal to the turn number. Each tuple has two floating point numbers representing the x and y coordinate of the point.makePlay
must also return a tuple of two floating point numbers representing the point you’re selecting for your turn. This will all probably make more sense when you look at the example files insubmissions
. Please Note: YourmakePlay
function needs to be able to run in 1 second or less.
Once you’ve finished implementing your class or you want to test what you have so far, you should create a test workflow. To do this, click on the dropdown next to the Green
Run
button. ClickManage Workflows
. In the pane that opens up, click+ New Workflow
.Workflow
, give your workflow a name. Then underTasks
, selectExecute Shell Command
and in the field below add the commandpython validate_submission.py --file submissions/<your_file>.py && python test_strategy.py --file submissions/<your_file>.py
This set of tests should help ensure that your class conforms to the requirements and can be run in the tournament!
You can either leave your file there (but keep in mind your solution will be visible others!) or you can download that file and attach it to your GoogleForms submission.
The ReadMe in the Replit workspace also has some instructions if you need additional clarification.
If you aren’t comfortable programming, fear not. The wonders of generative AI should be able to help with the coding part of this. If you give a model like ChatGPT the submisison_example.py
file and a detailed description of how your strategy works, it should be able to provide you with workable results.
Please let me know if you encounter any issues!
A few other notes
Replit’s default execution environment has many of the standard Python package but if you find it doesn’t have one you need (like scipy
or something like that), you can add a step to your test workflow before the testing commands. The command should be something like
pip install <package_you_need>
I noticed that when the strategy outputs a point strictly inside the unit circle, the validation script (validate_submission.py) seems to fail, even though points on the boundary---such as (0.6, 0.8)---pass without issue.
Is this still going? I'd love to join if so.