lifebeyondfife / Decider

An Open Source .Net Constraint Programming Solver
MIT License
150 stars 21 forks source link

Extended syntax for ConstraintInteger's #24

Closed dlidstrom closed 5 years ago

dlidstrom commented 5 years ago

I was trying to model this riddle:

[?] [?] [?]
 6   8   2 One number is correct and well placed
 6   1   4 One number is correct but wrong placed
 7   8   0 One number is correct but wrong placed

I am using this as an example to learn more about this nice library. My first attempt goes something like this:

var validElements = new List<int>
{
    0, 1, 2, 4, 6, 7, 8,
};
var first = new VariableInteger("first", validElements);
var second = new VariableInteger("second", validElements);
var third = new VariableInteger("third", validElements);
var constraint1 = new ConstraintInteger(first == 6 && second != 8 && third != 2);

This is where I got stuck. The compiler complains about && above:

In order for 'ExpressionInteger.operator &(ExpressionInteger, ExpressionInteger)' to be applicable as a short circuit operator, its declaring type 'ExpressionInteger' must define operator true and operator false

Would it be useful to have these operators? CSP is very interesting. Would you be able to give some guidance on how to model the riddle? Thanks!

lifebeyondfife commented 5 years ago

Thanks for the query Daniel. The logical AND operator is available i.e. &, as opposed to &&. I could have overridden conditional AND if I'd overridden true and false but didn't want to go that far.

Check the operator precedence though, you may need to say ((x == 1) & (y != 3)) etc.

Hope this helps. If not give me another shout and I'll load your code myself and try to get it working.

On Mon, 2 Sep 2019, 17:10 Daniel Lidström, notifications@github.com wrote:

I was trying to model this riddle:

[?] [?] [?] 6 8 2 One number is correct and well placed 6 1 4 One number is correct but wrong placed 7 8 0 One number is correct but wrong placed

I am using this as an example to learn more about this nice library. My first attempt goes something like this:

var validElements = new List { 0, 1, 2, 4, 6, 7, 8, };var first = new VariableInteger("first", validElements);var second = new VariableInteger("second", validElements);var third = new VariableInteger("third", validElements);var constraint1 = new ConstraintInteger(first == 6 && second != 8 && third != 2);

This is where I got stuck. The compiler complains about && above:

In order for 'ExpressionInteger.operator &(ExpressionInteger, ExpressionInteger)' to be applicable as a short circuit operator, its declaring type 'ExpressionInteger' must define operator true and operator false

Would it be useful to have these operators? CSP is very interesting. Would you be able to give some guidance on how to model the riddle? Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/lifebeyondfife/Decider/issues/24?email_source=notifications&email_token=AAYNLMNWH4BR6UFIU3ACQYLQHU3IRA5CNFSM4IS63LJ2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HI2GP5A, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYNLMJVYQZFQYU2U2B2QL3QHU3IRANCNFSM4IS63LJQ .

dlidstrom commented 5 years ago

I got it working!

private static void Decide()
{
    /**
     * [?] [?] [?]
     * 6 8 2 One number is correct and well placed
     * 6 1 4 One number is correct but wrong placed
     * 7 8 0 One number is correct but wrong placed
     */
    var validElements = new List<int>
    {
        0, 1, 2, 4, 6, 7, 8,
    };
    var first = new VariableInteger("first", validElements);
    var second = new VariableInteger("second", validElements);
    var third = new VariableInteger("third", validElements);
    var constraint1 = new ConstraintInteger(
        ((first == 6) & (second != 8 & second != 2) & (third != 8 & third != 2)) // 6 is correct and well placed
        | ((first != 6 & first != 2) & (second == 8) & (third != 6 & third != 2)) // 8 is correct and well placed
        | ((first != 6 & first != 8) & (second != 6 & second != 8) & (third == 2))); // 2 is correct and well placed

    // one number is correct but wrong placed
    var constraint2 = new ConstraintInteger(
        (first == 1 | first == 4 | second == 6 | second == 4 | third == 6 | third == 1)
        & (first != 6 & second != 1 & third != 4));

    // one number is correct but wrong placed
    var constraint3 = new ConstraintInteger(
        (first == 8 | first == 0 | second == 7 | second == 0 | third == 7 | third == 8)
        & (first != 7 & second != 8 & third != 0));

    var constraints = new List<IConstraint>
        {
            constraint1, constraint2, constraint3,
        };

    var variables = new[] { first, second, third, };
    IState<int> state = new StateInteger(variables, constraints);

    state.StartSearch(out StateOperationResult searchResult);

    Console.WriteLine("Runtime:\t{0}\nBacktracks:\t{1}\n", state.Runtime, state.Backtracks);
    Console.WriteLine($"[{first}] [{second}] [{third}]");
}

It gives the (surprising to me) answer [1] [0] [2]. Thanks!

lifebeyondfife commented 5 years ago

Great to hear that you were able to get your problem encoded. Thanks for sharing.