2020
2121public class CryptaGenModel extends WordsListModel {
2222
23- private final ICryptaGenModel left ;
23+ //private final ICryptaGenModel left;
24+ //private final CryptaMemberScalar left;
25+ private final CryptaMemberLen left ;
2426
2527 private final ICryptaGenModel right ;
2628
27- public CryptaGenModel (String [] words ) {
29+ public CryptaGenModel (String [] words , boolean lenOrCardModel ) {
2830 super (new Model ("Generate" ), words );
29- //left = new CryptaMemberScalar(model, words, "L_");
30- left = new CryptaMemberScalar (model , words , "L_" );
31- //right = new CryptaMemberScalar(model, words, "R_");
32- right = new CryptaMemberScalar (model , words , "R_" );
31+ left = lenOrCardModel ? new CryptaMemberLen (model , words , "L_" ) : new CryptaMemberCard (model , words , "L_" );
32+ right = new CryptaMemberElt (model , words , "R_" );
3333 this .buildModel ();
34- // model.getSolver().showDecisions();
35- // model.getSolver().limitNode(20);
36-
3734 }
3835
3936
@@ -42,86 +39,88 @@ public void buildModel() {
4239 super .buildModel ();
4340 left .buildModel ();
4441 right .buildModel ();
45- postLeftOrRightMemberConstraints ();
46- postMemberMaxLenConstraint ();
42+ postLeftOrRightConstraints ();
43+ postSymBreakLengthLenConstraint ();
4744 }
48-
4945
50- private void postLeftOrRightMemberConstraints () {
46+
47+ @ Override
48+ protected void postMaxLengthConstraints () {
49+ model .max (maxLength , left .getMaxLength (), right .getMaxLength ()).post ();
50+ }
51+
52+
53+ private void postLeftOrRightConstraints () {
5154 final BoolVar [] l = left .getWordVars ();
5255 final BoolVar [] r = right .getWordVars ();
5356 for (int i = 0 ; i < vwords .length ; i ++) {
5457 l [i ].add (r [i ]).eq (vwords [i ]).post ();
5558 }
5659 }
5760
58-
59- private void postMemberMaxLenConstraint () {
60- right .getMaxLength ().ge ( left .getMaxLength ()). post ( );
61-
61+
62+ private void postSymBreakLengthLenConstraint () {
63+ left .getMaxLength ().le ( right .getMaxLength ());
64+
6265 }
6366
64- public void postMemberCardConstraints (int min , int max ) {
65- if (min > 1 ) left .getWordCount ().ge (min ).post ();
66- else left .getWordCount ().ge (2 ).post ();
67- // FIXMW why ?
67+ public void postLeftCountConstraints (int min , int max ) {
68+ min = Math .max (min , 2 );
69+ left .getWordCount ().ge (min ).post ();
6870 if (max >= min ) left .getWordCount ().le (max ).post ();
69-
70- // TODO Option to relax the constraint (allow subtractions in the bignum model)
71- // Would need to break reflexion symmetry
72- right .getWordCount ().eq (1 ).post ();
71+
7372 }
74-
75- public void postLeftMinCardConstraints (int base ) {
76- IntVar diff = right .getMaxLength ().sub (left .getMaxLength ()).intVar ();
77- final int n = getN ();
73+
74+ public static void postMinLeftCountConstraints (int maxWordCount , IntVar leftCount , IntVar leftMaxLen ,IntVar rightMaxLen , int base ) {
75+ IntVar diff = rightMaxLen .sub (leftMaxLen ).intVar ();
7876 int prod = base ;
7977 int i = 2 ;
80- while (prod <= n ) {
81- diff .ge (i ).imp (left . getWordCount (). ge (prod )).post ();
78+ while (prod <= maxWordCount ) {
79+ diff .ge (i ).imp (leftCount . ge (prod + 1 )).post ();
8280 prod *= base ;
8381 i ++;
8482 }
8583 diff .lt (i ).post ();
8684 }
87-
88- public void postRightMemberConstraint () {
85+
86+ public void postMinLeftCountConstraints (int base ) {
87+ left .postLentghSumConstraints (right .getMaxLength (), base );
88+ }
89+
90+ public void postFixedRightMemberConstraint () {
8991 final BoolVar [] vars = right .getWordVars ();
9092 vars [vars .length - 1 ].eq (1 ).post ();
9193 }
9294
9395 public void postDoublyTrueConstraint (int lb ) {
9496 final int n = getN ();
9597 final IntVar sum = model .intVar ("SUM" , lb , n - 1 );
96-
98+
9799 final IntVar [] lvars = new IntVar [n +1 ];
98100 System .arraycopy (left .getWordVars (), 0 , lvars , 0 , n );
99101 lvars [n ] = sum ;
100-
102+
101103 final IntVar [] rvars = new IntVar [n +1 ];
102104 System .arraycopy (right .getWordVars (), 0 , rvars , 0 , n );
103105 rvars [n ] = sum ;
104-
106+
105107 final int [] coeffs = ArrayUtils .array (0 , n );
106108 coeffs [n ] = -1 ;
107-
109+
108110 model .scalar (lvars , coeffs , "=" , 0 ).post ();
109111 model .scalar (rvars , coeffs , "=" , 0 ).post ();
110112 }
111113
112- public final ICryptaNode recordCryptarithm () {
113- // TODO Check that members are non-null.
114- return new CryptaNode (CryptaOperator .EQ , recordAddition (left ), recordAddition (right ));
114+ public final ICryptaNode recordCryptarithm () {
115+ final ICryptaNode l = recordAddition (left );
116+ final ICryptaNode r = recordAddition (right );
117+ return r == null || l == null ? null : new CryptaNode (CryptaOperator .EQ , l , r );
115118 }
116119
117120
118121 @ Override
119122 public String toString () {
120123 return left .toString () + " = " + right .toString ();
121124 }
122-
123-
124-
125-
126125
127126}
0 commit comments