latin.h 4.3 KB

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