Saturday, September 13, 2014

Refactoring my generalized fizzbuzz to use only applicative higher-order functions

I refactored my my previous version of generalized FizzBuzz, so that, it doesn't use neither for loops nor recursion. Now it only uses: reduce and map.

This is the new code:

var makeSubstitute = function(substitutionDescriptions) {
var substituteNumber = (function() {
var substitutionFns = substitutionDescriptions.map(
function(desc) {
return function(number) {
return desc.pred(number) ? desc.replacement : "";
};
}
);
return function(number) {
var res = substitutionFns.reduce(
function(acc, substite) {
return acc + substite(number)
},
""
);
return res !== "" ? res : String(number);
};
}());
return function(numbers) {
return numbers.map(substituteNumber).join(" ");
};
};

The tests are exactly the same as in the previous version:

describe("FizzBuzz", function () {
var fizzBuzzSubstitute;
beforeEach(function () {
fizzBuzzSubstitute = makeSubstitute([
{ pred: function(number) {return number % 3 == 0;},
replacement: "Fizz"},
{ pred: function(number) {return number % 5 == 0;},
replacement: "Buzz"}
]);
});
it("works for an empty array", function () {
expect(fizzBuzzSubstitute([])).toBe("");
});
it("returns same number for array with number not multiple of 3 or 5", function () {
expect(fizzBuzzSubstitute([1])).toBe("1");
});
it("returns Fizz for an array with a multiple of 3", function () {
expect(fizzBuzzSubstitute([3])).toBe("Fizz");
expect(fizzBuzzSubstitute([9])).toBe("Fizz");
});
it("returns Buzz for an array with a multiple of 5", function () {
expect(fizzBuzzSubstitute([5])).toBe("Buzz");
expect(fizzBuzzSubstitute([25])).toBe("Buzz");
});
it("returns FizzBuzz for an array with a multiple of both 3 and 5", function () {
expect(fizzBuzzSubstitute([15])).toBe("FizzBuzz");
});
it("also works with arrays with more than one element", function () {
expect(fizzBuzzSubstitute([1, 2, 15])).toBe("1 2 FizzBuzz");
});
});
describe("FizzKozz", function () {
var fizzKozzSubstitute = makeSubstitute([
{ pred: function(number) {return number % 3 == 0;},
replacement: "Fizz"},
{ pred: function(number) {return number % 2 == 0;},
replacement: "Kozz"}
]);
it("also works with different substitution rules", function () {
expect(
fizzKozzSubstitute([1, 2, 4, 6, 15])).toBe("1 Kozz Kozz FizzKozz Fizz");
});
});
describe("FizzOddSeven", function () {
var fizzOddSevenSubstitute = makeSubstitute([
{ pred: function(number) {return number % 3 == 0;},
replacement: "Fizz"},
{ pred: function(number) {return number % 2 == 1;},
replacement: "Odd"},
{ pred: function(number) {return number == 7;},
replacement: "Seven"}
]);
it("works with rules using any predicate on a number", function () {
expect(
fizzOddSevenSubstitute(
[1, 2, 4, 6, 15, 7])).toBe("Odd 2 4 Fizz FizzOdd OddSeven");
});
});

Thursday, September 4, 2014

Euler Project: Problem 10 in Clojure

This is my solution in Clojure to the 10th problem from Euler project:

(defn sieve [[nums primes]]
(let [[prime & more] nums]
(vector (remove #(zero? (rem % prime)) nums)
(cons prime primes))))
(defn primes-below [n]
(let [sqrt-n (Math/sqrt n)]
(apply
concat
(first
(drop-while
#(< (ffirst %) sqrt-n)
(iterate sieve [(range 2 (inc n)) nil]))))))
(defn sum-primes-below [n]
(reduce + (primes-below n)))
(sum-primes-below 10) ; 17
(sum-primes-below 100) ; 1060
(sum-primes-below 1000) ; 76127
(sum-primes-below 10000) ; 5736396
(sum-primes-below 100000) ; 454396537
(sum-primes-below 2000000) ; 142913828922
view raw euler-10.clj hosted with ❤ by GitHub

Euler Project: Problem 9 in Clojure

This is my solution in Clojure to the ninth problem from Euler project:

(defn square [x]
(* x x))
(defn pythagorean-triplet? [a b c]
(and (< a b c)
(= (square c) (+ (square a) (square b)))))
(def triplet
(let [nums (range 500)]
(for [a nums
b nums
c nums
:when (and (= 1000 (+ a b c))
(pythagorean-triplet? a b c))]
[a b c])))
triplet ; [200 375 425]
(reduce * triplet) ; 31875000
view raw euler-9.clj hosted with ❤ by GitHub

Wednesday, September 3, 2014

Euler Project: Problem 8 in Clojure

This is my solution in Clojure to the eighth problem from Euler project:

(def huge-num 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450)
(defn parse-int [s]
(Integer. (re-find #"\d+" s )))
(defn- digits-to-numbers [digits]
(map (comp parse-int str) digits))
(defn greatest-product-and-n-digits [huge-num n]
(let
[prod-n-digits-pairs (map #(let [numbers (digits-to-numbers %)]
[(reduce * numbers) numbers])
(partition n 1 (str huge-num)))
max-prod (apply max (map first prod-n-digits-pairs))]
(filter #(= max-prod (first %)) prod-n-digits-pairs)))
(greatest-product-and-n-digits huge-num 4) ; ([5832 (9 9 8 9)])
(greatest-product-and-n-digits huge-num 13) ; ([23514624000 (5 5 7 6 6 8 9 6 6 4 8 9 5)])
(def greatest-product
(comp ffirst greatest-product-and-n-digits))
(greatest-product huge-num 13) ; 23514624000
view raw euler-8.clj hosted with ❤ by GitHub

Tuesday, September 2, 2014

Euler Project: Problem 7 in Clojure

This is my solution in Clojure to the seventh problem from Euler project:

(defn prime? [n]
(loop [n n prime 2 factors []]
(if (> (count factors) 1)
false
(cond
(= n 1) true
(factor? n prime) (recur (/ n prime) prime (conj factors prime))
:else (recur n (inc prime) factors)))))
(def nums (iterate inc 2))
(last (take 10001 (filter prime? nums))) ; 104743
view raw euler-7.clj hosted with ❤ by GitHub

It works but it's quite slow.

Monday, September 1, 2014

Euler Project: Problem 6 in Clojure

This is my solution in Clojure to the sixth problem from Euler project:

(defn pow [x n]
(reduce * (repeat n x)))
(pow 55 2) ; 3025
(defn square [x]
(pow x 2))
(square 55) ; 3025
(def sum (comp (partial reduce +) map))
(sum identity (range 0 11)) ; 55
(sum square (range 0 11)) ; 385
(defn sum-square-difference [n]
(let [nums (range 0 (+ 1 n))]
(- (square (sum identity nums))
(sum square nums))))
(sum-square-difference 10) ; 2640
(sum-square-difference 100) ; 25164150
view raw euler-6.clj hosted with ❤ by GitHub