Subversion Repositories wimsdev

Rev

Rev 8185 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8185 Rev 12248
Line 33... Line 33...
33
char *input;
33
char *input;
34
 
34
 
35
/* Print the result */
35
/* Print the result */
36
void printresult(char curr[])
36
void printresult(char curr[])
37
{
37
{
38
    int i,j;
38
  int i,j;
39
    char ch;
39
  char ch;
40
    for(i=0;i<linecnt;i++) {
40
  for(i=0;i<linecnt;i++) {
41
      for(j=0;j<charcnt[i];j++) {
41
    for(j=0;j<charcnt[i];j++) {
42
          ch=basetab[i][j];
42
      ch=basetab[i][j];
43
          if(ch==0) ch=' ';
43
      if(ch==0) ch=' ';
44
          else if(ch>='A' && ch<='Z') ch=curr[ch-'A'];
44
      else if(ch>='A' && ch<='Z') ch=curr[ch-'A'];
45
          printf(" %d",ch);
45
      printf(" %d",ch);
46
      }
-
 
47
      printf("\n");
-
 
48
    }
46
    }
49
    printf("\n");
47
    printf("\n");
-
 
48
  }
-
 
49
  printf("\n");
50
}
50
}
51
 
51
 
52
/* returns 1 if OK, 0 if bad. */
52
/* returns 1 if OK, 0 if bad. */
53
int putvalue(char ch, char k, char curr[], char currb[])
53
int putvalue(char ch, char k, char curr[], char currb[])
54
{
54
{
55
    int i=ch-'A';
55
  int i=ch-'A';
56
    if(ch==0) {
56
  if(ch==0) {
57
      if(k>0) return 0; else return 1;
57
    if(k>0) return 0; else return 1;
58
    }
58
  }
59
    if((curr[i]!=-1 && curr[i]!=k) || (currb[k]!=0 && currb[k]!=ch))
59
  if((curr[i]!=-1 && curr[i]!=k) || (currb[k]!=0 && currb[k]!=ch))
60
      return 0;
60
    return 0;
61
    curr[i]=k;currb[k]=ch; return 1;
61
  curr[i]=k;currb[k]=ch; return 1;
62
}
62
}
63
 
63
 
64
/* check that leading number is not 0. Returns 0 if bad. */
64
/* check that leading number is not 0. Returns 0 if bad. */
65
int checklead(char curr[])
65
int checklead(char curr[])
66
{
66
{
67
    int i;
67
  int i;
68
    char ch;
68
  char ch;
69
    for(i=0;i<linecnt;i++) {
69
  for(i=0;i<linecnt;i++) {
70
      ch=basetab[i][charcnt[i]-1];
70
    ch=basetab[i][charcnt[i]-1];
71
      if(curr[ch-'A']<=0) return 0;
71
    if(curr[ch-'A']<=0) return 0;
72
    }
72
  }
73
    return 1;
73
  return 1;
74
}
74
}
75
 
75
 
