Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

A (one dimensional) cellular automaton is a function1 F : Σ → Σ with the property that there is a K > 0 such that F (x)i depends only on the 2K + 1 coordinates xi−K , xi−K+1, . . . , xi−1, xi, xi+1, . . . , xi+K . A periodic point of σ is any x such that σ^p (x) = x for some p ∈ N, and a periodic point of F is any x such that F^q (x) = x for some q ∈ N. Given a cellular automaton F, a point x ∈ Σ is jointly periodic if there are p, q ∈ N such that σ^p (x) = F^q (x) = x, that is, it is a periodic point under both functions.

This project aims to explore the nature of one-dimensional Cellular Automata, in the hope of finding the structure of cellular automata through its periodic points.

2034 views
License: MIT
ubuntu2004
1
/*
2
* Copyright (C) 2004 Bryant Lee
3
*
4
* This file is part of FProbPeriod.
5
*
6
* FProbPeriod is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* FProbPeriod is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with FProbPeriod; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
/* This is the main function of the FProbPeriod program
22
* FProbPeriod program samples points over N-shift that are shift periodic
23
* with period k and finds period and preperiod. The result gives some
24
* indication of what is the average period of all points of shift period k
25
* over the N-shift.
26
*
27
* Written by: Bryant Lee
28
* Date: 9/01/05
29
*/
30
31
#define USEARRAYS 0
32
#define DEBUG 0
33
34
//Standard C++
35
#include <string.h>
36
#include <iostream>
37
#include <iomanip>
38
#include <fstream> //for file ops
39
40
//C
41
#include <stdlib.h> //for atoi
42
#include <math.h> //for pow, and ceil
43
#include <time.h> //to get seed for random numbers
44
45
//STL
46
#include <vector>
47
#include <list>
48
#include <map>
49
50
//local
51
#include "StringOps.h"
52
#include "Comp.h"
53
#include "StorageKey.h"
54
#include "StorageVal.h"
55
#include "RecNode.h"
56
#include "StorageKeyUInt.h"
57
58
//mersenne twister, pseudo-random number generator
59
#include "MTRand.h"
60
61
//function definitions
62
void convertPeriodList(const string &strInput, vector<int> &periodList);
63
void probExp(unsigned int shiftSize, const vector<int> &periodList,
64
Comp *comp, int numPoints, list<RecNode*> &recList,
65
string &prefix, vector<string> &commandbuffer);
66
void probExpTwoShift(const vector<int> &periodList,
67
Comp *comp, int numPoints, list<RecNode*> &recList,
68
string &prefix, vector<string> &commandbuffer);
69
void clearStorageNodes(vector<StorageVal*> &table);
70
void clearRecList(list<RecNode*> &recList);
71
void output(unsigned int shiftSize, int numPoints, string &prefix,
72
const vector<int> &periodList, Comp * comp,
73
list<RecNode*> &recList, vector<string> &commandbuffer);
74
void findDivisors(unsigned int x, vector<int> &divisorsList);
75
bool leastPeriod(byte *word, unsigned int currPeriod,
76
const vector<int> &divisorsList);
77
bool leastPeriod(unsigned int word, unsigned int currPeriod,
78
const vector<int> &divisorsList);
79
80
//GLOBAL
81
82
//this debug variable allows testing the "special case 2-shift" with
83
//arrays of unsigned ints in which each unsigned int carries UINTSIZE
84
//bits of info (each bit representing 1 coordinate). Values up to 32 allowed.
85
int UINTSIZE = 32;
86
87
//boolean that determines whether output is given after each completed experiment (after each K)
88
//or only at end
89
bool OUTPUT_AFTER_EACH = false;
90
91
//main
92
int main() {
93
unsigned int shiftSize; //# symbols in shift
94
string prefix; //prefix for output files
95
string strInput, strInput2, strInput3; //temp variables
96
vector<int> periodList; //list of periods
97
unsigned int i = 0, temp; //counter
98
list<RecNode*> recList; //list of records
99
list<RecNode*> leastRecList; //list of records for points of least period k
100
Comp *comp = NULL; //composition to apply
101
102
int numPoints;
103
string outoption;
104
105
//hold the command strings
106
vector<string> commandbuffer;
107
int commandbufferit;
108
109
//grab all input from cin and put in an array of strings
110
while(!cin.eof()) {
111
std::getline(cin, strInput);
112
commandbuffer.push_back(strInput);
113
}
114
115
commandbufferit = 0;
116
117
//get "output after each" or "output at end"
118
outoption = commandbuffer[commandbufferit++];
119
trim(outoption);
120
transform(outoption.begin(), outoption.end(), outoption.begin(), tolower);
121
122
if(outoption == "output after each")
123
OUTPUT_AFTER_EACH = true;
124
else if(outoption == "output at end")
125
OUTPUT_AFTER_EACH = false;
126
else {
127
cout << "Error on line 1: invalid value for output mode\n";
128
goto cleanup;
129
}
130
131
//get filename prefix
132
prefix = commandbuffer[commandbufferit++];
133
trim(prefix);
134
135
//get N, the number of symbols in the full shift
136
strInput = commandbuffer[commandbufferit++];
137
trim(strInput);
138
shiftSize = atoi(strInput.c_str());
139
140
//get set of K, the periodicities to be tested
141
strInput = commandbuffer[commandbufferit++];
142
convertPeriodList(strInput, periodList);
143
144
//get m, the number of sample points
145
strInput = commandbuffer[commandbufferit++];
146
trim(strInput);
147
numPoints = atoi(strInput.c_str());
148
149
//Allocate composition object
150
comp = new Comp(shiftSize);
151
152
//get "Begin Definitions"
153
strInput = commandbuffer[commandbufferit++];
154
155
//make it lowercase
156
trim(strInput);
157
transform(strInput.begin(), strInput.end(), strInput.begin(), tolower);
158
159
if(strInput.compare("begin definitions") != 0) {
160
cout << "ERROR: Expecting \"BEGIN DEFINITIONS\"\n";
161
goto cleanup;
162
}
163
164
//read definitions
165
while(1) {
166
strInput = commandbuffer[commandbufferit++];
167
168
//strInput2 is lowercased and trimmed
169
strInput2.resize(strInput.length());
170
transform(strInput.begin(), strInput.end(), strInput2.begin(), tolower);
171
trim(strInput2);
172
173
//strInput3 is lowercased and NOT TRIMMED
174
strInput3.resize(strInput.length());
175
transform(strInput.begin(), strInput.end(), strInput3.begin(), tolower);
176
177
if(strInput2 == "" || (strInput2[0] == '/' && strInput2[1] == '/')) {
178
//ignore blank lines and allow comment out
179
}
180
else if(strInput2 == "begin commands") {
181
break; //BREAK
182
}
183
else {
184
i = 0;
185
186
while(i < strInput.length()) {
187
if(strInput[i] == '=') {
188
break;
189
}
190
191
i++;
192
}
193
194
if(strInput2[0] == 'o' && strInput2[1] == 'p' && strInput2[2] == 't') {
195
temp = strInput3.find("opt");
196
temp += 3;
197
198
comp->addFunc(strInput.substr(i+1, strInput.length() - (i+1)),
199
strInput.substr(temp, i-temp), true);
200
}
201
else {
202
comp->addFunc(strInput.substr(i+1, strInput.length() - (i+1)),
203
strInput.substr(0,i), false);
204
}
205
}
206
}
207
208
//read commands
209
while(commandbufferit < (int)commandbuffer.size()) { //check for EOF
210
strInput = commandbuffer[commandbufferit++];
211
trim(strInput);
212
213
//ignore blank lines and allow comment out with "//"
214
if(strInput != "" && !(strInput[0] == '/' && strInput[1] == '/')) {
215
216
//set composition
217
if(!comp->setComposition(strInput)) {
218
cout << "ERROR: Command \"" << strInput
219
<< "\" references undefined function\n";
220
goto cleanup;
221
}
222
223
//do experiment
224
if(shiftSize == 2 && sizeof(unsigned int) == 4 && !USEARRAYS)
225
probExpTwoShift(periodList, comp, numPoints, recList, prefix,
226
commandbuffer);
227
else
228
probExp(shiftSize, periodList, comp, numPoints, recList, prefix,
229
commandbuffer);
230
231
if(!OUTPUT_AFTER_EACH)
232
output(shiftSize, numPoints, prefix, periodList, comp, recList,
233
commandbuffer);
234
235
//clear records (delete the nodes with ptrs in lists)
236
clearRecList(recList);
237
clearRecList(leastRecList);
238
recList.clear();
239
leastRecList.clear();
240
}
241
}
242
243
//cleanup and exit
244
cleanup:
245
//delete the nodes with ptrs in lists
246
clearRecList(recList);
247
clearRecList(leastRecList);
248
249
//delete composition (and the functions in the Comp object's storage)
250
delete comp;
251
252
return 0;
253
}
254
255
256
/*
257
* Full output
258
*/
259
260
void output(unsigned int shiftSize, int numPoints, string &prefix,
261
const vector<int> &periodList, Comp * comp, list<RecNode*> &recList,
262
vector<string> &commandbuffer) {
263
list<RecNode*>::const_iterator it;
264
265
unsigned int commandbufferit = 0;
266
267
if(DEBUG)
268
cout << "Output\n";
269
270
//output
271
ofstream fout;
272
string fname = prefix + comp->returnName() + ".txt";
273
fout.open(fname.c_str(), ios::trunc | ios::out);
274
275
if(!fout.is_open()) {
276
cout << "ERROR: could not create file " << fname << "\n";
277
return;
278
}
279
280
//HEADER
281
fout << "FProbPeriod 3.67\n";
282
283
/*
284
fout << "N = " << shiftSize << "\n";
285
fout << "K = ";
286
for(i = 0; i < periodList.size(); i++) {
287
fout << periodList[i];
288
if(i != periodList.size() - 1)
289
fout << ",";
290
}
291
fout << "\n";
292
fout << "m = " << numPoints << "\n";
293
*/
294
295
fout << "\n";
296
297
//copy of the input
298
fout << "INPUT\n";
299
fout << "--------------------\n";
300
for(commandbufferit = 0; commandbufferit < commandbuffer.size(); commandbufferit++) {
301
string test;
302
test = commandbuffer[commandbufferit];
303
trim(test);
304
if(test != "") {
305
fout << commandbuffer[commandbufferit] << "\n";
306
}
307
}
308
fout << "--------------------\n";
309
fout << "\n";
310
311
//file for preperiods
312
ofstream fout_preperiod;
313
string fname_preperiod = prefix + comp->returnName() +
314
"_preperiods.txt";
315
fout_preperiod.open(fname_preperiod.c_str(), ios::trunc | ios::out);
316
317
if(!fout_preperiod.is_open()) {
318
cout << "ERROR: could not create file " << fname_preperiod << "\n";
319
return;
320
}
321
322
//HEADER
323
fout_preperiod << "FProbPeriod 3.67\n";
324
/*
325
fout_preperiod << "N = " << shiftSize << "\n";
326
fout_preperiod << "K = ";
327
for(i = 0; i < periodList.size(); i++) {
328
fout_preperiod << periodList[i];
329
if(i != periodList.size() - 1)
330
fout_preperiod << ",";
331
}
332
fout_preperiod << "\n";
333
fout_preperiod << "m = " << numPoints << "\n";
334
*/
335
336
fout_preperiod << "\n";
337
338
//copy of the input
339
fout_preperiod << "INPUT\n";
340
fout_preperiod << "--------------------\n";
341
for(commandbufferit = 0; commandbufferit < commandbuffer.size(); commandbufferit++) {
342
string test;
343
test = commandbuffer[commandbufferit];
344
trim(test);
345
if(test != "") {
346
fout_preperiod << commandbuffer[commandbufferit] << "\n";
347
}
348
}
349
fout_preperiod << "--------------------\n";
350
fout_preperiod << "\n";
351
352
/* Output file */
353
354
//fill on right side, show in fixed notation
355
fout << setiosflags(ios::left | ios::fixed);
356
357
fout << "COMMAND:\n";
358
fout << comp->returnName() << "\n";
359
fout << "WITH DEFINITIONS:\n";
360
comp->printDefinitions(fout);
361
fout << "\n";
362
363
/* Preperiod file */
364
365
//fill on right side, show in fixed notation
366
fout_preperiod << setiosflags(ios::left | ios::fixed);
367
368
fout_preperiod << "Preperiod output\n\n";
369
370
fout_preperiod << "COMMAND:\n";
371
fout_preperiod << comp->returnName() << "\n";
372
fout_preperiod << "WITH DEFINITIONS:\n";
373
comp->printDefinitions(fout_preperiod);
374
fout_preperiod << "\n";
375
376
/* output file */
377
fout << "PERIOD K (NOT LEAST)\n\n";
378
379
/* preperiod file */
380
fout_preperiod << "PERIOD K (NOT LEAST)\n\n";
381
382
/* output file */
383
//Summary info
384
385
fout << "K (AvgPd)^(1/K) (MaxPd)^(1/K) (AvgPrepd)^(1/K) (MaxPrepd)^(1/K)\n";
386
387
for(it = recList.begin(); it != recList.end(); it++) {
388
fout << setw(3) << (*it)->currPeriod << " ";
389
390
if((*it)->pending) {
391
fout << "PENDING" << "\n";
392
}
393
else {
394
fout << setw(13) << setprecision(4) <<
395
pow((*it)->avgPeriod(),((double)1/((double)(*it)->currPeriod))) << " ";
396
fout << setw(13) << setprecision(4) <<
397
pow((*it)->maxPeriod(),((double)1/(double)(*it)->currPeriod)) << " ";
398
fout << setw(16) << setprecision(4) <<
399
pow((*it)->avgPreperiod(),((double)1/((double)(*it)->currPeriod))) << " ";
400
fout << setw(16) << setprecision(4) <<
401
pow((*it)->maxPreperiod(), ((double)1/((double)(*it)->currPeriod))) <<"\n";
402
}
403
}
404
fout <<"\n";
405
406
fout << "K AvgPd MaxPd AvgPrepd MaxPrepd\n";
407
408
for(it = recList.begin(); it != recList.end(); it++) {
409
fout << setw(3) << (*it)->currPeriod << " ";
410
411
if((*it)->pending) {
412
fout << "PENDING" << "\n";
413
}
414
else {
415
fout << setw(13) << setprecision(2) << (*it)->avgPeriod() << " ";
416
fout << setw(13) << setprecision(2) << (*it)->maxPeriod() << " ";
417
fout << setw(16) << setprecision(2) << (*it)->avgPreperiod() << " ";
418
fout << setw(16) << setprecision(2) << (*it)->maxPreperiod() <<"\n";
419
}
420
}
421
422
//orbit and period multiplicity
423
fout << "\n";
424
fout << "K Period Mult(#points)\n";
425
for(it = recList.begin(); it != recList.end(); it++) {
426
fout << setw(3) << (*it)->currPeriod << " ";
427
428
if((*it)->pending) {
429
fout << "PENDING" << "\n";
430
}
431
else {
432
map<unsigned long long, unsigned long long>::const_iterator pitpoint;
433
bool pfirst = true;
434
435
//note that the period and orbit maps have the same periods in the same orders
436
// so we can iterate through both at once
437
for(pitpoint = (*it)->periodMap.begin();
438
pitpoint != (*it)->periodMap.end(); pitpoint++) {
439
if(!pfirst) {
440
fout << " ";
441
}
442
else {
443
pfirst = false;
444
}
445
446
fout << setw(11) << pitpoint->first << " ";
447
fout << setw(13) << pitpoint->second << "\n"; //points
448
}
449
}
450
}
451
452
/* Preperiod file */
453
454
//Preperiod multiplicity
455
fout_preperiod << "K Preperiod Mult\n";
456
for(it = recList.begin(); it != recList.end(); it++) {
457
fout_preperiod << setw(3) << (*it)->currPeriod << " ";
458
459
if((*it)->pending) {
460
fout_preperiod << "PENDING" << "\n";
461
}
462
else {
463
map<unsigned long long, unsigned long long>::const_iterator pit;
464
bool pfirst = true;
465
466
for(pit = (*it)->preperiodMap.begin(); pit != (*it)->preperiodMap.end();
467
pit++) {
468
if(!pfirst) {
469
fout_preperiod << " ";
470
}
471
else {
472
pfirst = false;
473
}
474
475
fout_preperiod << setw(11) << pit->first << " ";
476
fout_preperiod << setw(13) << pit->second << "\n";
477
}
478
}
479
}
480
481
//DONE
482
fout_preperiod.close();
483
fout.close();
484
}
485
486
void probExp(unsigned int shiftSize, const vector<int> &periodList,
487
Comp *comp, int numPoints, list<RecNode*> &recList,
488
string &prefix, vector<string> &commandbuffer) {
489
unsigned int i = 0; //k = 0; //counters
490
unsigned long long j;
491
unsigned int currPeriod;
492
int point_it;
493
494
map<StorageKey,unsigned long long> tree; //records points that we have seen
495
496
list<RecNode*>::const_iterator recIterator;
497
498
//initialize random number generator
499
MTRand random;
500
501
if(DEBUG)
502
cout << "Arrays\n";
503
504
if(DEBUG)
505
random.seed(2005); //hand seed
506
507
//make a list of recNodes, one recNode per K value
508
for(i =0; i < periodList.size(); i++) {
509
recList.push_back(new RecNode(periodList[i], numPoints));
510
}
511
512
//initialize recIterator
513
recIterator = recList.begin();
514
515
//do for every K value
516
for(i = 0; i < periodList.size(); i++) {
517
currPeriod = periodList[i];
518
519
//record keeping
520
RecNode *record = *recIterator;
521
522
//start the sampled test
523
for(point_it = 0; point_it < numPoints; point_it++) {
524
byte cWord[currPeriod]; //curr word
525
byte output[currPeriod]; //helper word
526
unsigned long long period = 0, preperiod = 0;
527
map<StorageKey,unsigned long long>::iterator rt;
528
529
tree.clear(); //clear the tree
530
531
//Set current word to random point
532
for(j = 0; j < currPeriod; j++) {
533
cWord[j] = random.randInt(shiftSize - 1);
534
}
535
536
//insert the first word into tree
537
StorageKey sk1 = StorageKey(cWord, currPeriod);
538
tree.insert(pair<StorageKey,unsigned long long>(sk1,0));
539
540
//DEBUG
541
if(DEBUG >= 5) {
542
cout << "\n\n-- Start orbit --\n";
543
printArray(cWord, currPeriod);
544
}
545
546
//Perform experiment
547
j = 1;
548
while(true) {
549
comp->image(cWord, currPeriod, output);
550
copyWord(cWord, output, currPeriod);
551
552
//DEBUG
553
if(DEBUG >= 5)
554
printArray(cWord, currPeriod);
555
556
StorageKey sk2 = StorageKey(cWord, currPeriod);
557
558
rt = tree.find(sk2);
559
if(rt != tree.end()) {
560
break;
561
}
562
else {
563
tree.insert(pair<StorageKey,unsigned long long>(sk2,j));
564
}
565
566
j++;
567
}
568
569
period = j - rt->second;
570
preperiod = rt->second;
571
572
record->recordPeriod(period, preperiod);
573
}
574
575
record->pending = false;
576
577
//advance recIterator to next in list
578
recIterator++;
579
580
if(OUTPUT_AFTER_EACH) {
581
output(shiftSize, numPoints, prefix, periodList, comp, recList,
582
commandbuffer);
583
}
584
}
585
}
586
587
void probExpTwoShift(const vector<int> &periodList,
588
Comp *comp, int numPoints, list<RecNode*> &recList,
589
string &prefix, vector<string> &commandbuffer) {
590
unsigned int i = 0;
591
unsigned long long j = 0; //k = 0; //counters
592
unsigned int currPeriod;
593
int point_it;
594
595
map<StorageKeyUInt, unsigned long long> tree;
596
597
list<RecNode*>::const_iterator recIterator;
598
599
MTRand random;
600
601
if(DEBUG)
602
random.seed(2005); //hand seed
603
604
if(DEBUG)
605
cout << "Special case 2-shift\n";
606
607
for(i = 0; i < periodList.size(); i++) {
608
recList.push_back(new RecNode(periodList[i], numPoints));
609
}
610
611
recIterator = recList.begin();
612
613
for(i = 0; i < periodList.size(); i++) {
614
unsigned int blocks;
615
currPeriod = periodList[i];
616
617
blocks = (int) ceil( ((double)currPeriod) / ((double)UINTSIZE) );
618
619
if(DEBUG) {
620
cout << "K = " << currPeriod << " blocks = " << blocks << "\n";
621
}
622
623
RecNode *record = *recIterator;
624
625
for(point_it = 0; point_it < numPoints; point_it++) {
626
627
unsigned int cWord[blocks]; //curr word
628
unsigned int output[blocks]; //helper word
629
unsigned long long period = 0, preperiod = 0;
630
map<StorageKeyUInt,unsigned long long>::iterator rt;
631
632
//clear the tree
633
tree.clear();
634
635
//set cWord to a random word
636
//NOTE: it is very important to clear the array first or
637
//else you may start out with junk
638
for(j = 0; j < blocks; j++) {
639
cWord[j] = 0;
640
}
641
642
int blocki = 0, offseti = 0;
643
for(j = 0; j < currPeriod; j++) {
644
cWord[blocki] |= (random.randInt(1) << (offseti));
645
646
offseti++;
647
if(offseti >= UINTSIZE) {
648
blocki++;
649
offseti -= UINTSIZE;
650
}
651
}
652
653
tree.insert(pair<StorageKeyUInt, unsigned long long>(StorageKeyUInt(cWord, blocks), 0));
654
655
//DEBUG
656
if(DEBUG >= 5) {
657
cout << "\n-- Start Orbit --\n";
658
printUIntArray(cWord, currPeriod);
659
cout << "\n";
660
}
661
662
//Perform experiment
663
j = 1;
664
while(true) {
665
//NOTE: no need to clear output[]. Comp::image will automatically
666
//initialize output[] to 0's and then fill it in.
667
668
comp->image(cWord, currPeriod, output, blocks);
669
670
copyUIntArray(cWord, output, blocks);
671
672
//DEBUG
673
if(DEBUG >= 5) {
674
printUIntArray(cWord, currPeriod);
675
cout << "\n";
676
}
677
678
StorageKeyUInt sk(cWord,blocks);
679
680
rt = tree.find(sk);
681
if(rt != tree.end()) {
682
break;
683
}
684
else {
685
tree.insert(pair<StorageKeyUInt, unsigned long long>(sk, j));
686
}
687
688
j++;
689
}
690
691
period = j - rt->second;
692
preperiod = rt->second;
693
694
record->recordPeriod(period, preperiod);
695
}
696
697
record->pending = false;
698
699
//advance recIterator to next in list
700
recIterator++;
701
702
if(OUTPUT_AFTER_EACH) {
703
output(2, numPoints, prefix, periodList, comp, recList, commandbuffer);
704
}
705
}
706
}
707
708
void convertPeriodList(const string &strInput,
709
vector<int> &periodList) {
710
vector<string> strList; //all terms
711
vector<string> subList; //vector representation of an "[a,b]" term
712
unsigned int strListLength = 0, i = 0;
713
714
split(strInput,';', strList);
715
strListLength = strList.size();
716
717
for(i = 0; i < strListLength; i++) {
718
string *temp = &(strList[i]);
719
720
trim(*temp);
721
722
if((*temp)[0] == '[') {
723
int j, low, high;
724
725
temp->erase(0,1); //remove '['
726
temp->erase(temp->length() - 1, 1); //remove ']'
727
728
split(*temp, ',', subList);
729
730
trim(subList[0]);
731
trim(subList[1]);
732
733
low = atoi(subList[0].c_str());
734
high = atoi(subList[1].c_str());
735
736
for(j = low; j <= high; j++) {
737
periodList.push_back(j);
738
}
739
740
subList.clear();
741
}
742
else {
743
periodList.push_back(atoi(temp->c_str()));
744
}
745
}
746
}
747
748
/*
749
* Delete the nodes pointed to by ptrs in recList
750
*/
751
void clearRecList(list<RecNode*> &recList) {
752
list<RecNode*>::iterator it;
753
754
for(it = recList.begin(); it != recList.end(); it++) {
755
delete (*it);
756
}
757
}
758
759
/*
760
* Delete the nodes pointed to by the values in the table
761
*/
762
void clearStorageNodes(vector<StorageVal*> &table) {
763
vector<StorageVal*>::iterator it;
764
765
for(it = table.begin(); it != table.end(); it++) {
766
delete (*it);
767
}
768
}
769
770
/*
771
* Find divisors of X, excluding X itself
772
*/
773
void findDivisors(unsigned int x, vector<int> &divisorsList) {
774
unsigned int i = 2;
775
unsigned int halfX = x/2;
776
777
divisorsList.clear();
778
779
if(x > 1) {
780
divisorsList.push_back(1);
781
}
782
783
for(i = 2; i <= halfX; i++) {
784
if(x % i == 0) {
785
divisorsList.push_back(i);
786
}
787
}
788
}
789
790
/*
791
* returns true if this word has least period p
792
*/
793
bool leastPeriod(byte *word, unsigned int currPeriod,
794
const vector<int> &divisorsList) {
795
bool result = false;
796
unsigned int i, j, k;
797
798
if(currPeriod == 1)
799
return true;
800
801
//for every divisor d
802
for(i = 0; i < divisorsList.size(); i++) {
803
unsigned int d = divisorsList[i];
804
805
result = false;
806
807
//check in chunks of length d
808
for(j = 0; j < currPeriod; j+= d) {
809
//check that this chunk is same as other chunks
810
for(k = 0; k < d; k++) {
811
if(word[k + j] != word[k]) {
812
result = true;
813
break;
814
}
815
}
816
817
if(result == true)
818
break;
819
}
820
821
if(result == false)
822
break;
823
}
824
825
return result;
826
}
827
828
/*
829
* returns true if this word has least period p
830
*/
831
bool leastPeriod(unsigned int word, unsigned int currPeriod,
832
const vector<int> &divisorsList) {
833
bool result = false;
834
unsigned int i, j, k;
835
836
if(currPeriod == 1)
837
return true;
838
839
//for every divisor d
840
for(i = 0; i < divisorsList.size(); i++) {
841
unsigned int d = divisorsList[i];
842
843
result = false;
844
845
//check in chunks of length d
846
for(j = 0; j < currPeriod; j+= d) {
847
//check that this chunk is same as other chunks
848
for(k = 0; k < d; k++) {
849
if(((word >> (k + j)) & 1) != ((word >> k) & 1)) {
850
result = true;
851
break;
852
}
853
}
854
855
if(result == true)
856
break;
857
}
858
859
if(result == false)
860
break;
861
}
862
863
return result;
864
}
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881