-
Notifications
You must be signed in to change notification settings - Fork 0
/
collatz.js
106 lines (89 loc) · 3.75 KB
/
collatz.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var bigInt = require("big-integer");
/*******************************************************************************************************/
/*DEFINITION AND ELEMENTARY METHODS*/
/*******************************************************************************************************/
var Collatz = function(n){
/* private */
this._number = new bigInt(n);
this._stoppingTime = -1;
this._length = -1;
this._sequence=[];
this._initObj=function(){
this._stoppingTime=-1;
this._length=-1;
this._sequence=[];
}
this.number(n);
}
/* Collatz.prototype.init */
Collatz.prototype.init = function(){
var i=bigInt(this._number);
while(!i.equals(1)){
i=getNextCollatz(i);
this._sequence.push(i.toString());
if (i<this._number && this._stoppingTime==-1){
this._stoppingTime=this._sequence.length;
}
}
}
/* Collatz.prototype.number */
Collatz.prototype.number = function(m){
if (typeof m === "undefined") return this._number.toString();
if (!/^\+?(0|[1-9]\d*)$/.test(m)) { throw new Error(m+" is not a positive number"); }
this._number=bigInt(m);
this._initObj();
}
/* Collatz.prototype.stoppingTime */
Collatz.prototype.stoppingTime = function(m){if (this._length==-1) this.init(); return this._stoppingTime;}
/* Collatz.prototype.length */
Collatz.prototype.length = function(m){if (this._length==-1) this.init(); return this._sequence.length;}
/* Collatz.prototype.sequence */
Collatz.prototype.sequence = function(m){if (this._length==-1) this.init(); return this._sequence;}
/* Collatz.prototype.toString */
Collatz.prototype.toString = function(){return this._number.toString()};
/*******************************************************************************************************/
/* ITERATOR METHODS */
/*******************************************************************************************************/
/* Collatz.prototype.iterate */
Collatz.prototype.iterate = function(){this.number(getNextCollatz(this._number)); return this.number();}
/* Collatz.prototype.isOne */
Collatz.prototype.isOne = function(){ return this._number.equals(bigInt.one);}
/*******************************************************************************************************/
/* ARRAY FUNCTIONS*/
/*******************************************************************************************************/
/* Collatz.prototype.lengths */
/*for an array starting from this._number to this._number */
Collatz.prototype.lengths = function(m,s){
return this.arrayFn(m,s,"length");
}
/* Collatz.prototype.stoppingTimes */
Collatz.prototype.stoppingTimes = function(m,s){
return this.arrayFn(m,s,"stoppingTime");
}
/* Collatz.prototype.arraFn */
Collatz.prototype.arrayFn = function(m,s,parameter){
if (typeof m === "undefined") throw new Error("offset is needed");
if (!(/^\+?(0|[1-9]\d*)$/.test(m) && /^\+?(0|[1-9]\d*)$/.test(s))) throw new Error(m + " or " + s + " are not a positive numbers");
if (!(parameter =="length" || parameter =="stoppingTime")) throw new Error(parameter + "is a wrong parameter");
var offset = bigInt(m);
var array=[];
var orig_number=this._number.toString();
var max_number=this._number.add(offset);
var iter = bigInt(this._number);
while (iter.lt(max_number)){
iter=iter.add(s);
this.number(iter);
if (parameter=="length"){
array.push(this.length());
}
else{
array.push(this.stoppingTime());
}
}
this.number(orig_number);
return array;
}
/*******************************************************************************************************/
module.exports = {Collatz: Collatz};
/*******************************************************************************************************/
function getNextCollatz(n){var m=bigInt(n); return (m.mod(2).equals(0) ? m.divide(2) : m.times(3).add(1));}