Commit Graph

60 Commits

Author SHA1 Message Date
David Wang
2f20aa4086 Add test: Takuzu (A.K.A. Binairo).
takuzu_grid1: 12 guesses.
takuzu_grid2: 0 guesses.
takuzu_grid3: 0 guesses.
takuzu_grid4: 20724 guesses (all solutions).
2017-03-21 08:44:26 +11:00
David Wang
b22c6466ca Add test: Nonogram (A.K.A. Hanjie, Picross).
nonogram_wikipedia: 10 guesses.
2017-03-20 08:31:09 +11:00
David Wang
c7c0bfa128 Version bump: 0.4.0. 2017-03-19 08:11:07 +11:00
David Wang
533c382605 Update README. 2017-03-19 08:08:00 +11:00
David Wang
f22b271000 Clean up.
- Use cloned instead of map.
- Use Val instead of i32.
- Import module instead of trait.
2017-03-18 09:22:52 +11:00
David Wang
630f09fc80 Add test: xkcd knapsack problem.
xkcd_knapsack: 60 guesses.
2017-03-17 08:45:57 +11:00
David Wang
3afb599568 Delete mini integer-division module.
We no longer need this since we've added rationals.
2017-03-16 08:03:29 +11:00
David Wang
ab6267b46c Add support for rational coefficients in linear expressions.
Coef has been redefined to Rational32.
2017-03-15 08:13:30 +11:00
David Wang
20e5242624 Replace Coef with i32 in arithmetic overloads.
We want to redefine Coef to be Rational32.  However, we want to be
able to build linear expressions as easily as before.  We will do this
by retaining the overloads with i32, and introduce new overloads for
operations with Rational32s.
2017-03-14 07:52:39 +11:00
David Wang
bf656fcb0d Add dependency: num-rational. 2017-03-13 08:30:11 +11:00
David Wang
80b84f4f90 Version bump: 0.3.0. 2017-03-12 08:17:54 +11:00
David Wang
889d12bf75 Update README. 2017-03-12 08:14:42 +11:00
David Wang
65222f24d1 Update test: Samurai Sudoku.
samuraisudoku_easy: 2 -> no guesswork!
2017-03-12 08:07:31 +11:00
David Wang
93cf70c0ca Add convenience functions for unify. 2017-03-11 10:38:15 +11:00
David Wang
f265a165dd Add unification constraint.
This constraint unifies two variables.  This is done by substituting
one variable for another in all of the current constraints, resulting
a new set of constraints.

We would like to make the equality constraint perform the more general
substitution: "coef1 var1 -> coef2 var2 + constant".  While this
constraint is less general, it can be used when the variables are not
integer quantities.
2017-03-11 10:06:53 +11:00
David Wang
4a331fdc1a Separate constraints from puzzle.
Separate the list of puzzle constraints from the puzzle structure.
This allows different stages of the puzzle solution search to have
different constraints.
2017-03-11 09:51:04 +11:00
David Wang
035a8fc8a4 Clean up: candidate manipulation returns a Result.
Functions to manipulate candidates during the solution search now
always return a Result instead of sometimes returning a bool, and
other times returning an Option.

We opted to use Result over Option mainly to (ab)use the try! macro.
In addition, it also makes it emit a warning when we forget to handle
the result.  (We tend to assume people don't just ignore the result
and continue as normal, instead of putting the puzzle in a special
contradiction detected state.)
2017-03-11 09:40:20 +11:00
David Wang
5bb52b03f2 Add simple variable substitution for constraints.
Constraints must now implement the substitution of "from" with "to".
The implementations can be sanity checked when we come to build the
list of constraints that each variable wakes up.

In the future, we would like to make the more general substitution:
from -> scale * to + constant.
2017-03-09 07:52:08 +11:00
David Wang
bae1138501 Store constraints in Rc instead of Box.
We will implement unification by substituting one variable for
another, creating a new set of constraints.  Only the affected
constraints need to perform the substitution, the others can simply be
cloned.  As such, we will store constraints using reference counting.
2017-03-08 08:02:37 +11:00
David Wang
ddf425efe0 Automatically box constraints.
Puzzle.add_constraint() now takes a generic (unboxed) constraint,
making it more pleasant to use when adding custom constraints.
2017-03-08 07:57:19 +11:00
David Wang
b1b727b38e Implement Debug for intermediate puzzle search state. 2017-03-07 07:44:42 +11:00
David Wang
6689b0106f Add test: Samurai Sudoku.
samuraisudoku_easy: 2 guesses.
2017-03-06 07:53:10 +11:00
David Wang
9f9549ee56 Version bump: 0.2.0. 2017-03-05 08:58:06 +11:00
David Wang
bfb85a9f1d Update README. 2017-03-05 08:49:26 +11:00
David Wang
23ae2331bf Add test: Killer Sudoku.
killersudoku_wikipedia: 7 guesses.
2017-03-04 09:07:04 +11:00
David Wang
c93b9430c1 Add test: Kakuro.
kakuro_wikipedia: 9 guesses.
2017-03-04 08:57:52 +11:00
David Wang
dfda5961ef Add test: Sujiko.
sujiko_simetric: 4 guesses.

