Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | signature MATRIX = |
2 | sig | |
3 | type 'entry matrix | |
4 | val make: int * int * (int * int -> 'entry) -> 'entry matrix | |
5 | val height: 'entry matrix -> int | |
6 | val width: 'entry matrix -> int | |
7 | val fetch: 'entry matrix * int * int -> 'entry | |
8 | val fetchRow: 'entry matrix * int -> int -> 'entry | |
9 | val fetchCol: 'entry matrix * int -> int -> 'entry | |
10 | val store: 'entry matrix * int * int * 'entry -> unit | |
11 | val storeRow: 'entry matrix * int -> int * 'entry -> unit | |
12 | val storeCol: 'entry matrix * int -> int * 'entry -> unit | |
13 | val rowSwap: 'entry matrix * int * int -> unit | |
14 | val colSwap: 'entry matrix * int * int -> unit | |
15 | val rowOp: 'entry matrix * int * int * ('entry * 'entry -> 'entry) -> unit | |
16 | val colOp: 'entry matrix * int * int * ('entry * 'entry -> 'entry) -> unit | |
17 | val copy: 'entry matrix -> 'entry matrix | |
18 | val map: 'entry1 matrix * ('entry1 -> 'entry2) -> 'entry2 matrix | |
19 | val toString: 'entry matrix * ('entry -> string) -> string | |
20 | end | |
21 | ||
22 | structure Matrix:> MATRIX = | |
23 | struct | |
24 | type 'entry matrix = int * int * 'entry array | |
25 | ||
26 | exception sizeError | |
27 | ||
28 | exception index | |
29 | ||
30 | exception foldError | |
31 | ||
32 | fun make (height: int, width: int, generator: int * int -> 'entry) | |
33 | : 'entry matrix = | |
34 | if height < 0 orelse width < 0 | |
35 | then raise sizeError | |
36 | else (height, | |
37 | width, | |
38 | Array.tabulate (height*width, | |
39 | fn z => generator (z div width, | |
40 | z mod width))) | |
41 | ||
42 | fun height (height, _, _) = height | |
43 | ||
44 | fun width (width, _, _) = width | |
45 | ||
46 | fun fetch ((height, width, mat), row, col) = | |
47 | if 0 <= row | |
48 | andalso row < height | |
49 | andalso 0 <= col | |
50 | andalso col < width | |
51 | then Array.sub (mat, col + width*row) | |
52 | else raise index | |
53 | ||
54 | fun fetchRow ((height, width, mat), row) = | |
55 | if 0 <= row andalso row < height | |
56 | then let val offset = width * row | |
57 | in fn col => | |
58 | if 0 <= col andalso col < width | |
59 | then Array.sub (mat, col + offset) | |
60 | else raise index | |
61 | end | |
62 | else raise index | |
63 | ||
64 | fun fetchCol ((height, width, mat), col) = | |
65 | if 0 <= col andalso col < width | |
66 | then fn row => | |
67 | if 0 <= row andalso row < height | |
68 | then Array.sub (mat, col + width*row) | |
69 | else raise index | |
70 | else raise index | |
71 | ||
72 | fun store ((height, width, mat), row, col, entry) = | |
73 | if 0 <= row | |
74 | andalso row < height | |
75 | andalso 0 <= col | |
76 | andalso col < width | |
77 | then Array.update (mat, col + width*row, entry) | |
78 | else raise index | |
79 | ||
80 | fun storeRow ((height, width, mat), row) = | |
81 | if 0 <= row andalso row < height | |
82 | then let val offset = width * row | |
83 | in fn (col, entry) => | |
84 | if 0 <= col andalso col < width | |
85 | then Array.update (mat, col + offset, entry) | |
86 | else raise index | |
87 | end | |
88 | else raise index | |
89 | ||
90 | fun storeCol ((height, width, mat), col) = | |
91 | if 0 <= col andalso col < width | |
92 | then fn (row, entry) => | |
93 | if 0 <= row andalso row < height | |
94 | then Array.update (mat, col + width*row, entry) | |
95 | else raise index | |
96 | else raise index | |
97 | ||
98 | fun swapLoop (from1: int -> 'entry, | |
99 | to1: int * 'entry -> unit, | |
100 | from2: int -> 'entry, | |
101 | to2: int * 'entry -> unit, | |
102 | limit: int): unit = | |
103 | let fun loop (i: int): unit = | |
104 | if i = limit | |
105 | then () | |
106 | else let val tmp = from1 i | |
107 | in to1 (i, from2 i); | |
108 | to2 (i, tmp); | |
109 | loop (i + 1) | |
110 | end | |
111 | in loop 0 | |
112 | end | |
113 | ||
114 | fun rowSwap (mat as (height, width, _), row1, row2): unit = | |
115 | if 0 <= row1 andalso row1 < height | |
116 | andalso 0 <= row2 andalso row2 < height | |
117 | then if row1 = row2 | |
118 | then () | |
119 | else swapLoop (fetchRow (mat, row1), | |
120 | storeRow (mat, row1), | |
121 | fetchRow (mat, row2), | |
122 | storeRow (mat, row2), | |
123 | width) | |
124 | else raise index | |
125 | ||
126 | fun colSwap (mat as (height, width, _), col1, col2): unit = | |
127 | if 0 <= col1 andalso col1 < width | |
128 | andalso 0 <= col2 andalso col2 < width | |
129 | then if col1 = col2 | |
130 | then () | |
131 | else swapLoop (fetchCol (mat, col1), | |
132 | storeCol (mat, col1), | |
133 | fetchCol (mat, col2), | |
134 | storeCol (mat, col2), | |
135 | height) | |
136 | else raise index | |
137 | ||
138 | fun opLoop (from1: int -> 'entry, | |
139 | from2: int -> 'entry, | |
140 | to2: int * 'entry -> unit, | |
141 | limit: int, | |
142 | f: 'entry * 'entry -> 'entry): unit = | |
143 | let fun loop (i: int): unit = | |
144 | if i = limit | |
145 | then () | |
146 | else ( | |
147 | to2 (i, | |
148 | f (from1 i, from2 i)); | |
149 | loop (i + 1)) | |
150 | in loop 0 | |
151 | end | |
152 | ||
153 | fun rowOp (mat as (height, width, _), | |
154 | row1, | |
155 | row2, | |
156 | f: 'entry * 'entry -> 'entry): unit = | |
157 | if 0 <= row1 andalso row1 < height | |
158 | andalso 0 <= row2 andalso row2 < height | |
159 | andalso row1 <> row2 | |
160 | then opLoop (fetchRow (mat, row1), | |
161 | fetchRow (mat, row2), | |
162 | storeRow (mat, row2), | |
163 | width, | |
164 | f) | |
165 | else raise index | |
166 | ||
167 | fun colOp (mat as (height, width, _), | |
168 | col1, | |
169 | col2, | |
170 | f: 'entry * 'entry -> 'entry): unit = | |
171 | if 0 <= col1 andalso col1 < width | |
172 | andalso 0 <= col2 andalso col2 < width | |
173 | andalso col1 <> col2 | |
174 | then opLoop (fetchCol (mat, col1), | |
175 | fetchCol (mat, col2), | |
176 | storeCol (mat, col2), | |
177 | height, | |
178 | f) | |
179 | else raise index | |
180 | ||
181 | fun copy ((height, width, mat)) = | |
182 | (height, | |
183 | width, | |
184 | Array.tabulate (Array.length mat, | |
185 | fn i => Array.sub (mat, i))) | |
186 | ||
187 | fun map ((height, width, mat: 'entry1 Array.array), | |
188 | f: 'entry1 -> 'entry2) | |
189 | : 'entry2 matrix = | |
190 | (height, | |
191 | width, | |
192 | Array.tabulate (Array.length mat, | |
193 | fn i => f (Array.sub (mat, i)))) | |
194 | ||
195 | (* Natural fold a range of integers in reverse. *) | |
196 | fun naturalFold (limit: int, | |
197 | state: 'state, | |
198 | folder: int * 'state -> 'state): 'state = | |
199 | let fun loop (i: int, state: 'state) = | |
200 | if i = 0 | |
201 | then state | |
202 | else loop (i - 1, folder (i - 1, state)) | |
203 | in if limit < 0 | |
204 | then raise foldError | |
205 | else loop (limit, state) | |
206 | end | |
207 | ||
208 | ||
209 | local val blank8 = Byte.charToByte #" " | |
210 | ||
211 | fun makeBlanks size = | |
212 | let val blanks = Word8Vector.tabulate (size, | |
213 | fn _ => blank8) | |
214 | in Byte.bytesToString blanks | |
215 | end | |
216 | ||
217 | in fun toString (mat: 'entry matrix, f: 'entry -> string): string = | |
218 | let val mat as (height, width, _) = map (mat, f) | |
219 | fun maxSize from (i, width) = Int.max (String.size (from i), | |
220 | width) | |
221 | fun colWidth col = naturalFold (height, | |
222 | 0, | |
223 | maxSize (fetchCol (mat, | |
224 | col))) | |
225 | val widths = Vector.tabulate (width, colWidth) | |
226 | fun doRow (row: int, ac: string list): string list = | |
227 | let val from = fetchRow (mat, row) | |
228 | fun loop (col: int, ac: string list) = | |
229 | let val next = from col | |
230 | val ac = next::ac | |
231 | val s = String.size next | |
232 | val pad = Vector.sub (widths, col) - s | |
233 | val ac = if pad <= 0 | |
234 | then ac | |
235 | else (makeBlanks pad)::ac | |
236 | in if col = 0 | |
237 | then ac | |
238 | else loop (col - 1, | |
239 | " "::ac) | |
240 | end | |
241 | val ac = "\n"::ac | |
242 | in if width = 0 | |
243 | then ac | |
244 | else loop (width - 1, ac) | |
245 | end | |
246 | val pieces = naturalFold (height, | |
247 | [], | |
248 | doRow) | |
249 | in String.concat pieces | |
250 | end | |
251 | end | |
252 | end | |
253 | ||
254 | val zero = IntInf.fromInt 0 | |
255 | ||
256 | fun smaller (a: IntInf.int, b: IntInf.int): bool = | |
257 | (not (a = zero)) | |
258 | andalso (b = zero orelse IntInf.< (IntInf.abs a , IntInf.abs b)) | |
259 | ||
260 | fun smithNormalForm (mat: IntInf.int Matrix.matrix): IntInf.int Matrix.matrix = | |
261 | let val height = Matrix.height mat | |
262 | val width = Matrix.width mat | |
263 | val mat = Matrix.copy mat | |
264 | val range = Int.min (width, height) | |
265 | fun dd pos = | |
266 | let val matCol = Matrix.fetchCol (mat, pos) | |
267 | val matRow = Matrix.fetchRow (mat, pos) | |
268 | val _ = print ("dd: pos = " ^ (Int.toString pos) ^ "\n") | |
269 | fun swapRowLoop (best, bestRow, bestCol, row) = | |
270 | if row >= height | |
271 | then (Matrix.rowSwap (mat, pos, bestRow); | |
272 | Matrix.colSwap (mat, pos, bestCol)) | |
273 | else let val matRow = Matrix.fetchRow (mat, row) | |
274 | fun swapColLoop (best, bestRow, bestCol, col) = | |
275 | if col >= width | |
276 | then swapRowLoop (best, bestRow, bestCol, row + 1) | |
277 | else let val next = matRow col | |
278 | in if smaller (next, best) | |
279 | then swapColLoop (next, row, col, col + 1) | |
280 | else swapColLoop (best, bestRow, bestCol, col + 1) | |
281 | end | |
282 | in swapColLoop (best, bestRow, bestCol, pos) | |
283 | end | |
284 | fun rowLoop row = | |
285 | if row < height | |
286 | then if (matCol row) = zero | |
287 | then rowLoop (row + 1) | |
288 | else (Matrix.rowOp (mat, | |
289 | pos, | |
290 | row, | |
291 | let val x = IntInf.~ (IntInf.quot(matCol row, matCol pos)) | |
292 | in fn (lhs, rhs) => IntInf.+ (IntInf.* (lhs, x), rhs) | |
293 | end); | |
294 | if (matCol row) = zero | |
295 | then rowLoop (row + 1) | |
296 | else hitPosAgain ()) | |
297 | else let fun colLoop col = | |
298 | if col < width | |
299 | then if (matRow col) = zero | |
300 | then colLoop (col + 1) | |
301 | else (Matrix.colOp (mat, | |
302 | pos, | |
303 | col, | |
304 | let val x = IntInf.~ (IntInf.quot (matRow col, matRow pos)) | |
305 | in fn (lhs, rhs) => IntInf.+ (IntInf.* (lhs, x), rhs) | |
306 | end); | |
307 | if (matRow col) = zero | |
308 | then colLoop (col + 1) | |
309 | else hitPosAgain ()) | |
310 | else () | |
311 | in colLoop (pos + 1) | |
312 | end | |
313 | and hitPosAgain () = (swapRowLoop (zero, pos, pos, pos); | |
314 | rowLoop (pos + 1)) | |
315 | in hitPosAgain () | |
316 | end | |
317 | fun loop pos = | |
318 | if pos = range | |
319 | then mat | |
320 | else (dd pos; | |
321 | loop (pos + 1)) | |
322 | in loop 0 | |
323 | end | |
324 | ||
325 | val table = [[ 8, ~3, 1, 3, 6, 9, ~2, 4, ~9, ~9, 2, 3, 8, ~1, 3, ~5, 4, ~3, ~5, ~6, 8, 1, 4, ~5, 7, ~4, ~4, ~7, 7, 1, 4, ~3, 8, 4, ~4, ~8, 5, ~9, 3, ~4, 1, 9, ~8, ~6, ~2, 8, ~9, ~5, ~3, ~3], | |
326 | [ 0, 8, ~6, ~2, ~3, 4, 5, ~2, 7, ~7, ~6, ~7, ~3, ~4, 9, 7, ~3, 3, 0, 3, 3, ~8, ~8, 2, 3, 8, 3, ~2, ~4, 3, ~6, ~6, ~2, 6, 5, ~1, ~3, 1, 8, ~8, 2, 1, ~7, ~7, ~7, ~3, ~6, 6, ~4, ~9], | |
327 | [ 0, ~5, 8, ~9, 2, 4, 2, 7, ~4, 9, ~3, 6, ~2, 3, ~3, 0, ~9, 5, 8, ~1, 2, ~8, 3, 4, ~6, 5, ~6, ~5, ~8, 0, ~5, 3, ~2, ~5, 8, 7, ~1, 1, ~1, 7, 6, 3, 6, 5, 6, 8, 7, 9, 7, ~3], | |
328 | [ 5, 4, 7, 2, 3, ~9, 7, ~7, 3, ~8, 7, 5, 5, ~2, ~6, ~3, 6, 5, 3, ~1, ~1, 4, 5, ~5, 5, 9, 9, 3, 8, ~3, ~1, 9, ~9, 6, ~7, 7, 4, 6, ~8, ~9, 0, ~3, ~2, ~7, 1, ~2, ~6, 7, 7, 7], | |
329 | [ 2, 9, 9, 3, ~4, 0, 9, 2, 5, 3, ~5, ~3, ~1, 1, 8, ~6, 2, ~4, ~8, ~7, ~8, 4, 5, 8, ~1, ~1, 7, 2, 5, 5, ~4, ~7, ~3, ~7, 6, ~4, ~5, ~8, ~5, ~9, ~8, 5, ~5, ~5, 0, 8, 8, 6, 4, ~1], | |
330 | [ 5, 5, 1, ~7, 3, ~5, 4, 9, 3, 4, 4, ~5, 7, ~1, 7, 4, ~7, 7, ~7, ~2, 9, ~9, 0, ~4, ~4, 0, 2, 6, 3, ~1, 6, 6, 8, ~6, ~4, ~9, 3, ~2, ~5, 5, ~3, 2, ~1, ~6, 9, 3, ~3, ~8, ~9, 7], | |
331 | [ 7, 1, 2, 7, 6, 5, ~6, ~3, ~4, ~8, 0, 9, 6, 1, 2, ~5, 4, 4, 4, ~6, ~7, ~9, ~6, 2, ~4, 5, ~2, 1, 0, 1, ~8, 7, ~7, ~5, 4, 1, ~5, 4, ~4, ~2, ~3, 1, 1, 3, 4, ~4, ~5, 9, 8, ~2], | |
332 | [ 6, 2, ~1, ~8, 4, ~7, 7, ~3, ~2, ~5, 3, 0, 3, ~9, 3, 3, 9, ~1, 4, 8, ~9, 6, ~5, 9, 5, ~1, ~1, ~9, 7, ~2, 3, 9, 8, 9, 2, 7, 7, 6, ~1, ~1, ~2, ~2, ~7, 3, ~6, 0, ~9, 4, 3, 7], | |
333 | [ 0, ~6, ~3, ~7, ~1, 5, ~2, 8, ~5, ~3, ~8, 7, ~2, ~2, 0, ~8, 4, 8, 9, ~5, ~4, ~8, ~1, 7, 1, 1, 6, ~9, ~4, 0, 8, 4, 3, ~7, 6, 0, 1, 8, 6, ~1, ~1, ~7, 9, ~9, ~5, ~2, ~2, ~1, 1, 0], | |
334 | [~4, 9, 6, ~3, ~2, ~6, ~3, 4, 8, ~8, 1, ~5, 9, 7, 9, 7, ~9, ~6, 6, 1, ~3, 3, ~3, ~7, 1, 7, ~7, 0, ~2, 7, ~4, ~6, 0, 1, ~3, ~5, ~9, ~7, 8, 4, 9, ~8, ~8, ~7, ~6, 7, 6, ~3, ~8, 5], | |
335 | [ 6, 7, ~5, ~9, 6, 1, 8, 4, ~2, 7, ~7, ~1, ~9, 1, ~6, ~5, 4, 9, 6, 0, ~8, ~3, 1, ~3, 8, ~3, 2, 9, ~3, ~9, ~1, ~3, 4, 3, 2, ~9, ~5, ~3, 8, ~4, 8, 5, ~4, 7, 6, ~8, 7, 6, ~5, 5], | |
336 | [ 1, 7, ~8, ~9, ~7, ~3, 8, 9, ~7, ~1, ~7, 4, 0, 0, 1, ~5, 9, ~8, ~1, ~2, 3, 5, 9, ~9, 5, 4, ~9, 1, ~4, ~2, 3, ~4, 8, ~6, ~4, ~8, ~5, ~5, 4, ~2, ~4, ~1, ~9, ~5, 2, ~9, 2, ~9, ~2, ~3], | |
337 | [~5, ~4, ~4, 9, 2, 7, ~2, 6, 7, 2, ~9, 4, 2, 7, 8, ~9, 2, 5, 3, 9, 6, 3, 0, ~7, ~6, ~7, 6, ~2, 9, ~3, ~6, 9, ~9, 2, 2, ~6, ~1, 4, ~3, 3, 0, 6, ~3, 4, 9, 9, ~6, 5, 5, ~5], | |
338 | [ 5, ~7, 8, ~4, 8, 8, ~4, ~9, 6, 0, ~3, 6, 0, 8, 8, ~6, ~2, 5, 4, ~1, ~8, 1, ~3, ~1, 2, 3, ~9, ~9, ~5, 1, 8, ~5, ~3, 0, ~4, ~9, 0, ~6, 3, ~1, ~7, 0, 8, 9, ~6, ~1, ~9, 1, ~6, 2], | |
339 | [ 7, ~5, ~1, 5, ~2, 7, 0, ~7, ~1, 8, 8, ~3, 9, ~5, 7, ~8, ~8, ~4, 3, 2, ~1, 8, ~2, 1, 2, 5, 0, ~6, 7, 3, 3, 7, ~5, 5, ~1, 1, 0, ~8, 1, 0, 0, ~4, 6, 9, ~5, ~6, 3, ~5, 8, 5], | |
340 | [~4, ~2, 3, ~3, ~1, 2, ~2, ~1, ~9, ~5, 1, 0, 0, 2, 9, ~3, ~9, 2, 9, 3, 8, ~3, 4, 8, 8, 3, ~3, ~1, ~4, 4, ~6, ~9, 5, ~2, 1, 3, ~7, ~5, ~6, ~5, ~8, 4, ~8, ~3, 5, 0, 7, ~9, 6, 2], | |
341 | [ 5, 1, 4, ~3, ~1, ~9, 5, ~8, ~8, 6, 1, 1, ~2, 7, 5, 6, ~4, 2, ~7, 0, ~7, ~3, ~5, 9, 3, 4, ~6, 8, ~4, 3, 6, 0, 2, 3, ~6, 3, 9, 4, 1, ~4, 6, ~5, ~7, 0, ~1, ~8, ~3, ~9, 9, 7], | |
342 | [ 2, ~6, ~1, 8, 4, ~3, ~1, ~6, ~2, ~8, ~2, ~1, ~1, ~5, ~9, ~8, 9, ~9, 5, 1, 9, ~1, ~6, 9, ~7, 2, 8, ~7, 4, ~9, 7, 6, ~2, 1, ~2, ~7, 8, 0, 5, 0, ~5, ~7, ~6, 0, 4, 0, 3, ~8, 5, 4], | |
343 | [~2, 9, ~9, ~6, 1, ~8, 8, 4, ~6, 8, 1, ~3, ~7, 8, ~5, 2, ~8, 1, 3, ~2, 6, 6, 6, 1, 0, 0, ~7, 7, ~3, ~3, 0, ~4, 3, ~7, ~6, 7, 5, 9, ~5, 7, ~8, 2, 3, ~8, ~7, 6, ~5, ~5, ~8, ~9], | |
344 | [~7, ~4, 4, 1, ~1, ~3, ~8, 3, 7, 9, 8, 3, 0, 4, 4, ~1, ~5, 4, 2, 2, 0, 6, ~6, 2, ~9, 8, ~9, 3, ~2, 2, 6, 6, 1, 7, 1, 0, ~8, 2, 3, ~3, 8, 9, 5, 5, ~6, 4, ~7, ~4, ~2, ~3], | |
345 | [~5, 8, 6, 1, ~6, ~6, 6, 1, 1, ~3, ~9, ~6, 2, ~7, 2, ~1, 6, ~6, 0, 2, ~7, 8, ~8, 4, 9, ~3, 9, ~7, ~9, ~6, ~4, ~4, ~5, 8, 2, ~5, ~4, ~3, 5, 2, 1, ~3, ~3, ~7, ~9, 3, 7, ~7, 3, ~8], | |
346 | [~4, ~7, ~2, 2, ~4, ~2, 6, ~3, ~1, ~4, 0, ~5, 9, 7, ~6, ~9, 7, ~9, ~6, 2, ~3, 1, 5, ~9, 4, ~5, 4, ~9, 1, ~2, ~2, 4, 0, 4, ~8, ~8, 3, ~1, ~5, ~4, ~9, ~7, 7, 6, 3, ~9, 6, 4, ~4, ~7], | |
347 | [~9, 6, 6, ~5, ~1, ~7, 4, ~9, 4, ~1, 6, ~4, 7, 2, 8, 7, 3, 1, ~7, 7, 7, 9, 8, ~9, 7, 2, 1, 2, ~8, 4, 5, 6, 7, 2, ~7, 6, 8, 4, ~9, 7, ~5, 6, 9, ~1, 9, 2, 0, 9, 3, 6], | |
348 | [ 4, ~3, 8, 0, ~2, ~2, 2, ~3, 8, 3, 1, ~8, ~5, ~2, 5, 6, 8, 0, ~3, 4, ~2, 4, ~9, ~5, 7, 6, ~4, ~7, 2, 4, ~3, ~8, ~9, 9, 8, ~9, 3, ~7, 4, ~7, ~5, 4, 9, 3, ~6, ~3, ~7, 4, 2, ~2], | |
349 | [~8, ~8, 6, ~2, ~6, 8, ~3, 3, ~1, ~7, 1, 9, 1, 7, ~6, 8, ~2, ~9, ~1, 3, ~4, 7, 8, ~1, 9, ~9, 6, ~3, 5, 0, 2, 5, ~1, ~6, ~6, 1, 8, 6, ~3, ~9, ~1, 9, ~2, 9, ~8, ~7, ~3, 6, ~3, ~3], | |
350 | [ 5, ~2, 3, 0, ~9, ~8, ~6, 1, 8, 0, 1, 2, ~8, ~2, 0, ~9, ~8, 0, 5, ~3, ~4, 5, 6, ~2, ~5, 0, ~9, 9, ~9, ~5, 9, 9, ~5, ~2, 4, 3, 8, ~8, ~7, 5, ~3, ~2, 2, 3, 9, 7, ~1, 0, 4, ~1], | |
351 | [~4, 5, ~5, 7, 8, 9, 7, ~3, 1, 9, ~7, ~1, 8, ~5, ~1, 2, ~8, 1, 0, 9, ~8, ~1, 6, ~1, 9, ~8, 7, 4, ~8, 7, 0, ~6, 2, 3, 7, 4, ~3, ~5, 9, ~3, 0, 6, ~9, 2, 4, ~8, 6, ~7, 9, 1], | |
352 | [ 7, 0, ~9, 6, 8, 2, 2, 5, ~6, ~6, 9, ~5, 9, 2, 2, ~8, 0, ~6, ~9, ~6, ~4, ~9, 8, ~2, 9, 7, ~5, ~1, 7, 2, ~7, 7, ~1, ~3, 6, 6, 1, ~4, 0, ~1, ~6, ~5, 6, ~7, ~3, ~2, 8, 2, ~9, 8], | |
353 | [ 8, ~7, ~9, ~6, 9, ~7, ~7, 6, ~8, 9, 5, ~4, 1, ~7, ~8, ~6, ~3, 8, ~8, 1, ~8, 6, 9, ~3, ~7, 7, 1, 6, 1, 0, 8, ~5, ~8, 8, ~9, 0, 4, 4, 3, ~4, 6, ~3, ~9, 0, 4, ~4, ~5, ~9, ~5, ~8], | |
354 | [~3, ~2, 8, 1, ~1, ~1, ~4, 3, 7, ~2, ~9, 9, ~8, ~9, 6, ~4, 7, ~1, ~5, ~3, ~9, 0, ~3, 0, 7, 9, 1, ~2, 7, ~9, ~6, 3, 3, ~4, ~7, ~3, ~4, ~8, ~2, ~3, ~9, ~2, ~6, 3, ~6, ~4, 7, ~5, ~8, ~1], | |
355 | [~9, ~9, ~2, ~9, ~9, 9, 6, 6, 7, 5, ~1, ~2, 1, 5, 2, ~3, ~4, 1, ~6, 0, ~3, ~9, ~1, 7, 0, ~9, 5, ~2, ~2, 5, 3, 4, ~1, 6, ~6, 3, ~6, 7, ~1, 5, ~8, ~4, ~2, ~2, ~6, ~5, ~6, 3, ~1, 4], | |
356 | [ 7, 7, 8, 7, 6, 1, ~2, 5, ~6, 9, 4, 8, 5, 0, ~4, ~2, ~2, ~5, ~2, ~6, 9, ~8, ~2, ~5, ~9, 3, ~6, ~3, ~4, ~5, ~2, 6, 1, 6, ~5, 0, ~3, ~2, 4, ~6, 1, 6, ~1, 3, ~9, 2, ~3, 1, 5, ~6], | |
357 | [ 6, 4, ~7, 3, ~7, 9, 1, ~7, ~8, 0, ~6, 8, 4, 1, 9, 6, 8, 3, 0, 9, 0, 4, 9, ~7, ~7, 1, 5, 1, ~5, 6, 9, 2, 4, 1, ~9, 8, 4, 5, 8, 3, 2, ~9, ~6, ~9, 9, ~9, 7, ~6, ~4, 3], | |
358 | [~3, ~9, ~4, 2, 3, 9, ~9, 8, ~9, 9, ~4, ~9, ~5, 5, 0, 7, 3, ~5, ~8, 2, ~3, 0, ~9, ~3, 1, 9, 4, 5, ~1, 8, 0, ~4, ~2, 9, ~4, ~1, 3, 5, 9, ~1, 1, 4, ~8, ~2, ~3, 5, 1, 5, ~6, 7], | |
359 | [ 9, ~3, 2, ~9, 3, 4, 0, 7, ~5, 9, 0, ~6, 7, ~2, 3, ~7, 2, ~5, ~2, 6, 3, ~9, ~5, ~9, 5, 2, ~5, ~3, 8, ~5, 6, 2, 9, ~7, ~7, ~7, ~6, 9, ~3, 6, 0, 6, ~6, ~9, 4, ~3, ~9, 0, ~4, ~9], | |
360 | [~4, ~8, 8, ~7, 7, 0, ~6, ~6, 8, ~9, ~4, 5, ~3, ~1, 7, ~5, ~6, ~1, 8, 6, ~2, 1, ~1, 5, ~9, 1, ~1, ~7, ~6, ~6, ~6, ~4, 6, 3, ~5, ~5, ~6, 2, 3, ~6, ~8, ~3, 8, ~2, ~5, ~4, ~3, 1, 4, ~4], | |
361 | [ 4, ~6, 2, 6, 2, ~8, 8, 5, 8, ~2, 0, ~6, ~1, ~6, ~2, 2, 6, ~9, ~7, ~6, ~4, ~4, ~7, ~2, 8, 6, 3, ~7, ~6, 8, 2, 3, 4, 5, 3, 4, ~6, 8, 8, ~1, 4, ~5, 6, 2, 8, ~3, ~9, ~2, 6, 7], | |
362 | [ 3, ~4, 0, ~3, ~5, 0, ~2, ~6, ~2, 8, 5, ~9, ~4, ~8, ~6, 0, 8, 9, 1, ~2, 8, 2, ~2, 8, 9, 3, 3, 5, ~9, ~3, ~2, 7, 2, 9, 0, 4, 8, ~9, 0, ~6, 9, ~9, 9, ~4, 8, ~8, ~8, 2, ~3, 2], | |
363 | [~1, 3, ~9, ~8, ~7, 6, ~6, 3, 0, 5, ~5, 1, 2, ~2, ~3, 7, 7, 3, ~4, ~2, ~9, ~5, ~1, 9, 6, 8, 2, 8, 7, ~3, 4, 6, 6, 0, ~2, 2, ~7, ~7, 6, ~3, 8, 2, 1, 0, 8, ~1, 3, 9, 8, 6], | |
364 | [ 1, ~2, ~3, 6, 5, 5, ~6, ~4, ~5, 1, 1, 6, ~7, ~4, ~3, 4, 4, ~8, ~9, 7, ~2, ~3, ~7, ~2, 1, 2, 0, 8, ~6, ~5, ~5, 7, 8, 5, ~2, 3, 9, 0, 5, 1, 3, ~4, ~6, 1, 4, ~9, ~2, 5, 4, 3], | |
365 | [ 3, 3, 9, ~2, 6, 9, 4, 9, 4, ~8, 5, ~1, 3, ~2, 1, ~7, ~3, 2, 2, 0, ~3, 3, 8, 2, 0, ~5, 7, 1, 4, ~8, 8, ~9, ~1, 1, ~9, ~4, 5, 2, 2, 8, 6, 1, 6, ~2, 2, 7, 1, ~6, ~1, ~1], | |
366 | [ 4, ~2, 4, ~1, ~5, ~1, 5, ~2, 3, ~4, ~5, 0, 2, ~4, 6, 4, ~3, 2, 2, 5, ~6, ~7, ~9, ~1, ~9, ~9, 6, 0, 6, 5, 9, ~1, 3, ~3, ~8, 8, ~8, 8, 4, 5, ~1, ~5, 1, 0, 3, ~2, 5, 6, 6, 5], | |
367 | [~4, 9, 6, 8, ~9, 5, 5, ~3, ~7, 7, 6, 8, ~8, 0, 4, ~1, 9, 5, ~7, 0, ~1, ~2, 3, 6, 0, 4, ~3, 1, 4, 6, 4, 0, 5, ~1, 7, ~7, ~6, ~8, ~3, ~6, 7, ~1, ~3, ~2, ~3, ~5, 3, 1, ~8, ~9], | |
368 | [~6, 4, ~5, 9, 9, ~7, ~1, ~8, ~4, 2, ~6, 0, ~6, ~6, 7, 6, 0, 1, 7, ~7, 0, ~4, ~6, ~8, ~9, 5, ~6, ~9, 2, ~7, ~2, ~6, 9, 4, ~5, 0, 4, ~4, ~5, 6, 9, 1, ~6, ~5, 3, ~1, 7, ~7, ~6, 7], | |
369 | [~8, 7, 7, ~6, 7, ~4, 8, 0, ~9, ~8, ~3, 7, ~3, 3, 8, ~7, ~2, ~7, 5, 5, ~5, 4, 6, 2, 4, 1, 4, ~9, ~3, 8, 8, ~9, ~4, ~2, 1, ~3, 1, 3, 9, ~5, ~8, ~2, 7, 8, 9, 2, 0, 1, ~9, 6], | |
370 | [~7, 1, ~9, 5, ~5, ~5, 7, 6, ~5, ~9, ~6, ~8, ~6, 9, 7, 9, 0, ~5, 7, 7, ~6, 4, 5, ~9, ~1, ~2, ~7, 3, ~5, ~2, ~5, 5, ~3, ~4, ~2, ~8, 2, ~8, 0, ~8, 0, ~8, 9, 8, ~5, ~5, 1, 3, 5, ~4], | |
371 | [~8, ~8, 0, ~5, ~8, ~6, 3, ~6, ~4, 6, 1, ~5, ~6, ~8, ~4, ~6, ~2, ~6, 6, ~4, 8, 8, 4, ~5, ~1, 0, 9, ~8, ~3, ~1, ~8, 7, ~3, 0, ~7, 1, ~7, ~1, ~7, 3, ~7, 3, ~4, ~8, 8, ~7, ~9, ~8, 3, 2], | |
372 | [ 3, 6, 8, ~9, 7, 1, ~9, 9, 3, 8, 6, 4, ~2, 1, ~8, 4, ~7, ~4, ~3, 3, ~5, ~6, ~7, ~2, 0, ~4, 5, 2, 5, 6, 3, ~8, 2, ~5, ~7, 6, 8, ~2, ~5, ~4, 9, 9, 2, ~2, ~2, 7, 4, 4, ~2, 3], | |
373 | [ 6, 6, ~5, ~2, ~8, ~2, ~9, 0, 2, 4, ~6, ~9, 9, 0, ~8, ~3, ~1, ~2, ~1, 6, 8, 2, ~9, 5, ~2, 1, 7, ~6, 5, 1, ~1, 4, ~4, ~7, ~6, ~3, ~8, 2, 2, 5, 5, ~6, 5, 3, 3, 7, 4, 7, ~3, ~9], | |
374 | [~9, 6, ~4, 1, 3, ~8, ~8, ~8, ~1, 5, 1, 1, ~1, 6, 5, 1, ~1, 5, ~8, 8, ~7, ~5, ~1, ~1, 6, ~8, ~3, ~1, ~2, ~6, ~5, ~5, ~6, 0, 2, 2, 7, ~1, ~5, ~7, ~1, ~3, 7, 6, 0, 2, 4, ~5, 0, ~4]] | |
375 | ||
376 | fun f (x, y) = List.nth (List.nth (table, x), y) | |
377 | fun show m = print (Matrix.toString (m, IntInf.toString)) | |
378 | val _ = | |
379 | let val dim = 32 | |
380 | val big = Matrix.map (Matrix.make (dim, dim, f), IntInf.fromInt) | |
381 | in show big; | |
382 | print "\n"; | |
383 | show (smithNormalForm big) | |
384 | end | |
385 |