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 |
|
38 | int i,j; |
39 |
|
39 | char ch; |
40 |
|
40 | for(i=0;i<linecnt;i++) { |
41 |
|
41 | for(j=0;j<charcnt[i];j++) { |
42 |
|
42 | ch=basetab[i][j]; |
43 |
|
43 | if(ch==0) ch=' '; |
44 |
|
44 | else if(ch>='A' && ch<='Z') ch=curr[ch-'A']; |
45 |
|
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 |
|
55 | int i=ch-'A'; |
56 |
|
56 | if(ch==0) { |
57 |
|
57 | if(k>0) return 0; else return 1; |
58 |
|
58 | } |
59 |
|
59 | if((curr[i]!=-1 && curr[i]!=k) || (currb[k]!=0 && currb[k]!=ch)) |
60 |
|
60 | return 0; |
61 |
|
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 |
|
67 | int i; |
68 |
|
68 | char ch; |
69 |
|
69 | for(i=0;i<linecnt;i++) { |
70 |
|
70 | ch=basetab[i][charcnt[i]-1]; |
71 |
|
71 | if(curr[ch-'A']<=0) return 0; |
72 |
|
72 | } |
73 |
|
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 |
|
79 | int i,j,k,sum; |
80 |
|
80 | char ch; |
81 | 81 | ||
82 |
|
82 | switch(style[1]) { |
83 |
|
83 | case '-': |
84 |
|
84 | case '+': |
85 |
|
85 | case '.': { |
86 |
|
86 | for(j=sum=0;j<linecnt;j++) { |
87 |
|
87 | if(!active[j]) continue; |
88 |
|
88 | ch=basetab[j][c]; |
89 |
|
89 | if(ch!=0) { |
90 |
|
90 | if(style[j]!='-') sum+=curr[ch-'A']; |
91 |
|
91 | else sum-=curr[ch-'A']; |
92 |
|
92 | } |
93 |
|
93 | } |
94 |
|
94 | lastline: |
95 |
|
95 | sum+=carry[linecnt-1][c]; |
96 |
|
96 | carry[linecnt-1][c+1]=(sum+10000)/10-1000; k=(sum+10000)%10; |
97 |
|
97 | return putvalue(basetab[linecnt-1][c],k,curr,currb); |
98 |
|
98 | } |
99 | 99 | ||
100 |
|
100 | case '*': { |
101 |
|
101 | char c1,c2; |
102 |
|
102 | c2=basetab[0][c]; |
103 |
|
103 | if(c2!=0) c2=curr[c2-'A']; |
104 |
|
104 | for(i=0;i<c && i<linecnt-3;i++) { |
105 |
|
105 | c1=basetab[1][i]; |
106 |
|
106 | if(c2*c1!=0) sum=c2*curr[c1-'A']+carry[2+i][c]; |
107 |
|
107 | else sum=carry[2+i][c]; |
108 |
|
108 | carry[2+i][c+1]=sum/10; |
109 |
|
109 | if(!putvalue(basetab[2+i][c],sum%10,curr,currb)) |
110 |
|
110 | return 0; |
111 |
|
111 | } |
112 |
|
112 | c2=basetab[1][c]; |
113 |
|
113 | if(c2!=0) { |
114 |
|
114 | c2=curr[c2-'A']; |
115 |
|
115 | for(i=0;i<=c;i++) { |
116 |
|
116 | c1=basetab[0][i]; |
117 |
|
117 | if(c1==0) break; |
118 |
|
118 | sum=c2*curr[c1-'A']+carry[2+c][i]; |
119 |
|
119 | carry[2+c][i+1]=sum/10; |
120 |
|
120 | if(!putvalue(basetab[2+c][i],sum%10,curr,currb)) |
121 |
|
121 | return 0; |
122 |
|
122 | } |
123 |
|
123 | } |
124 |
|
124 | for(i=sum=0;i<=c && i<linecnt-3;i++) { |
125 |
|
125 | ch=basetab[2+i][c-i]; |
126 |
|
126 | if(ch!=0) sum+=curr[ch-'A']; |
127 |
|
127 | } |
128 |
|
128 | goto lastline; |
129 |
|
129 | } |
130 | 130 | ||
131 | /* short multiplication */ |
131 | /* short multiplication */ |
132 |
|
132 | case '$': { |
133 |
|
133 | char c1,c2; |
134 |
|
134 | for(j=sum=0;j<=c;j++) { |
135 |
|
135 | c1=basetab[0][j]; c2=basetab[1][c-j]; |
136 |
|
136 | if(c1==0) break; |
137 |
|
137 | if(c2==0) continue; |
138 |
|
138 | sum+=curr[c1-'A']*curr[c2-'A']; |
139 |
|
139 | } |
140 |
|
140 | goto lastline; |
141 |
|
141 | } |
142 | - | ||
143 | 142 | ||
144 |
|
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 |
|
149 | char curr[32], currb[16]; |
151 |
|
150 | int lreg[MAX_LINES],lfix[MAX_LINES]; |
152 |
|
151 | int i,j,icarry; |
153 |
|
152 | char ch; |
154 | 153 | ||
155 |
|
154 | memset(lreg,0,sizeof(lreg)); |
156 |
|
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( |
179 | if(!putvalue(basetab[i][c],lreg[i],curr,currb)) goto loopend; |
162 | } |
180 | } |
163 |
|
181 | if(!colcompute(c,curr,currb)) continue; |
164 |
|
182 | if(c<activelen-1) column(c+1,curr,currb); |
- | 183 | else { |
|
- | 184 | for(i=activelen;i<maxlen;i++) { |
|
165 |
|
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 |
|
188 | if(active[i]) continue; |
190 |
|
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 |
|
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 |
|
201 | char *p,*p2,*p3; |
203 |
|
202 | int i; |
204 |
|
203 | input=getenv("wims_exec_parm"); |
205 | /* nothing to do if no problem */ |
204 | /* nothing to do if no problem */ |
206 |
|
205 | if(input==NULL || *input==0) return 0; |
207 | 206 | ||
208 |
|
207 | memset(basetab,0,sizeof(basetab)); |
209 |
|
208 | memset(corresp,-1,sizeof(corresp)); |
210 |
|
209 | memset(bcorresp,0,sizeof(bcorresp)); |
211 |
|
210 | memset(carry,0,sizeof(carry)); |
212 |
|
211 | memset(active,0,sizeof(active)); |
213 | 212 | ||
214 |
|
213 | for(p=input+strlen(input);p>input && isspace(*(p-1));p--); |
215 |
|
214 | *p=0; |
216 |
|
215 | activelen=maxlen=0; |
217 |
|
216 | active[0]=active[1]=1; |
218 |
|
217 | for(linecnt=0,p=input;*p!=0 && linecnt<MAX_LINES;p=p3) { |
219 |
|
218 | p2=strchr(p,'\n'); |
220 |
|
219 | if(p2==NULL) { |
221 |
|
220 | p2=p+strlen(p);p3=p2; |
222 |
|
221 | } |
223 |
|
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 |
|
228 | else style[linecnt]='+'; |
230 |
|
229 | if(*p3==0) style[linecnt]='='; |
231 |
|
230 | if(linecnt>1) { |
232 |
|
231 | switch(style[1]) { |
233 |
|
232 | case '+': |
234 |
|
233 | case '-': { |
235 |
|
234 | if(*p3!=0) active[linecnt]=1; |
236 |
|
235 | break; |
237 |
|
236 | } |
238 | 237 | ||
239 |
|
238 | case '*': |
240 |
|
239 | case '/': |
241 |
|
240 | case '=': |
242 |
|
241 | break; |
243 |
|
242 | } |
244 |
|
243 | } |
245 |
|
244 | while(p2>p && isspace(*(p2-1))) p2--; |
246 |
|
245 | if(p2>p+MAX_CHARS) p2=p+MAX_CHARS; |
247 |
|
246 | *p2=0; |
248 |
|
247 | if(p2<=p) continue; |
249 |
|
248 | for(i=0;i<p2-p;i++) { |
250 |
|
249 | char ch; |
251 |
|
250 | ch=toupper(*(p2-i-1)); |
252 | /* bad char */ |
251 | /* bad char */ |
253 |
|
252 | if(ch<'A' || ch>'Z') return 1; |
254 |
|
253 | basetab[linecnt][i]=ch; |
255 |
|
254 | } |
256 |
|
255 | charcnt[linecnt]=p2-p; |
257 |
|
256 | if(active[linecnt] && p2-p>activelen) activelen=p2-p; |
258 |
|
257 | if(p2-p>maxlen) maxlen=p2-p; |
259 |
|
258 | linecnt++; |
260 |
|
259 | } |
261 | /* multiplication */ |
260 | /* multiplication */ |
262 |
|
261 | if(style[1]=='*') { |
263 |
|
262 | if(linecnt==3) style[1]='$'; |
264 |
|
263 | else { |
265 |
|
264 | if(linecnt!=charcnt[1]+3) return 1; |
266 |
|
265 | for(i=3;i<linecnt-1;i++) |
267 |
|
266 | if(charcnt[i]+i-2>maxlen) maxlen=charcnt[i]+i-2; |
268 | } |
- | |
269 | } |
267 | } |
- | 268 | } |
|
270 | 269 | ||
271 |
|
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 |
|
272 | return 0; |
274 | } |
273 | } |
275 | - |