var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _.filter(products, function(product){
             return (!product.containsNuts &&
                      _.all(product.ingredients, function(ingredient){
                        return !(ingredient === "mushrooms")
                      })
                    )
        });

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = _.reduce(_.range(1000), function(sum, num){
      if (num % 3 === 0 || num % 5 === 0) return sum + num
        else return sum;
    },0);    /* try chaining range() and reduce() */

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var ingredientName = 'mushrooms';
    /* chain() together map(), flatten() and reduce() */
    //ingredientCount[ingredientName] = products
       var afterMap = _.map(products, function(product){
          return product.ingredients;
        });
        console.log('after map:', afterMap);
        var afterFlatten = _.flatten(afterMap);
        console.log('after flatten:', afterFlatten);
        var afterReduce = _.reduce(afterFlatten, function(item){
          if (item === ingredientName) {
            ingredientCount[ingredientName] += 1;
          }
          return ingredientCount;
        },{ingredientName: 0});
        console.log('after reduce:', afterReduce);
        ingredientCount = afterReduce;

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {


  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});

@@ -3335,47 +3335,8 @@
 0 %7D;
-%0A%0A    var ingredientName = 'mushrooms';
 %0A   
@@ -3384,24 +3384,68 @@
  reduce() */
+%0A%0A    var ingredientName = 'mushrooms';%0A    
 %0A    //ingre
@@ -3798,66 +3798,270 @@
 on(i
-tem)%7B%0A          if (item === ingredientName) %7B%0A           
+ngredientCount, item)%7B%0A          console.log('item: ', item);%0A          if (item === ingredientName) %7B%0A            console.log('item: ',item);%0A            if (!ingredientCount%5BingredientName%5D)%0A                ingredientCount%5BingredientName%5D = 1;%0A            else
  ing
@@ -4151,17 +4151,17 @@
       %7D,
-%7B
+ 
 ingredie
@@ -4166,16 +4166,13 @@
 ient
-Name: 0%7D
+Count
 );%0A 

Complete koans 53 in 9.AboutApplyingWhatWeHaveLearned.js