Skip to content

Instantly share code, notes, and snippets.

@ProfAvery
Created January 7, 2021 05:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ProfAvery/cbcb880538b799bf1c2b1a7de42b044e to your computer and use it in GitHub Desktop.
Save ProfAvery/cbcb880538b799bf1c2b1a7de42b044e to your computer and use it in GitHub Desktop.
State machine example in C
/* Knuth-Yao state machine - model a fair die using only a fair coin
*
* See <https://www.prismmodelchecker.org/casestudies/dice.php>.
*
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int counter = 0;
int counts[6] = {0};
bool coin_flip(void)
{
return (rand() % 2) == 0;
}
void report(void)
{
for (int i = 0; i < 6; i++) {
printf("%.3f ", (double) counts[i] / counter);
}
printf("\n");
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s N\n", argv[0]);
return EXIT_FAILURE;
}
int n = atoi(argv[1]);
srand(time(NULL));
s0:
if (++counter > n) { report(); goto end; }
if (coin_flip()) { goto s1; } else { goto s2; }
s1:
if (coin_flip()) { goto s3; } else { goto s4; }
s2:
if (coin_flip()) { goto s5; } else { goto s6; }
s3:
if (coin_flip()) { goto s1; } else { counts[0]++; goto s0; }
s4:
if (coin_flip()) { counts[1]++; goto s0; } else { counts[2]++; goto s0; }
s5:
if (coin_flip()) { counts[3]++; goto s0; } else { counts[4]++; goto s0; }
s6:
if (coin_flip()) { goto s2; } else { counts[5]++; goto s0; }
end:
return EXIT_SUCCESS;
}
CFLAGS= -g -std=c11 -Wall -Wextra -Wpedantic
TARGET=dieroll
$(TARGET): $(TARGET).c
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
test: $(TARGET)
./$< 100000
clean:
rm -f $(TARGET)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment