simu

Ice hockey final standings simulator
git clone https://git.inz.fi/simu
Log | Files | Refs

commit 0a61712c1fcab678dc05743ec256912efda93abe
parent 4cf7965e86a8e7128660791e6c2d80cbfa69ed6d
Author: Santtu Lakkala <inz@inz.fi>
Date:   Thu, 12 Mar 2026 09:54:21 +0200

Reduce repetition in C version

Diffstat:
Msimu.c | 80++++++++++++++++++++++++++++++-------------------------------------------------
1 file changed, 30 insertions(+), 50 deletions(-)

diff --git a/simu.c b/simu.c @@ -86,12 +86,11 @@ static inline uint32_t getrand(struct rand_t *r) } #endif -static inline bool urand(uint32_t limit, bool *anti, struct rand_t *r) +static inline void urand(uint32_t limit, bool rv[static 2], struct rand_t *r) { uint32_t v = getrand(r); - if (anti) - *anti = (uint32_t)R_MAX - v < limit; - return (uint32_t)v < limit; + rv[0] = (uint32_t)v < limit; + rv[1] = (uint32_t)R_MAX - v < limit; } struct team { @@ -186,8 +185,7 @@ void simulate(struct team *teams, struct rand_t *seedp) { struct standing s0[n_teams]; - struct standing standings[n_teams]; - struct standing antistandings[n_teams]; + struct standing standings[2][n_teams]; size_t i; for (i = 0; i < n_teams; i++) { @@ -199,58 +197,40 @@ void simulate(struct team *teams, for (i = 0; i < iterations / 2; i++) { size_t j; + size_t k; - memcpy(standings, s0, sizeof(standings)); - memcpy(antistandings, s0, sizeof(antistandings)); + memcpy(standings[0], s0, sizeof(*standings)); + memcpy(standings[1], s0, sizeof(*standings)); for (j = 0; j < n_games; j++) { - size_t wi; - size_t li; - size_t awi; - size_t ali; - - bool antihw; - bool antiot; - bool hw = urand(games[j].expected, &antihw, seedp); - bool ot = urand(otprob, &antiot, seedp); - - wi = games[j].t[!hw]; - li = games[j].t[hw]; - - awi = games[j].t[!antihw]; - ali = games[j].t[antihw]; - - standings[wi].points += 3 - ot; - standings[li].points += ot; - standings[wi].wins += !ot; - standings[wi].games++; - standings[li].games++; - - antistandings[awi].points += 3 - ot; - antistandings[ali].points += ot; - antistandings[awi].wins += !ot; - antistandings[awi].games++; - antistandings[ali].games++; - } + bool hw[2]; + bool ot[2]; - for (j = 0; j < n_teams; j++) { - standings[j].random = getrand(seedp) % (INT_MAX / 2); - antistandings[j].random = getrand(seedp) % (INT_MAX / 2); - } - isort(standings, n_teams, sizeof(*standings), pointscmp); + urand(games[j].expected, hw, seedp); + urand(otprob, ot, seedp); + + for (k = 0; k < 2; k++) { + size_t wi = games[j].t[!hw[k]]; + size_t li = games[j].t[hw[k]]; - for (j = 0; j < n_teams; j++) { - teams[standings[j].ti].pointsum += standings[j].points; - teams[standings[j].ti].gamessum += standings[j].games; - teams[standings[j].ti].poscounts[j]++; + standings[k][wi].points += 3 - ot[k]; + standings[k][li].points += ot[k]; + standings[k][wi].wins += !ot[k]; + standings[k][wi].games++; + standings[k][li].games++; + } } - isort(antistandings, n_teams, sizeof(*antistandings), pointscmp); + for (k = 0; k < 2; k++) { + for (j = 0; j < n_teams; j++) + standings[k][j].random = getrand(seedp) % (INT_MAX / 2); + isort(standings[k], n_teams, sizeof(*standings[k]), pointscmp); - for (j = 0; j < n_teams; j++) { - teams[antistandings[j].ti].pointsum += antistandings[j].points; - teams[antistandings[j].ti].gamessum += antistandings[j].games; - teams[antistandings[j].ti].poscounts[j]++; + for (j = 0; j < n_teams; j++) { + teams[standings[k][j].ti].pointsum += standings[k][j].points; + teams[standings[k][j].ti].gamessum += standings[k][j].games; + teams[standings[k][j].ti].poscounts[j]++; + } } }