     /------------------------------\
-----|   DeewiantSudoku ChangeLog   |-------------------------------------------
     \------------------------------/

-------------------------------------------------------------------------------
 3.0.0 alpha 1                   2006-08-27
-------------------------------------------------------------------------------
 - New example.
 - Removed option: --force-naked.
 - Change: bit arrays instead of integer arrays used for candidates.
 - Change: report any correct guesses at end of solving when explaining.
 - Change: removed the asterisk as a possible "empty" token: it is often used
           as corners or edges of a grid, like minus and plus signs.
 - Change: added the X, both lower and upper case, as an "empty" token.
 - Change: show iterations used whilst guessing.
 - Change: made naked and hidden subsets always calculate the maximum size they
           could be in a given area, so that they don't needlessly check for
           too big subsets. A noticeable optimisation for hidden subsets.
 - Change: changed the filename to something other than "sudoku", something I
           had been meaning to do for a long time.
 - Change: statistics now output the number of techniques used.
 - Bug fix: naked subsets were broken, now they're fixed, and thereby a lot
            slower. This is due to bit counting, as mentioned above.
 - Bug fix: loading would sometimes fail causing Access Violations or the like.
            Now, loading should always fail gracefully when running into excess
            or too few characters, or into a lack of an EOL at EOF.
 - Bug fix: strange printGrid() logic following the main loop.
 - Bug fix: xyWing() would sometimes go out of bounds of the candidates array
            and thereby crash the entire program.
 - Internal: combined naked and hidden subsets into a single function which
             searches first for pairs, then for triplets, etc. Altogether the
             subset code is now a lot faster than previously, but a slowdown
             comes from counting the number of bits in a BitArray. Fast
             algorithms for dims <= 32 and <= 64 were found but it's still the
             bottleneck. Nevertheless the code is now fast enough.
 - Internal: swapped order of XY- and XYZ-wing; in some sets of harder puzzles
             the latter is more common, but in most the former is.
 - Internal: switched to using type inference in foreach loops.
 - Internal: made nested functions static where reasonably possible.
 - Internal: made ichthyology use only one function for both rows and columns.
             Also made it use the parts array used by subsets instead of
             calculating its own partitions every time, as an optimisation.
 - Internal: improved logic in the load() function. No need for a NEWLINES
             array, the program figures that it needs a new row when it runs
             out of room in the current one.
 - Internal: removed pointless "package" accessibility modifiers.
 - Internal: changed many imports to be selective.

-------------------------------------------------------------------------------
 2.1.0                           2006-03-02
-------------------------------------------------------------------------------
 - New example.
 - Bug fix: an incorrect plural in "1 guess, of which 0 were correct".
 - Bug fix: forgot to change version number with 2.0.1.
 - Bug fix: the "-d=N" way of specifying a custom dimension had probably not
            worked since before 1.0.0.
 - Bug fix: terse output and input was fairly screwed up for higher dimensions.
 - Bug fix: ichthyology explanations used rows when meaning columns, and vice
            versa.
 - Bug fix: flushing output streams only when it's necessary now.
 - Change: added the asterisk and comma as possible "empty" tokens.
 - Change: forgetting about hidden subsets already for any dimension > 9: the
           code is just too slow even for 16*16 Sudokus - and, to be honest,
           for 9*9 as well, but not unbearably so.
 - New option: --force-naked.
 - Internal: removed the module constructor in solver.d, moving the method
             initialisation to initSolver().
 - Internal: changed "catch (Exception e)" to just "catch" in the load()
             function.

-------------------------------------------------------------------------------
 2.0.1                            2006-02-27
-------------------------------------------------------------------------------
 - Bug fix: two incorrect plurals in "1 guesses, all of which were correct".

-------------------------------------------------------------------------------
 2.0.0                            2006-02-27
-------------------------------------------------------------------------------
 - Milestone: will find a solution to any Sudoku which has at least one.
 - New technique: guessing. Not done by default.
 - New option: --allow-guessing.
 - New option: --benchmark.
 - Bug fix: modification of newlines in output.
 - Internal: no need to check for candidate 0 in printCandidates(), as there can
             be no such thing.
 - Internal: Realised from the above that using 0 as empty might be smart, and
             thus changed the constant NONE from -1 to 0.

