diff --git a/pom.xml b/pom.xml index 9aac22c..3d72263 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ org.choco-solver choco-solver - 4.10.6 + 4.10.10 guru.nidi diff --git a/src/test/java/cryptator/Failing.java b/src/test/java/cryptator/Failing.java index 2cf2a66..63a093a 100644 --- a/src/test/java/cryptator/Failing.java +++ b/src/test/java/cryptator/Failing.java @@ -75,4 +75,15 @@ public void testExpression2() { assertTrue(true); } + @Test + public void testPrinterError2() throws CryptaParserException, CryptaModelException, CryptaSolverException { + // https://mathworld.wolfram.com/PrintersErrors.html + t.testUNIQUE("3^4*425 = 34425"); + } + + @Test + public void testBarker4() throws CryptaParserException, CryptaModelException, CryptaSolverException { + t.testUNIQUE("copper*neon=iron*silver"); + } + } diff --git a/src/test/java/cryptator/ProductTest.java b/src/test/java/cryptator/ProductTest.java new file mode 100644 index 0000000..e57c762 --- /dev/null +++ b/src/test/java/cryptator/ProductTest.java @@ -0,0 +1,108 @@ +/** + * This file is part of cryptator, https://github.com/arnaud-m/cryptator + * + * Copyright (c) 2022, Université Côte d'Azur. All rights reserved. + * + * Licensed under the BSD 3-clause license. + * See LICENSE file in the project root for full license information. + */ +package cryptator; + +import org.chocosolver.solver.Model; +import org.chocosolver.solver.Solver; +import org.chocosolver.solver.variables.IntVar; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class ProductTest { + + private Model model; + private IntVar copper, neon, iron, silver, result; + + @Before + /*** + * Tests if choco can solve "copper*neon=iron*silver" via various way of writing constraints + */ + public void setup(){ + model = new Model("copper*neon=iron*silver"); + copper = model.intVar("copper",100000,999999); + neon = model.intVar("neon",1000,9999); + iron = model.intVar("iron",1000,9999); + silver = model.intVar("silver",100000,999999); + model.allDifferent(new IntVar[]{copper,neon,iron,silver}).post(); + } + + public void setupResult(int factor) { + //result is an intermediary to compare copper*neon and iron*silver + //all test would fail if factor = 1. + result = model.intVar("result",0, factor * IntVar.MAX_INT_BOUND); + } + + public void solve(int solutionCount) { + Solver solver = model.getSolver(); + System.out.println(model); + solver.printVersion(); + solver.showStatistics(); + solver.showSolutions(); + solver.findSolution(); + Assert.assertEquals(solutionCount, solver.getSolutionCount()); + } + + + @Test + /*** + * Using times directly to make our constraint + * will fail to find any solution because value needed is greater than the result's upper bound. + */ + public void model1NoSol(){ + setupResult(1); + model.times(copper, neon, result).post(); + model.times(silver, iron, result).post(); + solve(0); + } + + @Test + @Ignore + /*** + * Working version of the previous test. + */ + public void model1(){ + setupResult(10); + model.times(copper, neon, result).post(); + model.times(silver, iron, result).post(); + solve(1); + } + @Test + @Ignore + /*** + * Creating a model using arithm instead of times directly. + */ + public void model2(){ + setupResult(10); + model.arithm(copper, "*",neon,"=",result).post(); + model.arithm(iron, "*",silver,"=",result).post(); + solve(1); + } + @Test + @Ignore + /*** + * Creating a model using the operators function given by IntVar + */ + public void model3(){ + setupResult(10); + copper.mul(neon).eq(result).post(); + iron.mul(silver).eq(result).post(); + solve(1); + } + @Test + @Ignore + /*** + * Creating a model using the operators function given by IntVar without using result as an intermediary + */ + public void model4(){ + copper.mul(neon).eq(iron.mul(silver)).post(); + solve(1); + } +} \ No newline at end of file diff --git a/src/test/java/cryptator/SolverTest.java b/src/test/java/cryptator/SolverTest.java index 526ea68..9bff07e 100644 --- a/src/test/java/cryptator/SolverTest.java +++ b/src/test/java/cryptator/SolverTest.java @@ -358,10 +358,7 @@ public void testBarker3() throws CryptaParserException, CryptaModelException, Cr t.testUNIQUE("pear+plum+apple+grape+lemon=orange"); } - @Test - public void testBarker4() throws CryptaParserException, CryptaModelException, CryptaSolverException { - t.testUNIQUE("copper*neon=iron*silver"); - } + @Test public void testBarker5() throws CryptaParserException, CryptaModelException, CryptaSolverException { @@ -386,11 +383,7 @@ public void testPow1() throws CryptaParserException, CryptaModelException, Crypt t.testSAT("A = B ^ C", 2); } - @Test - public void testPrinterError2() throws CryptaParserException, CryptaModelException, CryptaSolverException { - // https://mathworld.wolfram.com/PrintersErrors.html - t.testUNIQUE("3^4*425 = 34425"); - } + @Test public void testDivision1() throws CryptaParserException, CryptaModelException, CryptaSolverException { diff --git a/src/test/resources/cryptarithms-barker.txt b/src/test/resources/cryptarithms-barker.txt index 12905f7..b5384a2 100644 --- a/src/test/resources/cryptarithms-barker.txt +++ b/src/test/resources/cryptarithms-barker.txt @@ -95,7 +95,7 @@ gold*iron=lead*tin gold*neon=lead*zinc ## FIXME iron*radium=neon*sodium argon*tin=iron*zinc -copper*neon=iron*silver +## FIXME copper*neon=iron*silver ## Colours of the Rainbow green+violet=indigo red+green+orange=yellow