function generator(sequencer) { return sequencer.apply( null, [] .slice .call(arguments) .slice(1) ); } function dummySeq() { this.next = function() { return "dummy"; }; return this; } function factorialSeq() { this.n = 1; this.i = 0; this.next = function() { const value = this.n; this.i++; this.n *= this.i; return value; }; return this; } function fibonacciSeq() { this.prev = 0; this.current = 1; this.next = function() { const value = this.current; const newValue = this.prev + this.current; this.prev = this.current; this.current= newValue; return value; }; return this; } function rangeSeq(start, step) { this.value = start; this.step = step; this.next = function() { const oldValue = this.value; this.value += this.step; return oldValue; }; return this; } function primeSeq() { const isPrime = function(n) { const top = Math.floor(Math.sqrt(n)); for (let i = 2; i <= top; i++) { if (n % i == 0) { return false; } } return true; }; const nextPrime = function(n) { n++; while (!isPrime(n)) { n++; } return n; }; this.p = 1; this.next = function() { this.p = nextPrime(this.p); return this.p; }; return this; } function partialSumSeq() { this.values = arguments; this.length = arguments.length; this.runningSum = 0; this.i = 0; this.next = function() { if (this.i >= this.length) { throw new RangeError("All input was processed!"); } this.runningSum += this.values[this.i++]; return this.runningSum; }; return this; }