Subversion Repositories distributed

Rev

Rev 14 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 14 Rev 15
Line 1... Line 1...
1
package de.viathinksoft.immortable.genX;
1
package de.viathinksoft.immortable.genX;
2
 
2
 
3
// TODO: Immort Test + Backups regelmäßig durchführen
3
// TODO: r als BigInteger
4
 
4
 
5
import java.io.BufferedReader;
5
import java.io.BufferedReader;
6
import java.io.BufferedWriter;
6
import java.io.BufferedWriter;
7
import java.io.File;
7
import java.io.File;
-
 
8
import java.io.FileNotFoundException;
8
import java.io.FileReader;
9
import java.io.FileReader;
9
import java.io.FileWriter;
10
import java.io.FileWriter;
10
import java.io.IOException;
11
import java.io.IOException;
-
 
12
import java.math.BigInteger;
11
import java.util.Vector;
13
import java.util.Vector;
12
 
14
 
-
 
15
/**
13
public class ImmortIterator {
16
 * Immortable Iterator
14
       
-
 
15
        /*
17
 *
16
         *      public static boolean isImmortable(BigInteger num) {
18
 * @author Daniel Marschall, René Gruber
17
                // Alternativ: n²%10^m == n%10^m
-
 
18
                return num.pow(2).toString().endsWith(num.toString());
19
 * @see http://www.matheboard.de/thread.php?postid=1259938
19
        }
-
 
20
 
-
 
21
         */
20
 */
-
 