76
/* returns 0 if fail, 1 if OK. */
76
/* returns 0 if fail, 1 if OK. */
77
int colcompute(int c,char curr[],char currb[])
77
int colcompute(int c,char curr[],char currb[])
78
{
78
{
79
    int i,j,k,sum;
79
  int i,j,k,sum;
80
    char ch;
80
  char ch;
81
 
81
 
82
    switch(style[1]) {
82
  switch(style[1]) {
83
      case '-':
83
    case '-':
84
      case '+':
84
    case '+':
85
      case '.': {
85
    case '.': {
86
          for(j=sum=0;j<linecnt;j++) {
86
      for(j=sum=0;j<linecnt;j++) {
87
            if(!active[j]) continue;
87
        if(!active[j]) continue;
88
            ch=basetab[j][c];
88
        ch=basetab[j][c];
89
            if(ch!=0) {
89
        if(ch!=0) {
90
                if(style[j]!='-') sum+=curr[ch-'A'];
90
          if(style[j]!='-') sum+=curr[ch-'A'];
91
                else sum-=curr[ch-'A'];
91
          else sum-=curr[ch-'A'];
92
            }
92
        }
93
          }
93
      }
94
          lastline:
94
      lastline:
95
          sum+=carry[linecnt-1][c];
95
      sum+=carry[linecnt-1][c];
96
          carry[linecnt-1][c+1]=(sum+10000)/10-1000; k=(sum+10000)%10;
96
      carry[linecnt-1][c+1]=(sum+10000)/10-1000; k=(sum+10000)%10;
97
          return putvalue(basetab[linecnt-1][c],k,curr,currb);
97
      return putvalue(basetab[linecnt-1][c],k,curr,currb);
98
      }
98
    }
99
 
99
 
100
      case '*': {
100
    case '*': {
101
          char c1,c2;
101
      char c1,c2;
102
          c2=basetab[0][c];
102
      c2=basetab[0][c];
103
          if(c2!=0) c2=curr[c2-'A'];
103
      if(c2!=0) c2=curr[c2-'A'];
104
          for(i=0;i<c && i<linecnt-3;i++) {
104
      for(i=0;i<c && i<linecnt-3;i++) {
105
            c1=basetab[1][i];
105
        c1=basetab[1][i];
106
            if(c2*c1!=0) sum=c2*curr[c1-'A']+carry[2+i][c];
106
        if(c2*c1!=0) sum=c2*curr[c1-'A']+carry[2+i][c];
107
            else sum=carry[2+i][c];
107
        else sum=carry[2+i][c];
108
            carry[2+i][c+1]=sum/10;
108
        carry[2+i][c+1]=sum/10;
109
            if(!putvalue(basetab[2+i][c],sum%10,curr,currb))
109
        if(!putvalue(basetab[2+i][c],sum%10,curr,currb))
110
              return 0;
110
          return 0;
111
          }
111
      }
112
          c2=basetab[1][c];
112
      c2=basetab[1][c];
113
          if(c2!=0) {
113
      if(c2!=0) {
114
            c2=curr[c2-'A'];
114
        c2=curr[c2-'A'];
115
            for(i=0;i<=c;i++) {
115
        for(i=0;i<=c;i++) {
116
                c1=basetab[0][i];
116
          c1=basetab[0][i];
117
                if(c1==0) break;
117
          if(c1==0) break;
118
                sum=c2*curr[c1-'A']+carry[2+c][i];
118
          sum=c2*curr[c1-'A']+carry[2+c][i];
119
                carry[2+c][i+1]=sum/10;
119
          carry[2+c][i+1]=sum/10;
120
                if(!putvalue(basetab[2+c][i],sum%10,curr,currb))
120
          if(!putvalue(basetab[2+c][i],sum%10,curr,currb))
121
                  return 0;
121
            return 0;
122
            }
122
        }
123
          }
123
      }
124
          for(i=sum=0;i<=c && i<linecnt-3;i++) {
124
      for(i=sum=0;i<=c && i<linecnt-3;i++) {
125
            ch=basetab[2+i][c-i];
125
          ch=basetab[2+i][c-i];
126
            if(ch!=0) sum+=curr[ch-'A'];
126
          if(ch!=0) sum+=curr[ch-'A'];
127
          }
127
      }
128
          goto lastline;
128
      goto lastline;
129
      }
129
    }
130
 
130
 
131
/* short multiplication */
131
/* short multiplication */
132
      case '$': {
132
    case '$': {
133
          char c1,c2;
133
      char c1,c2;
134
          for(j=sum=0;j<=c;j++) {
134
      for(j=sum=0;j<=c;j++) {
135
            c1=basetab[0][j]; c2=basetab[1][c-j];
135
        c1=basetab[0][j]; c2=basetab[1][c-j];
136
            if(c1==0) break;
136
        if(c1==0) break;
137
            if(c2==0) continue;
137
        if(c2==0) continue;
138
            sum+=curr[c1-'A']*curr[c2-'A'];
138
        sum+=curr[c1-'A']*curr[c2-'A'];
139
          }
139
      }
140
          goto lastline;
140
      goto lastline;
141
      }
141
    }
142
 
-
 
143
 
142
 
144
      default: return 0;
143
    default: return 0;
145
    }
144
  }
146
}
145
}
147
 
146
 
