Inspiration
A random outcome does not necessarily mean that the probabilities behind it are constant. House Edge challenged us to investigate that distinction: could we use a machine’s payout history to estimate its next payout distribution, even when its behavior changes?
We were interested in building a model we could understand and explain. Beyond obtaining a strong validation score, we wanted to understand which patterns were useful, how much evidence supported them, and when our model should remain uncertain.
What it does
Our program forecasts the probability of five possible payouts—0×, 1×, 2×, 5×, and 20×—for each simulated machine’s next spin.
It analyzes earlier outcomes, compares temporal relationships, and combines those estimates into a probability distribution. It learns which lag patterns recur across training machines while allowing individual machines to respond differently. For the adaptation round, it refits those shared patterns using the newly released data.
The final program produces the required prediction CSV and includes a saved model and reproducible code package.
How we built it
We built the forecasting pipeline in Python and worked with CSV histories, JSON checkpoints, and the organizer’s parsing and scoring tools.
We started with smoothed payout frequencies, then developed a model that compares individual lags and pairs of outcomes from up to eight ticks earlier. An important improvement was grouping lag-pair outcomes by whether they matched or differed. This reduced the number of conditional probabilities each machine needed to estimate from a short history.
We then learned a shared prior over useful lag relationships from training data. Each machine’s own history determines how it responds to those relationships. The model separately estimates the chance of a positive payout and the distribution of positive payout sizes.
Our final adaptation version averages two forecasts with different win-history memory lengths while using a longer memory for payout sizes. The submission predictor runs using only Python’s standard library and requires no network connection.
Challenges we ran into
The biggest modeling challenge was balancing responsiveness with uncertainty. Short memory helps detect changing behavior, but provides fewer observations for identifying patterns. Longer memory produces more stable estimates, but can preserve relationships that are no longer useful.
Missing observations also required careful handling. A missing tick could not be treated as a loss, and a lag had to refer to an actual time difference rather than a row position.
Another challenge was evaluating improvements honestly. Repeatedly tuning against the same validation episodes can produce misleading gains. We kept related machines together in episode-level splits, compared models across conditions, and distinguished validation performance from unknown private-test performance.
Finally, we needed to make the submission portable. The code had to recreate its forecasts from a clean folder without relying on our development environment or personal file paths.
Accomplishments that we're proud of
We developed an interpretable forecasting model that improved on the provided frequency baseline and adapted to a new set of temporal relationships.
We are especially proud that a simpler representation—grouping earlier outcomes into “match” and “differ”—produced a substantial improvement. It showed us that choosing a useful representation can matter more than adding complexity.
We also produced a complete, reproducible submission. The final adaptation CSV passed the official format checks for all 1,536 test queries, and a fresh extraction of the submission ZIP recreated that CSV byte-for-byte.
What we learned
We learned that forecasting probabilities requires more than predicting the most likely outcome. A useful model must represent uncertainty and assign reasonable probabilities to less common events.
We also learned how model structure affects the amount of data needed. Sharing evidence across related states and machines can improve estimates, but overly restrictive assumptions can hide real differences.
Most importantly, we learned to question validation improvements. A higher score is encouraging, but its meaning depends on how the model was selected and what information was available during evaluation. Building the evaluation and reproduction pipeline became as important as developing the forecasting algorithm.
What's next for 67/33 - House Edge
We want to separate learning a machine’s underlying temporal relationship from tracking how that relationship changes over time. A future model could use longer history to identify the relationship and a dynamic update process to estimate its current strength and direction.
We also want to investigate shared changes across machines and improve predictions of positive payout sizes. We would evaluate these additions through causal historical forecasts and episode-level comparisons, keeping a reproducible baseline to determine whether additional complexity is justified.