aboutsummaryrefslogtreecommitdiff
path: root/findloop.c (follow)
Commit message (Collapse)AuthorAge
* findloop: alternative query function.Simon Tatham2019-04-13
| | | | | | | | | | | | | | | | | | | | | | | | This one tells you if a graph edge _is_ a bridge (i.e. it has inverted sense to the existing is_loop_edge query). But it also returns auxiliary data, telling you: _if_ this edge were removed, and thereby disconnected some connected component of the graph, what would be the sizes of the two new components? The data structure built up by the algorithm very nearly contained enough information to answer that already: because we assign sequential indices to all the vertices in a traversal of our spanning forest, and any bridge must be an edge of that forest, it follows that we already know the size of _one_ of the two new components, just by looking up the (minindex,maxindex) values for the vertex at the child end of the edge. To determine the other subcomponent's size, we subtract that from the size of the full component. That's not quite so easy because we don't already store that - but it's trivial to annotate every vertex's data with a pointer back to the topmost node of the spanning forest in its component, and then we can look at the (minindex,maxindex) pair of that. So now we know the size of the original component and the size of one of the pieces it would be split into, so we can just subtract.
* 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 findloop API.Simon Tatham2018-11-13
| | | | | | This shouldn't be a disruptive change at all: findloop_run and findloop_is_loop_edge now return bool in place of int, but client code should automatically adjust without needing any changes.
* New centralised loop-finder, using Tarjan's algorithm.Simon Tatham2016-02-24
In the course of another recent project I had occasion to read up on Tarjan's bridge-finding algorithm. This analyses an arbitrary graph and finds 'bridges', i.e. edges whose removal would increase the number of connected components. This is precisely the dual problem to error-highlighting loops in games like Slant that don't permit them, because an edge is part of some loop if and only if it is not a bridge. Having understood Tarjan's algorithm, it seemed like a good idea to actually implement it for use in these puzzles, because we've got a long and dishonourable history of messing up the loop detection in assorted ways and I thought it would be nice to have an actually reliable approach without any lurking time bombs. (That history is chronicled in a long comment at the bottom of the new source file, if anyone is interested.) So, findloop.c is a new piece of reusable library code. You run it over a graph, which you provide in the form of a vertex count and a callback function to iterate over the neighbours of each vertex, and it fills in a data structure which you can then query to find out whether any given edge is part of a loop in the graph or not.