Note that the puzzle on Wikipedia does not specify the initial board
configuration and is not unique.
2017-03-04 08:16:33 +11:00
David Wang
d9f92e2baa Add test: Hidato.
hidato_wikipedia: 4 guesses.
2017-03-04 08:03:00 +11:00
David Wang
abb4cebce3 Equality: bound variable range by using min/max of other variables.
magicsquare_3x3: 873 -> 63 guesses.
magicsquare_4x4: 13475456 -> 539910 guesses (all solutions).
sendmoremoney_carry: 154 -> 6 guesses.
sendmoremoney_naive: 633681 -> 4 guesses.
zebra: 453 -> no guesswork!
2017-03-03 08:06:48 +11:00
David Wang
8e62c85bf5 Add test: Zebra puzzle (A.K.A. Einstein's riddle).
zebra: 453 guesses.
2017-03-02 08:42:46 +11:00
David Wang
57df25eb37 Add test: Magic Square.
magicsquare_3x3: 873 guesses.
magicsquare_4x4: 13475456 guesses (all solutions).
2017-03-02 08:25:29 +11:00
David Wang
67b7cb5dc6 Add test: Send More Money.
sendmoremoney_carry: 154 guesses.
sendmoremoney_naive: 633681 guesses.
2017-03-02 08:15:55 +11:00
David Wang
58a2b0b41f Add convenience functions for equality.
This function takes a LHS and RHS only to give the illusion of an
equality.  It simply subtracts one from the other because our
equations are all in the form: coef_i var_i + constant == 0.
2017-03-01 08:04:27 +11:00
David Wang
7e908457a2 Add equality constraint.
This is a very simple equality constraint.  It only assigns a variable
when all other variables in the equation have been assigned.  Possible
improvements:

- We can find the min and max range by considering the coefficients
  and the max and min values of the other variables in the equation.

- When there are only 2 variables remaining, we can eliminate the
  incompatible candidates and then substitute one variable for the
  other in other constraints.
2017-03-01 08:04:09 +11:00
David Wang
bddb31dd5b Add integer division with rounding up/down.
While these functions can be found in rational number libraries,
support for rational numbers is an extra complexity that we do not
wish to tackle at this stage.  We'll use these to keep things simple.
2017-02-28 07:58:38 +11:00
David Wang
407a3e7555 Overload arithmetic operators to build linear expressions.
This allows one to easily build linear constraint equations by writing
equations with the tokens.

Note that variables will always take integer values, but coefficients
may be generalised to support rationals.
2017-02-27 08:14:56 +11:00
David Wang
8b90319555 Add crates.io metadata. 2017-02-26 07:54:03 +11:00
David Wang
afc08ad697 Add README. 2017-02-26 07:54:02 +11:00
David Wang
73bf143595 All Different: detect values that can only be assigned to one variable.
queen_6x6: 66 -> 62 guesses.
queen_7x7: 179 -> 167 guesses.
queen_8x8: 662 -> 590 guesses.
sudoku_hardest: 1850 -> 172 guesses.
2017-02-25 09:05:13 +11:00
David Wang
7c3ba0faee All Different: contradiction if more variables than candidates.
sudoku_hardest: 1850 -> 1594 guesses.
2017-02-25 08:45:38 +11:00
David Wang
0477a5bbb0 Only wake affected constraints. 2017-02-25 08:17:07 +11:00
David Wang
6eb25f6af0 Add test: N-queens problem.
queens_4x4: 8 guesses.
queens_5x5: 21 guesses.
queens_6x6: 66 guesses.
queens_7x7: 179 guesses.
queens_8x8: 662 guesses.
2017-02-24 07:40:33 +11:00
David Wang
34e58114ea Add test: Sudoku.
sudoku_hardest: 1850 guesses.
sudoku_wikipedia: no guesswork!
2017-02-24 07:26:56 +11:00
David Wang
6546a936c3 Count the number of guesses taken to solve the puzzle. 2017-02-24 07:16:53 +11:00
David Wang
3911802d89 Add convenience functions for all different.
The constraint creation functions now take an IntoIterator allowing
you to use generic collections, and even perform maps and filters.
This is useful, for example, when the variables are in a 2d array.
2017-02-23 08:06:17 +11:00
David Wang
fcefa40b6c Add all different constraint.
This is a very simple all different constraint, e.g.

- It does not know that if there are more variables than candidates,
  it has reached a contradiction.

- It does not know that, if there are as many variables as candidates,
  if only one variable can take on a candidate value, then all other
  candidates for that variable can be eliminated.
2017-02-23 07:53:26 +11:00
David Wang
460e91e16b Apply puzzle constraints.
For simplicity, we currently wake every constraint whenever there is a
change.  A constraint's on_assigned function must take this into
account.
2017-02-22 08:11:17 +11:00
David Wang
d199b65a22 Add puzzle solver stubs.
We have not implemented any constraints yet, so this simply finds all
combinations of variable assignments.
2017-02-22 07:40:06 +11:00
David Wang
651cc9f6c7 Add constraint trait.
Each constraint is a little sub-program that attempts to reduce the
search space.  They should only be run as required, i.e. when the
candidates of the variables they use were updated, though this has not
yet been implemented.

Constraints are traits so that puzzles may implement their own
specialised contraints as required.  We have split the trait into an
"on_assigned" call and an "on_updated" call for clarity.  The provided
methods simply return true, indicating no contradiction.
2017-02-21 08:24:59 +11:00
David Wang
a5c274d9b7 Add puzzle search helper type.
The puzzle search type is a puzzle with some variables assigned.  It
will be passed (mutably) to constraints for them to do their thing.

All changes to a variables' candidates must go through this object so
that we can wake up affected constraints.
2017-02-20 08:18:42 +11:00