21
public class ImmortableNumberSearch {
22
 
22
 
23
        // TODO: Output M5/M6 function...
23
        private static final String SIGNATURE = "Immortable Number Report File Version 2000";
24
        // TODO: r als BigInteger?
24
        private static final String SIGNATURE_MINOR = "Iterator GenX Java int";
25
 
-
 
26
        private static final String SIGNATURE = "Immortable Interator GenX int DSO 1000";
25
        private static final String END_SIG = "END OF REPORT";
27
        private static final int SOFTBREAK = 76;
26
        private static final int SOFTBREAK = 76;
28
 
27
 
29
        private Vector<Integer> a = new Vector<Integer>();
28
        private Vector<Integer> a = null;
30
        private int u;
-
 
31
        private int r;
-
 
32
        private int saveInterval = 100000; // TODO: Größer
-
 
33
        private String filename;
29
        private String filename;
-
 
30
        private int saveInterval = 10000;
-
 
31
        private int u = -1;
-
 
32
        private int r = -1;
-
 
33
        private String creation_time;
-
 
34
        private String backupDir = "backup";
34
       
35
 
35
        // TODO: load+save prüfen
-
 
36
 
-
 
37
        public ImmortIterator(String filename) throws Exception {
36
        public ImmortableNumberSearch(String filename) throws LoadException {
38
                this.filename = filename;
37
                this.filename = filename;
39
                load();
38
                load();
40
        }
39
        }
41
 
40
 
-
 
41
        public String getBackupDir() {
-
 
42
                return backupDir;
-
 
43
        }
-
 
44
 
-
 
45
        public void setBackupDir(String backupDir) {
-
 
46
                this.backupDir = backupDir;
-
 
47
        }
-
 
48
 
42
        public int getSaveInterval() {
49
        public int getSaveInterval() {
43
                return this.saveInterval;
50
                return this.saveInterval;
44
        }
51
        }
45
 
52
 
-
 
53
        public Vector<Integer> getA() {
-
 
54
                return a;
-
 
55
        }
-
 
56
 
-
 
57
        public int getU() {
-
 
58
                return u;
-
 
59
        }
-
 
60
 
-
 
61
        public int getR() {
-
 
62
                return r;
-
 
63
        }
-
 
64
 
-
 
65
        public String getFilename() {
-
 
66
                return filename;
-
 
67
        }
-
 
68
 
46
        public void setSaveInterval(int saveInterval) {
69
        public void setSaveInterval(int saveInterval) {
47
                this.saveInterval = saveInterval;
70
                this.saveInterval = saveInterval;
48
        }
71
        }
49
 
72
 
50
        private boolean savePointExists() {
73
        private boolean savePointExists() {
51
                return new File(filename).exists();
74
                return new File(filename).exists();
52
        }
75
        }
53
 
76
 
54
        private void load() throws Exception {
77
        private void load() throws LoadException {
55
                if (!savePointExists())
78
                if (!savePointExists()) {
56
                        return;
79
                        return;
-
 
80
                }
-
 
81
 
-
 
82
                BufferedReader f;
-
 
83
                try {
-
 
84
                        f = new BufferedReader(new FileReader(filename));
-
 
85
                } catch (FileNotFoundException e) {
-
 
86
                        // Will not happen because of savePointExists().
-
 
87
                        return;
-
 
88
                }
57
 
89
 
58
                BufferedReader f = new BufferedReader(new FileReader(filename));
90
                a = null;
-
 
91
                u = -1;
-
 
92
                r = -1;
59
 
93
 
-
 
94
                try {
-
 
95
                        try {
60
                String s = f.readLine();
96
                                String s = f.readLine();
61
                if (!s.equals(SIGNATURE)) {
97
                                if (!s.equals(SIGNATURE)) {
62
                        throw new Exception("Wrong signature");
98
                                        throw new LoadException("Wrong signature");
63
                }
99
                                }
64
               
100
 
-
 
101
                                f.readLine(); // Minor. signature
65
                f.readLine(); // ""
102
                                f.readLine(); // ""
66
                f.readLine(); // "(u)"
-
 
67
               
103
                               
-
 
104
                                f.readLine(); // "(Starting time)"
68
                s = f.readLine();
105
                                creation_time = f.readLine();
69
                u = Integer.parseInt(s);
106
                                f.readLine(); // ""
70
 
107
 
-
 
108
                                f.readLine(); // "(Save timestamp)"
-
 
109
                                f.readLine(); // Timestamp
71
                f.readLine(); // ""
110
                                f.readLine(); // ""
72
                f.readLine(); // "(r)"
-
 
73
               
111
 
-
 
112
                                f.readLine(); // "(u)"
74
                s = f.readLine();
113
                                s = f.readLine();
75
                r = Integer.parseInt(s); // TODO: more than 1 line
114
                                u = Integer.parseInt(s);
-
 
115
                                f.readLine(); // ""
76
               
116
                               
-
 
117
                                f.readLine(); // "(r)"
-
 
118
                                s = f.readLine();
-
 
119
                                r = Integer.parseInt(s); // FUTURE: (1) Multi-Line-Support?
77
                f.readLine(); // ""
120
                                f.readLine(); // ""
78
                f.readLine(); // "(M5rev)"
-
 
79
               
121
 
-
 
122
                                f.readLine(); // "(M5rev)"
80
                a.clear();
123
                                a = new Vector<Integer>();
81
                do {
124
                                do {
82
                        s = f.readLine();
125
                                        s = f.readLine();
83
                        if (s == null) break; // eof
-
 
84
                        for (int i=0; i<s.length(); i++) {
126
                                        for (int i = 0; i < s.length(); i++) {
85
                                a.add(new Integer(s.substring(i, i+1)));
127
                                                a.add(new Integer(s.substring(i, i + 1)));
86
                        }
128
                                        }
87
                } while (!s.equals(""));
129
                                } while (!s.equals(""));
88
               
130
 
-
 
131
                                if (!integryTest()) {
-
 
132
                                        throw new LoadException("Corrupt: Not immortable!");
-
 
133
                                }
-
 
134
 
-
 
135
                                if (u+1 != a.size()) {
-
 
136
                                        throw new LoadException(
-
 
137
                                                        "Corrupt: Formal and actual length mismatch!");
-
 
138
                                }
-
 
139
 
-
 
140
                                s = f.readLine();
-
 
141
                                if (!s.equals(END_SIG)) {
-
 
142
                                        throw new LoadException("Corrupt: End-signature mismatch.");
-
 
143
                                }
-
 
144
                        } finally {
89
                f.close();
145
                                f.close();
90
        }
146
                        }
-
 
147
                } catch (IOException e) {
-
 
148
                        throw new LoadException(e);
-
 
149
                }
-
 
150
        }
91
 
151
 
92
        private void save() throws IOException {
152
        private void save(boolean integrityTest) throws SaveException {
-
 
153
                if (integrityTest) {
-
 
154
                        if (!integryTest()) {
-
 
155
                                throw new SaveException(
-
 
156
                                                "Integrity test failed. Will not save.");
-
 
157
                        }
-
 
158
                }
-
 
159
 
-
 
160
                String timestamp = DateUtils.now("EEE, d MMM yyyy HH:mm:ss Z");
-
 
161
                String timestamp_filename = DateUtils.now("dd-MM-yyyy_HH-mm-ss");
-
 
162
               
-
 
163
                try {
93
                BufferedWriter f = new BufferedWriter(new FileWriter(filename));
164
                        BufferedWriter f = new BufferedWriter(new FileWriter(filename));
94
 
165
 
-
 
166
                        try {
95
                f.write(SIGNATURE + "\r\n");
167
                                f.write(SIGNATURE + "\r\n");
-
 
168
 
-
 
169
                                f.write(SIGNATURE_MINOR + "\r\n");
-
 
170
                                f.write("\r\n");
-
 
171
 
-
 
172
                                f.write("(Starting time)\r\n");
-
 
173
                                f.write(creation_time + "\r\n");
-
 
174
                                f.write("\r\n");
-
 
175
 
-
 
176
                                f.write("(Save timestamp)\r\n");
-
 
177
                                f.write(timestamp + "\r\n");
96
                f.write("\r\n");
178
                                f.write("\r\n");
97
 
179
 
98
                f.write("(u)\r\n");
180
                                f.write("(u)\r\n");
99
                f.write(u + "\r\n");
181
                                f.write(u + "\r\n");
100
                f.write("\r\n");
182
                                f.write("\r\n");
101
 
183
 
102
                f.write("(r)\r\n");
184
                                f.write("(r)\r\n");
103
                f.write(r + "\r\n"); // TODO: Softbreak
185
                                f.write(r + "\r\n"); // FUTURE: (1) Multi-Line-Support?
104
                f.write("\r\n");
186
                                f.write("\r\n");
105
 
187
 
106
                f.write("(M5rev)\r\n");
188
                                f.write("(M5rev)\r\n");
107
 
-
 
108
                int i = 0;
189
                                int i = 0;
109
                for (Integer xa : a) {
190
                                for (Integer xa : a) {
110
                        f.write(xa.toString());
191
                                        f.write(xa.toString());
111
                        if (++i % SOFTBREAK == 0) {
192
                                        if (++i % SOFTBREAK == 0) {
112
                                f.write("\r\n");
193
                                                f.write("\r\n");
113
                        }
194
                                        }
114
                }
195
                                }
115
               
-
 
116
                if (++i % SOFTBREAK != 0) {
196
                                if (++i % SOFTBREAK != 0) {
117
                        f.write("\r\n");
197
                                        f.write("\r\n");
118
                }
198
                                }
-
 
199
                                f.write("\r\n");
119
 
200
 
-
 
201
                                f.write(END_SIG);
-
 
202
                        } finally {
120
                f.close();
203
                                f.close();
121
        }
204
                        }
-
 
205
                } catch (IOException e) {
-
 
206
                        throw new SaveException("Could not save master file.", e);
-
 
207
                }
-
 
208
 
-
 
209
                // Make backup
-
 
210
 
-
 
211
                new File(backupDir).mkdir();
-
 
212
                String bak_filename = backupDir + "/immortal_" + timestamp_filename + "_" + (u+1)
-
 
213
                                + ".txt";
-
 
214
                try {
-
 
215
                        FileUtils.copyFile(new File(filename), new File(bak_filename));
-
 
216
                } catch (IOException e) {
-
 
217
                        throw new SaveException("Could not make backup", e);
-
 
218
                }
-
 
219
        }
122
 
220
 
123
        public void calcIterate(int amount) throws IOException {
221
        public void calcIterate(int amount) throws SaveException {
124
                int s, m, k;
222
                int s, m, k;
125
                int cnt = 0;
223
                int cnt = 0;
126
 
224
 
-
 
225
                // Wir führen beim ersten Speichern einen weiteren
-
 
226
                // integrity-Test durch. Grund: Wäre bei einer Fortsetzung einer
-
 
227
                // Datei das "r" falsch (der Datenteil aber korrekt), dann würde
-
 
228
                // diese Datei beim Speichern ungültige Daten enthalten (Zahl
-
 
229
                // nicht immortabel).
-
 
230
                boolean firstSave = true;
-
 
231
 
127
                if (a.size() < 2) {
232
                if (a == null) {
-
 
233
                        creation_time = DateUtils.now("EEE, d MMM yyyy HH:mm:ss Z");
-
 
234
                        a = new Vector<Integer>();
128
                        a.add(5);
235
                        a.add(5);
129
                        a.add(2);
236
                        a.add(2);
130
                        u = 1;
237
                        u = 1;
131
                        r = 2;
238
                        r = 2;
132
                        cnt += 2;
239
                        cnt += 2;
133
                }
240
                }
134
 
241
 
135
                while (true) {
242
                do {
136
                        r = (r - a.elementAt(u)) / 10 + a.elementAt(u);
243
                        r = (r - a.elementAt(u)) / 10 + a.elementAt(u);
137
                        s = 0;
244
                        s = 0;
138
                        for (m = 1, k = u; m < k; m++, k--) {
245
                        for (m = 1, k = u; m < k; m++, k--) {
139
                                s += a.elementAt(m) * a.elementAt(k);
246
                                s += a.elementAt(m) * a.elementAt(k);
140
                        }
247
                        }
Line 144... Line 251...
144
                        }
251
                        }
145
                        u++;
252
                        u++;
146
                        a.add(r % 10);
253
                        a.add(r % 10);
147
 
254
 
148
                        if (cnt % saveInterval == 0) {
255
                        if (cnt % saveInterval == 0) {
149
                                save();
256
                                save(firstSave);
-
 
257
                                firstSave = false;
150
                        }
258
                        }
-
 
259
                } while (++cnt != amount);
151
 
260
 
-
 
261
                // Wir brauchen nicht zwei Mal zu speichern
152
                        if (++cnt == amount) {
262
                if (cnt-1 % saveInterval != 0) {
153
                                save();
263
                        save(firstSave);
154
                                break;
264
                        firstSave = false;
155
                        }
265
                }
156
                }
266
        }
