Rev 10 | Rev 8185 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 10 | Rev 7676 | ||
---|---|---|---|
Line 30... | Line 30... | ||
30 | int style[MAX_LINES]; |
30 | int style[MAX_LINES]; |
31 | int total=0; |
31 | int total=0; |
32 | 32 | ||
33 | char *input; |
33 | char *input; |
34 | 34 | ||
35 |
|
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 |
|
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 |
|
46 | } |
47 |
|
47 | printf("\n"); |
48 | } |
48 | } |
49 | printf("\n"); |
49 | printf("\n"); |
50 | } |
50 | } |
51 | 51 | ||
52 |
|
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 |
|
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 |
|
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 |
|
70 | ch=basetab[i][charcnt[i]-1]; |
71 |
|
71 | if(curr[ch-'A']<=0) return 0; |
72 | } |
72 | } |
73 | return 1; |
73 | return 1; |
74 | } |
74 | } |
75 | 75 | ||
76 |
|
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 |
|
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 |
|
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 | 142 | ||
143 | 143 | ||
144 |
|
144 | default: return 0; |
145 | } |
145 | } |
146 | } |
146 | } |
147 | 147 | ||
148 | void column(int c, char prev[], char prevb[]) |
148 | void column(int c, char prev[], char prevb[]) |
149 | { |
149 | { |
150 | char curr[32], currb[16]; |
150 | char curr[32], currb[16]; |
151 | int lreg[MAX_LINES],lfix[MAX_LINES]; |
151 | int lreg[MAX_LINES],lfix[MAX_LINES]; |
152 | int i,j,icarry; |
152 | int i,j,icarry; |
153 | char ch; |
153 | char ch; |
154 | 154 | ||
155 | memset(lreg,0,sizeof(lreg)); |
155 | memset(lreg,0,sizeof(lreg)); |
156 | memset(lfix,0,sizeof(lfix)); |
156 | memset(lfix,0,sizeof(lfix)); |
157 | 157 | ||
158 | for(i=0;i<linecnt;i++) { |
158 | for(i=0;i<linecnt;i++) { |
159 |
|
159 | if(!active[i]) continue; |
160 |
|
160 | ch=basetab[i][c]; |
161 |
|
161 | if(ch==0 || prev[ch-'A']!=-1) lfix[i]=1; |
162 | } |
162 | } |
163 | for(icarry=0;;icarry=1) { |
163 | for(icarry=0;;icarry=1) { |
164 |
|
164 | memmove(curr,prev,sizeof(curr)); |
165 |
|
165 | memmove(currb,prevb,sizeof(currb)); |
166 |
|
166 | for(i=0;i<linecnt;i++) { |
167 |
|
167 | if(!active[i] || lfix[i]) continue; |
168 |
|
168 | for(j=lreg[i]+icarry;j<10 && prevb[j]!=0;j++); |
169 |
|
169 | if(j>=10) { |
170 |
|
170 | for(j=0;j<10 && prevb[j]!=0;j++); |
171 |
|
171 | if(j>=10) return; |
172 |
|
172 | icarry=1; |
173 |
|
173 | } |
174 |
|
174 | else icarry=0; |
175 |
|
175 | lreg[i]=j; |
176 |
|
176 | } |
177 |
|
177 | if(icarry) break; |
178 |
|
178 | for(i=0;i<linecnt;i++) { |
179 |
|
179 | if(!active[i] || lfix[i]) continue; |
180 |
|
180 | if(!putvalue(basetab[i][c],lreg[i],curr,currb)) goto loopend; |
181 |
|
181 | } |
182 |
|
182 | if(!colcompute(c,curr,currb)) continue; |
183 |
|
183 | if(c<activelen-1) column(c+1,curr,currb); |
184 |
|
184 | else { |
185 |
|
185 | for(i=activelen;i<maxlen;i++) { |
186 |
|
186 | if(!colcompute(i,curr,currb)) goto loopend; |
187 |
|
187 | } |
188 |
|
188 | for(i=0;i<linecnt;i++) { |
189 |
|
189 | if(active[i]) continue; |
190 |
|
190 | if(carry[i][maxlen]) goto loopend; |
191 |
|
191 | } |
192 |
|
192 | if(!checklead(curr)) goto loopend; |
193 |
|
193 | total++; |
194 |
|
194 | printresult(curr); |
195 |
|
195 | } |
196 |
|
196 | loopend: |
197 | } |
197 | } |
198 | } |
198 | } |
199 | 199 | ||
200 | int main(int argc, char *argv[]) |
200 | int main(int argc, char *argv[]) |
201 | { |
201 | { |
202 | char *p,*p2,*p3; |
202 | char *p,*p2,*p3; |
203 | int i; |
203 | int i; |
204 | input=getenv("wims_exec_parm"); |
204 | input=getenv("wims_exec_parm"); |
205 |
|
205 | /* nothing to do if no problem */ |
206 | if(input==NULL || *input==0) return 0; |
206 | if(input==NULL || *input==0) return 0; |
207 | 207 | ||
208 | memset(basetab,0,sizeof(basetab)); |
208 | memset(basetab,0,sizeof(basetab)); |
209 | memset(corresp,-1,sizeof(corresp)); |
209 | memset(corresp,-1,sizeof(corresp)); |
210 | memset(bcorresp,0,sizeof(bcorresp)); |
210 | memset(bcorresp,0,sizeof(bcorresp)); |
Line 214... | Line 214... | ||
214 | for(p=input+strlen(input);p>input && isspace(*(p-1));p--); |
214 | for(p=input+strlen(input);p>input && isspace(*(p-1));p--); |
215 | *p=0; |
215 | *p=0; |
216 | activelen=maxlen=0; |
216 | activelen=maxlen=0; |
217 | active[0]=active[1]=1; |
217 | active[0]=active[1]=1; |
218 | for(linecnt=0,p=input;*p!=0 && linecnt<MAX_LINES;p=p3) { |
218 | for(linecnt=0,p=input;*p!=0 && linecnt<MAX_LINES;p=p3) { |
219 |
|
219 | p2=strchr(p,'\n'); |
220 |
|
220 | if(p2==NULL) { |
221 |
|
221 | p2=p+strlen(p);p3=p2; |
222 |
|
222 | } |
223 |
|
223 | else p3=p2+1; |
224 |
|
224 | while(isspace(*p)) p++; |
225 |
|
225 | if(strchr("+-*/=.",*p)!=NULL) { |
226 |
|
226 | style[linecnt]=*p;p++; |
227 |
|
227 | while(isspace(*p)) p++; |
228 |
|
228 | } |
229 |
|
229 | else style[linecnt]='+'; |
230 |
|
230 | if(*p3==0) style[linecnt]='='; |
231 |
|
231 | if(linecnt>1) { |
232 |
|
232 | switch(style[1]) { |
233 |
|
233 | case '+': |
234 |
|
234 | case '-': { |
235 |
|
235 | if(*p3!=0) active[linecnt]=1; |
236 |
|
236 | break; |
237 |
|
237 | } |
238 | 238 | ||
239 |
|
239 | case '*': |
240 |
|
240 | case '/': |
241 |
|
241 | case '=': |
242 |
|
242 | break; |
243 |
|
243 | } |
244 |
|
244 | } |
245 |
|
245 | while(p2>p && isspace(*(p2-1))) p2--; |
246 |
|
246 | if(p2>p+MAX_CHARS) p2=p+MAX_CHARS; |
247 |
|
247 | *p2=0; |
248 |
|
248 | if(p2<=p) continue; |
249 |
|
249 | for(i=0;i<p2-p;i++) { |
250 |
|
250 | char ch; |
251 |
|
251 | ch=toupper(*(p2-i-1)); |
252 |
|
252 | /* bad char */ |
253 |
|
253 | if(ch<'A' || ch>'Z') return 1; |
254 |
|
254 | basetab[linecnt][i]=ch; |
255 |
|
255 | } |
256 |
|
256 | charcnt[linecnt]=p2-p; |
257 |
|
257 | if(active[linecnt] && p2-p>activelen) activelen=p2-p; |
258 |
|
258 | if(p2-p>maxlen) maxlen=p2-p; |
259 |
|
259 | linecnt++; |
260 | } |
260 | } |
261 |
|
261 | /* multiplication */ |
262 | if(style[1]=='*') { |
262 | if(style[1]=='*') { |
263 |
|
263 | if(linecnt==3) style[1]='$'; |
264 |
|
264 | else { |
265 |
|
265 | if(linecnt!=charcnt[1]+3) return 1; |
266 |
|
266 | for(i=3;i<linecnt-1;i++) |
267 |
|
267 | if(charcnt[i]+i-2>maxlen) maxlen=charcnt[i]+i-2; |
268 |
|
268 | } |
269 | } |
269 | } |
270 | 270 | ||
271 | column(0,corresp,bcorresp); |
271 | column(0,corresp,bcorresp); |
272 | printf("\n!total %d solution(s).\n\n",total); |
272 | printf("\n!total %d solution(s).\n\n",total); |
273 | return 0; |
273 | return 0; |