A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 126 lines 4.4 kB view raw
1#ifndef LATIN_H 2#define LATIN_H 3 4#include "puzzles.h" 5 6typedef unsigned char digit; 7 8/* --- Solver structures, definitions --- */ 9 10#ifdef STANDALONE_SOLVER 11extern int solver_show_working, solver_recurse_depth; 12#endif 13 14struct latin_solver { 15 int o; /* order of latin square */ 16 unsigned char *cube; /* o^3, indexed by x, y, and digit: 17 true in that position indicates a possibility */ 18 digit *grid; /* o^2, indexed by x and y: for final deductions */ 19 20 unsigned char *row; /* o^2: row[y*cr+n-1] true if n is in row y */ 21 unsigned char *col; /* o^2: col[x*cr+n-1] true if n is in col x */ 22 23#ifdef STANDALONE_SOLVER 24 char **names; /* o: names[n-1] gives name of 'digit' n */ 25#endif 26}; 27#define cubepos(x,y,n) (((x)*solver->o+(y))*solver->o+(n)-1) 28#define cube(x,y,n) (solver->cube[cubepos(x,y,n)]) 29 30#define gridpos(x,y) ((y)*solver->o+(x)) 31#define grid(x,y) (solver->grid[gridpos(x,y)]) 32 33 34/* --- Solver individual strategies --- */ 35 36/* Place a value at a specific location. */ 37void latin_solver_place(struct latin_solver *solver, int x, int y, int n); 38 39/* Positional elimination. */ 40int latin_solver_elim(struct latin_solver *solver, int start, int step 41#ifdef STANDALONE_SOLVER 42 , const char *fmt, ... 43#endif 44 ); 45 46struct latin_solver_scratch; /* private to latin.c */ 47/* Set elimination */ 48int latin_solver_set(struct latin_solver *solver, 49 struct latin_solver_scratch *scratch, 50 int start, int step1, int step2 51#ifdef STANDALONE_SOLVER 52 , const char *fmt, ... 53#endif 54 ); 55 56/* Forcing chains */ 57int latin_solver_forcing(struct latin_solver *solver, 58 struct latin_solver_scratch *scratch); 59 60 61/* --- Solver allocation --- */ 62 63/* Fills in (and allocates members for) a latin_solver struct. 64 * Will allocate members of solver, but not solver itself 65 * (allowing 'struct latin_solver' to be the first element in a larger 66 * struct, for example). 67 * 68 * latin_solver_alloc returns false if the digits already in the grid 69 * could not be legally placed. */ 70bool latin_solver_alloc(struct latin_solver *solver, digit *grid, int o); 71void latin_solver_free(struct latin_solver *solver); 72 73/* Allocates scratch space (for _set and _forcing) */ 74struct latin_solver_scratch * 75 latin_solver_new_scratch(struct latin_solver *solver); 76void latin_solver_free_scratch(struct latin_solver_scratch *scratch); 77 78 79/* --- Solver guts --- */ 80 81/* Looped positional elimination */ 82int latin_solver_diff_simple(struct latin_solver *solver); 83 84/* Looped set elimination; extreme permits use of the more difficult 85 * single-number elimination. */ 86int latin_solver_diff_set(struct latin_solver *solver, 87 struct latin_solver_scratch *scratch, 88 bool extreme); 89 90typedef int (*usersolver_t)(struct latin_solver *solver, void *ctx); 91typedef bool (*validator_t)(struct latin_solver *solver, void *ctx); 92typedef void *(*ctxnew_t)(void *ctx); 93typedef void (*ctxfree_t)(void *ctx); 94 95/* Individual puzzles should use their enumerations for their 96 * own difficulty levels, ensuring they don't clash with these. */ 97enum { diff_impossible = 10, diff_ambiguous, diff_unfinished }; 98 99/* Externally callable function that allocates and frees a latin_solver */ 100int latin_solver(digit *grid, int o, int maxdiff, 101 int diff_simple, int diff_set_0, int diff_set_1, 102 int diff_forcing, int diff_recursive, 103 usersolver_t const *usersolvers, validator_t valid, 104 void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree); 105 106/* Version you can call if you want to alloc and free latin_solver yourself */ 107int latin_solver_main(struct latin_solver *solver, int maxdiff, 108 int diff_simple, int diff_set_0, int diff_set_1, 109 int diff_forcing, int diff_recursive, 110 usersolver_t const *usersolvers, validator_t valid, 111 void *ctx, ctxnew_t ctxnew, ctxfree_t ctxfree); 112 113void latin_solver_debug(unsigned char *cube, int o); 114 115/* --- Generation and checking --- */ 116 117digit *latin_generate(int o, random_state *rs); 118 119/* The order of the latin rectangle is max(w,h). */ 120digit *latin_generate_rect(int w, int h, random_state *rs); 121 122bool latin_check(digit *sq, int order); /* true => not a latin square */ 123 124void latin_debug(digit *sq, int order); 125 126#endif