aboutsummaryrefslogtreecommitdiff
path: root/dsf.c (follow)
Commit message (Collapse)AuthorAge
* Actually rewrite the dsf implementation.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | | | | | This rewrite improves the core data structure implementation in two ways. Firstly, when merging two equivalence classes, we check their relative sizes, and choose the larger class's canonical element to be the overall root of the new class tree. This minimises the number of overlong paths to the root after the merge. Secondly, we defer path compression until _after_ the two classes are merged, rather than do it beforehand (via using edsf_canonify as a subroutine) and then have to do it wastefully again afterwards. The size-based root selection was what we _used_ to do, and delivers the better asymptotic performance. I reverted it so that Keen could track the min of each equivalence class. But since then I've realised you can have the asymptotic goodness _and_ min-tracking if you store the minima separately from the main data structure. So now Keen does that, and other clients don't have to pay the cost. Similarly, the flip tracking is now a cost that only users of flip dsfs have to pay, because a normal one doesn't store that information at all.
* Reorganise the dsf API into three kinds of dsf.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | This is preparing to separate out the auxiliary functionality, and perhaps leave space for making more of it in future. The previous name 'edsf' was too vague: the 'e' stood for 'extended', and didn't say anything about _how_ it was extended. It's now called a 'flip dsf', since it tracks whether elements in the same class are flipped relative to each other. More importantly, clients that are going to use the flip tracking must say so when they allocate the dsf. And Keen's need to track the minimal element of an equivalence class is going to become a non-default feature, so there needs to be a new kind of dsf that specially tracks those, and Keen will have to call it. While I'm here, I've renamed the three dsf creation functions so that they start with 'dsf_' like all the rest of the dsf API.
* Introduce a new dsf_equivalent() function.Simon Tatham2023-04-20
| | | | | Not very interesting, but the idiom for checking equivalence via two calls to dsf_canonify is cumbersome enough to be worth abbreviating.
* Remove conditioned-out dsf diagnostic code.Simon Tatham2023-04-20
| | | | | | | | print_dsf was declared in puzzles.h, but never called, and its definition was commented out. So it probably wouldn't still have worked anyway. The other commented-out printfs in that file don't look very useful either, and they just mean more stuff will need messing about with as I continue to refactor.
* Remove size parameter from dsf init and copy functions.Simon Tatham2023-04-20
| | | | | | | | | Now that the dsf knows its own size internally, there's no need to tell it again when one is copied or reinitialised. This makes dsf_init much more about *re*initialising a dsf, since now dsfs are always allocated using a function that will initialise them anyway. So I think it deserves a rename.
* Store a size field inside the DSF type.Simon Tatham2023-04-20
| | | | | | This permits bounds-checking of all inputs to dsf_canonify and dsf_merge, so that any out-of-range values will provoke assertion failure instead of undefined behaviour.
* Actually make DSF an opaque structure type.Simon Tatham2023-04-20
| | | | | | | | | | This makes good on all the previous preparatory commits, which I did separately so that each one individually has a reasonably readable diff, and all the mechanical changes are separated out from the rewrites that needed actual thought. Still no functional change, however: the DSF type wraps nothing but the same int pointer that 'DSF *' used to store directly.
* Declare all dsfs as a dedicated type name 'DSF'.Simon Tatham2023-04-20
| | | | | | | In this commit, 'DSF' is simply a typedef for 'int', so that the new declaration form 'DSF *' translates to the same type 'int *' that dsfs have always had. So all we're doing here is mechanically changing type declarations throughout the code.
* Use a dedicated copy function to copy dsfs.Simon Tatham2023-04-20
| | | | | | | | | Previously we were duplicating the contents of a dsf using straight-up memcpy. Now there's a dsf_copy function wrapping the same memcpy. For the moment, this still has to take a size parameter, because the size isn't stored inside the dsf itself. But once we make a proper data type, it will be.
* Use a dedicated free function to free dsfs.Simon Tatham2023-04-20
| | | | | No functional change: currently, this just wraps the previous sfree call.
* Use C99 bool within source modules.Simon Tatham2018-11-13
| | | | | | | | | | This is the main bulk of this boolification work, but although it's making the largest actual change, it should also be the least disruptive to anyone interacting with this code base downstream of me, because it doesn't modify any interface between modules: all the inter-module APIs were updated one by one in the previous commits. This just cleans up the code within each individual source file to use bool in place of int where I think that makes things clearer.
* Replace TRUE/FALSE with C99 true/false throughout.Simon Tatham2018-11-13
| | | | | | This commit removes the old #defines of TRUE and FALSE from puzzles.h, and does a mechanical search-and-replace throughout the code to replace them with the C99 standard lowercase spellings.
* Adopt C99 bool in the edsf API.Simon Tatham2018-11-13
| | | | | | | | | | Now the flag passed to edsf_merge to say whether two items are the same or opposite is a bool, and so is the flag returned via a pointer argument from edsf_canonify. The latter requires client code to be updated to match (otherwise you'll get a pointer type error), so I've done that update in Loopy, which is edsf's only current in-tree client.
* New puzzle! 'Keen', a clone of KenKen.Simon Tatham2009-12-27
| | | | [originally from svn r8796]
* Tweak the semantics of dsf_merge() so that the canonical element ofSimon Tatham2009-12-27
| | | | | | | | | any equivalence class is always the element with the smallest index. This is slower (the previous behaviour, suggested by Jonas Koelker, was to choose the new root element to maximise performance), but still more than acceptably fast and more useful. [originally from svn r8792]
* New puzzle: `Filling', a Fillomino implementation by Jonas Koelker.Simon Tatham2007-02-25
| | | | [originally from svn r7326]
* James H's Palm-compatibility updates to the latest Loopy changes,Simon Tatham2006-11-01
| | | | | | | working around bugs in the Palm compiler and removing Palm- incompatible diagnostics such as fprintf. [originally from svn r6889]
* r6880 accidentally backed out r6780. That's what I get for acceptingSimon Tatham2006-10-29
| | | | | | | | | source files from Mike rather than patches, and not adequately checking the result... [originally from svn r6882] [r6780 == f05c25347d66821d928668a7e87dffbf3ffed027] [r6880 == b9547673c6462bf73e642328300479df6df71d7b]
* Mike Pinna has done some major reworking of the Loopy solver, givingSimon Tatham2006-10-28
| | | | | | rise to a new Hard difficulty level. [originally from svn r6880]
* Extra utility function.Simon Tatham2006-08-05
| | | | [originally from svn r6780]
* Cleanups from James H: a few missing statics, a precautionary castSimon Tatham2005-08-03
| | | | | | | | | or two, a debugging fix, a couple of explicit initialisations of variables that were previously read uninitialised, and a fix for a whopping great big memory leak in Slant owing to me having completely forgotten to write free_game(). [originally from svn r6159]
* New puzzle: `Slant', picked from the Japanese-language section ofSimon Tatham2005-08-02
nikoli.co.jp (which has quite a few puzzles that they don't seem to have bothered to translate into English). Minor structural change: the disjoint set forest code used in the Net solver has come in handy again, so I've moved it out into its own module dsf.c. [originally from svn r6155]