"use strict";
var assert = require('assert');

var basic = function(n) {
  var values = [];
  while (n !== 1) {
    values.push(n);
    if (n % 2 === 0) {
      n /= 2;
    } else {
      n = n * 3 + 1;
    }
  }
  values.push(1);
  return values;
};

var cycleLength = function(n) {
  var c = 1;
  while (n !== 1) {
    c++;
    if (n % 2 === 0) {
      n /= 2;
    } else {
      n = n * 3 + 1;
    }
  }
  return c;
};


var memo = function(f) {

  var table = {};
  return function(n) {
    if (!table[n]) {
      table[n] = f(n);
    }

    return table[n];
  };
};

var Chain = function() {
  this.cycleLength = function(n) {
    var c = 1;
    while (n !== 1) {
      c++;
      if (n % 2 === 0) {
        n /= 2;
      } else {
        n = n * 3 + 1;
      }
    }
    return c;    
  };

  return this;
};


describe('3n + 1', function() {
  describe('basics', function() {
    it('returns all values', function() {
      assert.deepEqual(
        [22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1],
        basic(22)
      );
    });

    it('calculates the cycle length', function() {
      assert.equal(16, cycleLength(22));
    });
  });

  describe('table stores all values', function() {
    it('keeps score', function() {
      var chain = new Chain();
      assert.equal(16, chain.cycleLength(22));
    });
  });

  describe('memoizer', function() {
    it('memoizes', function() {
      var callCount = 0;

      var memoed = memo(function(n) { callCount++; return n; });

      memoed(8);
      assert.equal(1, callCount);

      memoed(8);
      assert.equal(1, callCount);
    });
  });
});

@@ -249,180 +249,8 @@
 %7D;%0A%0A
-var cycleLength = function(n) %7B%0A  var c = 1;%0A  while (n !== 1) %7B%0A    c++;%0A    if (n %25 2 === 0) %7B%0A      n /= 2;%0A    %7D else %7B%0A      n = n * 3 + 1;%0A    %7D%0A  %7D%0A  return c;%0A%7D;%0A%0A%0A
 var 
@@ -862,109 +862,8 @@
  %7D);
-%0A%0A    it('calculates the cycle length', function() %7B%0A      assert.equal(16, cycleLength(22));%0A    %7D);
 %0A  %7D

remove redundant crap