-------------------------------------------------------------------------------
 1.2.2                           2006-02-21
-------------------------------------------------------------------------------
 - Internal: more messing about with the Hidden Subset code. Should be even
             faster now, but it's still by far the slowest function of the
             bunch.
 - Internal: extremely minor optimisation in Cell.removeCandidatesExcept().

-------------------------------------------------------------------------------
 1.2.1                           2006-02-20
-------------------------------------------------------------------------------
 - New option: --row-numbers.
 - Change: to reflect --row-numbers, removed silly characters from ROWCHARS, so
           big grids can now only be explained/keyed/etc with --row-numbers set.
 - Bug fix: fixed spacing in output - removed some extraneous newlines, added
            others, and such.
 - Bug fix: had left something accidentally commented out, put it back in.
 - Bug fix: Hidden Subset code was completely foobar!! Extremely slow - it was
            faster to check only for naked subsets up to 2*dim than for nakeds
            of size dim/2 and hiddens of size (dim-1)/2 - and didn't find what
            it should have.
            Well, it's still that slow, but much faster. The major bottleneck
            is clearly Parter, but I don't see how to manage without it.
 - Internal: removed the quit() function - std.c.stdlib.exit() breaks code
             coverage (which, I think, is because it breaks module destructors).
 - Internal: changed the noGrid "return 1" to a "return 42".
 - Internal: some minor optimisations in hiddenSubset(), ichthyology(),
             updateCandidates(Cell[]), and Parter.all().
 - Internal: added hasCandidate(int[], int), which mostly replaces
             contains(int[], int). It's a binary, instead of linear, search.
 - Internal: modified Cell.find (renamed it to findCandidate) to also use a
             binary search.
 - Internal: removed "inout" from all places where they referred to Cells,
             given that they're unnecessary (though sometimes helpful to
             readers of the code). I suspected that it would improve speed and
             was right.

-------------------------------------------------------------------------------
 1.2.0                           2006-02-19
-------------------------------------------------------------------------------
 - Milestone: all the "simple advanced" techniques are implemented. Next up is
              stuff like Colouring and Forcing chains.
 - New technique: XYZ-wing. Placed before XY-wing and Ichthyology due to its
                            ubiquitousness.
 - Internal: moved buddies() from being a separate function to a method of
             Cell.
 - Internal: overloaded contains() for int[], int[].

-------------------------------------------------------------------------------
 1.1.1                           2006-02-18
-------------------------------------------------------------------------------
 - Change: moved the "Solved!" output from showing the grid to the statistics.
 - Change: added a check for whether the puzzle is solved at every iteration.
           This is a significant optimisation, now that there are so many solve
           methods.
 - Internal: moved ++iterations from after calling the solve methods to before.
 - Internal: moved XY-wing so that it is tried before Ichthyology. A minor
             speed increase results.

-------------------------------------------------------------------------------
 1.1.0                           2006-02-17
-------------------------------------------------------------------------------
 - New feature: timer. Packaged in with the rest of the stats. Counts only the
                       time used in solving, not the total time taken.
 - New option: --no-solve.
 - New technique: XY-wing.
 - Bug fix: iterations were not zeroed at the beginning of solving.
 - Internal: added the handyish nCandidates() function.
 - Internal: moved output functions to a module of their own. Still lots of
             dout.writefln(), derr.writefln() elsewhere.

-------------------------------------------------------------------------------
 1.0.0                           2006-02-14
-------------------------------------------------------------------------------
 - Milestone: first numbered version!
 - Milestone: capabilities should now equal those of http://sudokusolver.co.uk/
              but only in terms of "logic": no equivalent to its "Ariadne's
              Thread" bruteforcer.
 - New technique: Ichthyology (X-Wing, Swordfish, etc.).
 - New option: --help.
 - New option: --version.
 - New option: --check-validity.
 - New option: --total-statistics.
 - New option: --examples.