148
void column(int c, char prev[], char prevb[])
147
void column(int c, char prev[], char prevb[])
149
{
148
{
150
    char curr[32], currb[16];
149
  char curr[32], currb[16];
151
    int lreg[MAX_LINES],lfix[MAX_LINES];
150
  int lreg[MAX_LINES],lfix[MAX_LINES];
152
    int i,j,icarry;
151
  int i,j,icarry;
153
    char ch;
152
  char ch;
154
 
153
 
155
    memset(lreg,0,sizeof(lreg));
154
  memset(lreg,0,sizeof(lreg));
156
    memset(lfix,0,sizeof(lfix));
155
  memset(lfix,0,sizeof(lfix));
157
 
156
 
-
 
157
  for(i=0;i<linecnt;i++) {
-
 
158
    if(!active[i]) continue;
-
 
159
    ch=basetab[i][c];
-
 
160
    if(ch==0 || prev[ch-'A']!=-1) lfix[i]=1;
-
 
161
  }
-
 
162
  for(icarry=0;;icarry=1) {
-
 
163
    memmove(curr,prev,sizeof(curr));
-
 
164
    memmove(currb,prevb,sizeof(currb));
-
 
165
    for(i=0;i<linecnt;i++) {
-
 
166
      if(!active[i] || lfix[i]) continue;
-
 
167
      for(j=lreg[i]+icarry;j<10 && prevb[j]!=0;j++);
-
 
168
      if(j>=10) {
-
 
169
        for(j=0;j<10 && prevb[j]!=0;j++);
-
 
170
        if(j>=10) return;
-
 
171
        icarry=1;
-
 
172
      }
-
 
173
      else icarry=0;
-
 
174
      lreg[i]=j;
-
 
175
    }
-
 
176
    if(icarry) break;
158
    for(i=0;i<linecnt;i++) {
177
    for(i=0;i<linecnt;i++) {
159
      if(!active[i]) continue;
178
      if(!active[i] || lfix[i]) continue;
160
      ch=basetab[i][c];
-
 
161
      if(ch==0 || prev[ch-'A']!=-1) lfix[i]=1;
179
      if(!putvalue(basetab[i][c],lreg[i],curr,currb)) goto loopend;
162
    }
180
    }
163
    for(icarry=0;;icarry=1) {
181
    if(!colcompute(c,curr,currb)) continue;
164
      memmove(curr,prev,sizeof(curr));
182
    if(c<activelen-1) column(c+1,curr,currb);
-
 
183
    else {
-
 
184
      for(i=activelen;i<maxlen;i++) {
165
      memmove(currb,prevb,sizeof(currb));
185
        if(!colcompute(i,curr,currb)) goto loopend;
-
 
186
      }
166
      for(i=0;i<linecnt;i++) {
187
      for(i=0;i<linecnt;i++) {
167
          if(!active[i] || lfix[i]) continue;
-
 
168
          for(j=lreg[i]+icarry;j<10 && prevb[j]!=0;j++);
-
 
169
          if(j>=10) {
-
 
170
            for(j=0;j<10 && prevb[j]!=0;j++);
-
 
171
            if(j>=10) return;
-
 
172
            icarry=1;
-
 
173
          }
-
 
174
          else icarry=0;
-
 
175
          lreg[i]=j;
-
 
176
      }
-
 
177
      if(icarry) break;
-
 
178
      for(i=0;i<linecnt;i++) {
-
 
179
          if(!active[i] || lfix[i]) continue;
-
 
180
          if(!putvalue(basetab[i][c],lreg[i],curr,currb)) goto loopend;
-
 
181
      }
-
 
182
      if(!colcompute(c,curr,currb)) continue;
-
 
183
      if(c<activelen-1) column(c+1,curr,currb);
-
 
184
      else {
-
 
185
          for(i=activelen;i<maxlen;i++) {
-
 
186
            if(!colcompute(i,curr,currb)) goto loopend;
-
 
187
          }
-
 
188
          for(i=0;i<linecnt;i++) {
-
 
189
            if(active[i]) continue;
188
        if(active[i]) continue;
190
            if(carry[i][maxlen]) goto loopend;
189
        if(carry[i][maxlen]) goto loopend;
191
          }
-
 
192
          if(!checklead(curr)) goto loopend;
-
 
193
          total++;
-
 
194
          printresult(curr);
-
 
195
      }
190
      }
-
 
191
      if(!checklead(curr)) goto loopend;
196
      loopend:
192
      total++;
-
 
193
      printresult(curr);
197
    }
194
    }
-
 
195
    loopend:
-
 
196
  }
198
}
197
}
199
 
198
 
