About the par model
Live coefficients are loaded from handicaps.json at the bottom of this page.
Every daily and weekly puzzle in GregSweeper has a par time — the time the model expects a typical player to need on that specific board. Your personal handicap shifts par up or down based on your past plays, golf-style.
What's in the model
The model is a Bayesian mixed-effects regression of completion time on board features:
The fixed-effect coefficients are global (every player shares them). The random intercept (1 | user) is your personal handicap — the average residual between your times and predicted par.
The fit, in detail
- Tool:
brmswith Stan, four chains, 2000 iterations per chain. - Priors: lognormal on each coefficient with a wide sigma; the data does most of the work after the first ~50 plays.
- Outlier rejection: rows with
time < max(5, 0.3 × predicted_par)are filtered before fitting. - Bomb hits: included in the fit as a regressor (~14s per hit) so the per-feature coefficients aren't polluted by mine-strike inflation. Not shipped to the client-side
predictPar— your shown par stays "clean-play par." - Threshold: a refit only ships if Rhat ≤ 1.05, min ESS ≥ 400, divergent transitions ≤ 0.25%. Below threshold, the previous coefficients stay and the workflow fails loudly.
- Schedule: refits run daily at ~10am ET (14:00 UTC).
Your personal handicap
If you've played at least 30 daily puzzles, your handicap is fitted directly as the random intercept on the model. Below that, the game shows a provisional handicap computed from the mean residual of your last few plays (with bomb-hit time cost subtracted). The provisional handicap converges to the fitted one as you accumulate plays.
Where the code lives
- scripts/refit-par-model.R — the production refit pipeline. Runs in GitHub Actions.
- scripts/fit-par-model.qmd — the exploratory Quarto notebook with diagnostics (VIF, posterior plots, prior-vs-posterior).
- src/logic/difficulty.js — the shipped coefficients (between the
PAR_MODEL:START/PAR_MODEL:ENDmarkers). - src/logic/handicaps.json — the per-user handicap map, refreshed by each refit.