-
 
267
 
-
 
268
        public int getDigit(int u) {
-
 
269
                return a.elementAt(u);
157
        }
270
        }
158
 
271
 
-
 
272
        public StringBuilder M5_StringBuilder(int u) {
-
 
273
                StringBuilder s = new StringBuilder();
-
 
274
                for (Integer xa : a) {
-
 
275
                        s.append(xa);
-
 
276
                }
-
 
277
                s.reverse();
-
 
278
                return s;
-
 
279
        }
-
 
280
 
-
 
281
        public String M5_String(int u) {
-
 
282
                return M5_StringBuilder(u).toString();
-
 
283
        }
-
 
284
 
-
 
285
        public BigInteger M5_BigInteger(int u) {
-
 
286
                return new BigInteger(M5_String(u));
-
 
287
        }
-
 
288
 
-
 
289
        public StringBuilder M6_StringBuilder(int u) {
-
 
290
                StringBuilder s = new StringBuilder();
-
 
291
                boolean first = true;
-
 
292
                for (Integer xa : a) {
-
 
293
                        if (first) {
-
 
294
                                s.append(6); // xa = 5
-
 
295
                                first = false;
-
 
296
                        } else {
-
 
297
                                s.append(9 - xa);
-
 
298
                        }
-
 
299
                }
-
 
300
                s.reverse();
-
 
301
                return s;
-
 
302
        }
-
 
303
 
-
 
304
        public String M6_String(int u) {
-
 
305
                return M6_StringBuilder(u).toString();
-
 
306
        }
-
 
307
 
-
 
308
        public BigInteger M6_BigInteger(int u) {
-
 
309
                return new BigInteger(M6_String(u));
-
 
310
        }
-
 
311
 
-
 
312
        private static boolean isImmortable(BigInteger num) {
-
 
313
                // Ist das auch OK?
-
 
314
                // return num.pow(2).toString().endsWith(num.toString());
-
 
315
 
-
 
316
                // n² === n (mod 10^m) <===> n²%10^m == n%10^m
-
 
317
                int m = num.toString().length();
-
 
318
                BigInteger m_pow = BigInteger.TEN.pow(m);
-
 
319
                return num.pow(2).mod(m_pow).equals(num.mod(m_pow));
-
 
320
 
-
 
321
        }
-
 
322
 
-
 
323
        public boolean integryTest() {
-
 
324
                // return isImmortable(M5_BigInteger(u));
-
 
325
                return isImmortable(M6_BigInteger(u));
-
 
326
        }
159
}
327
}