200
int main(int argc, char *argv[])
199
int main(int argc, char *argv[])
201
{
200
{
202
    char *p,*p2,*p3;
201
  char *p,*p2,*p3;
203
    int i;
202
  int i;
204
    input=getenv("wims_exec_parm");
203
  input=getenv("wims_exec_parm");
205
/* nothing to do if no problem */
204
/* nothing to do if no problem */
206
    if(input==NULL || *input==0) return 0;
205
  if(input==NULL || *input==0) return 0;
207
 
206
 
208
    memset(basetab,0,sizeof(basetab));
207
  memset(basetab,0,sizeof(basetab));
209
    memset(corresp,-1,sizeof(corresp));
208
  memset(corresp,-1,sizeof(corresp));
210
    memset(bcorresp,0,sizeof(bcorresp));
209
  memset(bcorresp,0,sizeof(bcorresp));
211
    memset(carry,0,sizeof(carry));
210
  memset(carry,0,sizeof(carry));
212
    memset(active,0,sizeof(active));
211
  memset(active,0,sizeof(active));
213
 
212
 
214
    for(p=input+strlen(input);p>input && isspace(*(p-1));p--);
213
  for(p=input+strlen(input);p>input && isspace(*(p-1));p--);
215
    *p=0;
214
  *p=0;
216
    activelen=maxlen=0;
215
  activelen=maxlen=0;
217
    active[0]=active[1]=1;
216
  active[0]=active[1]=1;
218
    for(linecnt=0,p=input;*p!=0 && linecnt<MAX_LINES;p=p3) {
217
  for(linecnt=0,p=input;*p!=0 && linecnt<MAX_LINES;p=p3) {
219
      p2=strchr(p,'\n');
218
    p2=strchr(p,'\n');
220
      if(p2==NULL) {
219
    if(p2==NULL) {
221
          p2=p+strlen(p);p3=p2;
220
      p2=p+strlen(p);p3=p2;
222
      }
221
    }
223
      else p3=p2+1;
222
    else p3=p2+1;
-
 
223
    while(isspace(*p)) p++;
-
 
224
    if(strchr("+-*/=.",*p)!=NULL) {
-
 
225
      style[linecnt]=*p;p++;
224
      while(isspace(*p)) p++;
226
      while(isspace(*p)) p++;
225
      if(strchr("+-*/=.",*p)!=NULL) {
-
 
226
          style[linecnt]=*p;p++;
-
 
227
          while(isspace(*p)) p++;
-
 
228
      }
227
    }
229
      else style[linecnt]='+';
228
    else style[linecnt]='+';
230
      if(*p3==0) style[linecnt]='=';
229
    if(*p3==0) style[linecnt]='=';
231
      if(linecnt>1) {
230
    if(linecnt>1) {
232
          switch(style[1]) {
231
     switch(style[1]) {
233
            case '+':
232
       case '+':
234
            case '-': {
233
       case '-': {
235
                if(*p3!=0) active[linecnt]=1;
234
        if(*p3!=0) active[linecnt]=1;
236
                break;
235
        break;
237
            }
236
       }
238
 
237
 
239
            case '*':
238
       case '*':
240
            case '/':
239
       case '/':
241
            case '=':
240
       case '=':
242
            break;
241
       break;
243
          }
242
    }
244
      }
243
  }
245
      while(p2>p && isspace(*(p2-1))) p2--;
244
  while(p2>p && isspace(*(p2-1))) p2--;
246
      if(p2>p+MAX_CHARS) p2=p+MAX_CHARS;
245
  if(p2>p+MAX_CHARS) p2=p+MAX_CHARS;
247
      *p2=0;
246
  *p2=0;
248
      if(p2<=p) continue;
247
  if(p2<=p) continue;
249
      for(i=0;i<p2-p;i++) {
248
  for(i=0;i<p2-p;i++) {
250
          char ch;
249
    char ch;
251
          ch=toupper(*(p2-i-1));
250
    ch=toupper(*(p2-i-1));
252
/* bad char */
251
/* bad char */
253
          if(ch<'A' || ch>'Z') return 1;
252
    if(ch<'A' || ch>'Z') return 1;
254
          basetab[linecnt][i]=ch;
253
      basetab[linecnt][i]=ch;
255
      }
254
    }
256
      charcnt[linecnt]=p2-p;
255
    charcnt[linecnt]=p2-p;
257
      if(active[linecnt] && p2-p>activelen) activelen=p2-p;
256
    if(active[linecnt] && p2-p>activelen) activelen=p2-p;
258
      if(p2-p>maxlen) maxlen=p2-p;
257
    if(p2-p>maxlen) maxlen=p2-p;
259
      linecnt++;
258
    linecnt++;
260
    }
259
  }
261
/* multiplication */
260
/* multiplication */
262
    if(style[1]=='*') {
261
  if(style[1]=='*') {
263
      if(linecnt==3) style[1]='$';
262
    if(linecnt==3) style[1]='$';
264
      else {
263
    else {
265
          if(linecnt!=charcnt[1]+3) return 1;
264
      if(linecnt!=charcnt[1]+3) return 1;
266
          for(i=3;i<linecnt-1;i++)
265
    for(i=3;i<linecnt-1;i++)
267
            if(charcnt[i]+i-2>maxlen) maxlen=charcnt[i]+i-2;
266
      if(charcnt[i]+i-2>maxlen) maxlen=charcnt[i]+i-2;
268
      }
-
 
269
    }
267
    }
-
 
268
  }
270
 
269
 
271
    column(0,corresp,bcorresp);
270
  column(0,corresp,bcorresp);
272
printf("\n!total %d solution(s).\n\n",total);
271
  printf("\n!total %d solution(s).\n\n",total);
273
    return 0;
272
  return 0;
274
}
273
}
275
 
-