GithubHelp home page GithubHelp logo

fiveham / sudoku_solver Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 832 KB

Solve sudoku puzzles by representing the puzzle as a bipartite graph of truth-claims about cells' values and rule-statements that have exactly one true neighbor and removing edges as information is added

License: MIT License

Java 100.00%

sudoku_solver's People

Contributors

fiveham avatar

Watchers

 avatar

sudoku_solver's Issues

Xor-chain pairs (in ColorChain) are tested by brute force

Currently, given n xor-chains, tests between chains for bridge interactions take O(n^2) time. Bridges between xor-chains can be found in O(n) time by first creating a Map from Claims of a chain to the chain, iterating over a collection of the chains, and for each chain, bridging Facts are detected, and those bridging Facts that contain Claims that map to another chain constitute the analysable link between two chains.

Child Times should add themselves as children of their parent during construction

This will enable the structure of a FalsifiedTime time tree to be discerned while the time tree is being built.

Calls such as

time.addChild(new SolveEventSledgehammer(time, ...).falsify());

would become

new SolveEventSledgehammer(time, ...).falsify();,

and time would know that this new SolveEventSledgehammer is among its children before the new Time has set its falsified Claims false.

Currently, the call to falsify() occurs entirely before the child Time is added as a child; as such, all the children of that child are constructed, similarly disconnected from the new child Time, before the nth grandchildren add the n+1th grandchildren as children, and so forth up the tree toward the root. That's a very unintuitive way to build a time tree; so, for the sake of clarity, bidirectionality of parent-child relationships should be enforced at the time when the child is constructed.

Size-2 Sledgehammer analysis is a particular case of XYChain analysis

Given two source Facts of size 2, either Fact can be treated as a very small xor-chain, such that bridge analysis (currently incorporated into XYChain analysis) with odd path lengths between the bridge's lanes in either xor-chain can fully account for the consequences of resolving the arrangement as a Sledgehammer scenario.

Attached is a diagram of such an arrangement and its solution states, which may help clarify what I mean.

This overlap in analysis means that once ColorChain has finished working on a puzzle, when Sledgehammer starts, it will repeat (without being able to make any changes) the efforts ColorChain did with respect to size-2 sledgehammer scenarios.

  • Remove consideration of size-2 sledgehammers from the Sledgehammer implementation, or
  • unify the ColorChain and Sledgehammer concepts somehow.

xor sledgehammer xy-chain

Techniques using constant Universe from Puzzle have less efficient BackedSets

BackedSets used by a Technique can be more efficient with a smaller Universe if the Technique's Universe is generated in the Technique itself so that the Universe contains only nodes found in the single-connected-component network being solved by that Technique.

Generating new Universes per Technique would

  • (+) Expedite iteration over BackedSets having that smaller Universe
  • (+) Expedite (slightly) bulk-operations on BackedSets having that smaller Universe, because the overall size of the internal mask is smaller, and
  • (-) Slow the start of Universe-using Technique instances because they need to take the time to build a new Universe object

Support for different charsets

Right now, Parsers only use Scanner's default character encoding. Solver, Parsers, and all other involved classes should have a way for the user or calling context to specify the charset to use for the Scanner(s) reading a specified file.

Copying Sets in Sledgehammer.exploreSourceCombos() less efficient than using internal BigInteger masks

Need to create (or find) a Set class that references a backend Set and masks that Set's elements with a bit in a BigInteger when that element is removed and use that Set class instead of HashSet where applicable in order to avoid copying subsets of such a Set: instead a reference to the backing set is copied and a BigInteger allowing only a small subset of elements to be acknowledged as present is created.

Formalize the need for FalsifiedTime args in retrofitted Collection methods in NodeSet

Currently, there are duplicate methods in NodeSet, such as clear() and clear(FalsifiedTime), where one method fulfills a requirement of the Set or Collection interface and the other fulfills the practical necessity of providing graph-modifying methods access to their appropriate modification-point on the growing time-tree of solution events.

Using Collection's methods in principle while never using Collection's methods themselves clashes with the concept of Collection as an API. NodeSet should be reconceived such that

  • NodeSet retains its analogous methods that accept a FalsifiedTIme and loses its timeless methods from Collection
  • the analogous methods that accept a FalsifiedTime are removed and Collection's methods are used instead, where the pertinent FalsifiedTime is specified elsewhere, such as on a third-party stack, or
  • new analogous methods are used that do not accept a FalsifiedTime and return a FalsifiedTime describing the solution events that occurred between entering that method and returning from it.

WhatIf can assume contradictory things.

An exception should be thrown in assumeTrue() if a Claim to be assumed true is already known to be false as a consequence of an (or some) other Claim(s) assumed to be true.

To expedite such a check, Claims should be partitioned, for example in a Map<Boolean,Set> paired with a reverse Map<Claim,Boolean> to quickly check for the Claim's status.

NodeSet.visible() duplicates code from ConnectedComponent

The method can be redesigned to use ConnectedComponent and a Graph's contractEventListeners.

One way to do this is to call getPuzzle() and get its connected component (Graph.component(List,Function,List) in which the NodeSet in question is the seed node, specifying a contractEventListener that counts how many times it has been called and throws a special Exception containing a reference to cuttingEdge once it has been called the appropriate number of times. NodeSet.visible() can then catch that exception and extract and return cuttingEdge.

Previous exploration of a Fact should factor into the Fact's popularity rating

If, for example, all but one of the WhatIfs in a Logic have explored a certain Fact, and the one remaining WhatIf has partially reduced that Fact, that Fact will have a popularity rating of 1, when really that Fact should be rated high on account of the synergy of exploring that Fact with other WhatIfs having already explored that Fact.

A good way to rate it high in accord with the potential for synergy with other WhatIfs is to rate it at N, where N is the number of WhatIfs in that Logic.

Claim-falsification code is duplicated

When Techniques falsify Claims, they do so in the form

TechniqueEvent event = new TechniqueSpecificEventType(falsifiedClaims);
falsifiedClaims.stream().forEach((falsifiedClaim) -> falsifiedClaim.setFalse(event));
return event;

which can be streamlined to

return new TechniqueSpecificEventType(falsifiedClaims);

by incorporating the

falsifiedClaims.stream().forEach((falsifiedClaim) -> falsifiedClaim.setFalse(event));

code into the FalsifiedTime constructor

Solver's call to wait(100) is arbitrary, should call wait() (no args) instead

So far, attempts to use wait() have resulted in inconsistent thread suspension, where the main thread is notified after the last solver thread terminates but the main thread passes the test in the header of the while loop in which its call to wait() is located again and calls wait() again

Maybe repeating the while loop's header test in an if-statement inside the synchronized block in the while loop would enable this use of wait(). That would mean that the removal of the final solver thread from its thread group had not yet registered in terms of the output of ThreadGroup.activeCount() before the main thread checked that active count and would mean that the removal of the final solver thread from its thread group will have manifested in the output of ThreadGroup.activeCount() between the
time when the main thread passes the header test and the time when the main thread gets the lock on the lock Object and entered the synchronized block inside the while loop.

Disclaimer: I don't really understand how synchronization, wait(), notify(), etc. work.

Wrap.wrap() should wrap using arbitrary WrapVertexs

So far, my attempts at enabling arbitrary output types from wrap() have all led to clashes with the "NodeSet" typing of the graph underlying Puzzle. ColorChain.link() uses the same algorithm as Wrap.wrap(); so, unifying these in one method, allowing ColorChain to specify that the output type should use ColorClaim, while Wrap is used by default, would be nice.

ColorChain doesn't detect Sledgehammer scenarios until it accounts for all possible solutions of the network

detection of sledgehammer scenarios can be expedited by prioritizing Facts that are shared by all the WhatIfs of a given Logic over those that are not shared among all the WhatIfs of that Logic so that when a WhatIf explores further possibilities, it will be much more likely to explore the possible states of the same Fact as its siblings in the same Logic.

When getting the smallest partially affected fact to act on, instead of sorting only by small-to-large, sort by small-to-large and then sort within that sort by popularity of the Fact.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.