diff --git a/spec/euler/level1/bowling_spec.clj b/spec/euler/level1/bowling_spec.clj new file mode 100644 index 0000000..75c43e7 --- /dev/null +++ b/spec/euler/level1/bowling_spec.clj @@ -0,0 +1,31 @@ +(ns euler.level1.bowling-spec + (:use + [speclj.core] + [euler.level1.bowling])) + +(describe "Bowling Game " + + (it "gutter game - no pins scores 0" + (should= 0 (score (repeat 0)))) + + (it "all 1s - score is sum of pins" + (should= 20 (score (repeat 1)))) + + (it "spare adds the next roll" + (should= 16 (score [4 6 3]))) + + (it "strike add next two rolls" + (should= 16 (score [10 1 2]))) + + (it "perfect game - all strikes" + (should= 300 (score (repeat 10)))) + + (it "->frames" + (should= [] (->frames [])) + (should= [[1]] (->frames [1])) + (should= [[1 2][3 4]] (->frames [1 2 3 4])) + (should= [[4 6 3][3]] (->frames [4 6 3])) + (should= [[10 1 2][1 2]] (->frames [10 1 2]))) + ) + +(run-specs) diff --git a/spec/euler/level1/problem001_spec.clj b/spec/euler/level1/problem001_spec.clj index 83421ee..3a28486 100644 --- a/spec/euler/level1/problem001_spec.clj +++ b/spec/euler/level1/problem001_spec.clj @@ -7,9 +7,19 @@ (describe "Euler Problem #1" + (it "finds multiples of 3 and 5" + (should= false (multiple-of-3-or-5? 1)) + (should= true (multiple-of-3-or-5? 3)) + (should= true (multiple-of-3-or-5? 10)) + ) + (it "Solves #1" (should= 23 (euler-1 10)) - (should= -1 (euler-1 1000))) + (should= 3 (euler-1 4)) + (should= 8 (euler-1 6)) + (should= 33 (euler-1 11)) + (should= 233168 (euler-1 1000)) + ) ) (run-specs) diff --git a/spec/euler/level1/problem002_spec.clj b/spec/euler/level1/problem002_spec.clj new file mode 100644 index 0000000..0b555de --- /dev/null +++ b/spec/euler/level1/problem002_spec.clj @@ -0,0 +1,28 @@ +(ns euler.level1.problem002-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem002 :refer :all])) + +; https://projecteuler.net/problem=2 + +(describe "Euler Problem #2" + + (it "fib" + (should= '(1) (fib 1)) + (should= '(1 2) (fib 2)) + (should= '(1 2 3) (fib 3)) + (should= '(1 2 3 5) (fib 4)) + (should= '(1 2 3 5 8 13) (fib 6)) + (should= 3524578 (last (fib 32))) + (should= 5702887 (last (fib 33))) + ) + + (it "euler-2" + (should= 4613732 (euler-2 32)) + ) + + ) + + + +(run-specs) diff --git a/spec/euler/level1/problem003_spec.clj b/spec/euler/level1/problem003_spec.clj new file mode 100644 index 0000000..617e520 --- /dev/null +++ b/spec/euler/level1/problem003_spec.clj @@ -0,0 +1,17 @@ +(ns euler.level1.problem003-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem003 :refer :all])) + +; https://projecteuler.net/problem=3 + +(describe "Euler Problem #3" + + (it "Solves #3" + (should= 7 (euler-3 7)) + (should= 29 (euler-3 13195)) + (should= 6857 (euler-3 600851475143)) + ) + ) + +(run-specs) diff --git a/spec/euler/level1/problem004_spec.clj b/spec/euler/level1/problem004_spec.clj new file mode 100644 index 0000000..5064ef7 --- /dev/null +++ b/spec/euler/level1/problem004_spec.clj @@ -0,0 +1,21 @@ +(ns euler.level1.problem004-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem004 :refer :all])) + +; https://projecteuler.net/problem=4 + +(describe "Euler Problem #4" + + (it "palindrome?" + (should= false (palindrome? 21)) + (should= true (palindrome? 1)) + (should= true (palindrome? 121))) + + (it "Solves #4" + (should= 9009 (euler-4 2)) + (should= 906609 (euler-4 3)) + ) + ) + +(run-specs) diff --git a/spec/euler/level1/problem005_spec.clj b/spec/euler/level1/problem005_spec.clj new file mode 100644 index 0000000..3bcc2d3 --- /dev/null +++ b/spec/euler/level1/problem005_spec.clj @@ -0,0 +1,22 @@ +(ns euler.level1.problem005-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem005 :refer :all])) + +; https://projecteuler.net/problem=5 + +(describe "Euler Problem #5" + + (it "divisible" + (should= true (divisible? 10 [2 5])) + (should= false (divisible? 10 [3 5])) + (should= true (divisible? 2520 [2 3 4 5 6 7 8 9 10])) + ) + + (it "Solves #5" + (should= 2520 (euler-5 10)) + (should= 232792560 (euler-5 20)) + ) + ) + +(run-specs) diff --git a/spec/euler/level1/problem006_spec.clj b/spec/euler/level1/problem006_spec.clj new file mode 100644 index 0000000..d5ced06 --- /dev/null +++ b/spec/euler/level1/problem006_spec.clj @@ -0,0 +1,15 @@ +(ns euler.level1.problem006-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem006 :refer :all])) + +; https://projecteuler.net/problem=6 + +(describe "Euler Problem #6" + + (it "Solves #6" + (should= 2640 (euler-6 10)) + (should= 25164150 (euler-6 100))) + ) + +(run-specs) diff --git a/spec/euler/level1/problem007_spec.clj b/spec/euler/level1/problem007_spec.clj new file mode 100644 index 0000000..1d44baf --- /dev/null +++ b/spec/euler/level1/problem007_spec.clj @@ -0,0 +1,32 @@ +(ns euler.level1.problem007-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem007 :refer :all])) + +; https://projecteuler.net/problem=7 + +(describe "Euler Problem #7" + + (it "prime" + (should= true (prime? 1)) + (should= true (prime? 2)) + (should= true (prime? 3)) + (should= false (prime? 4)) + (should= false (prime? 6)) + (should= false (prime? 9)) + ) + + (it "next-prime" + (should= 7 (next-prime 5)) + (should= 3 (next-prime 2)) + (should= 11 (next-prime 7)) + ) + + (it "Solves #7" + (should= 13 (euler-7 6)) + ;(should= 104743 (euler-7 10001)) + ) + + ) + +(run-specs) diff --git a/spec/euler/level1/problem008_spec.clj b/spec/euler/level1/problem008_spec.clj new file mode 100644 index 0000000..55a2134 --- /dev/null +++ b/spec/euler/level1/problem008_spec.clj @@ -0,0 +1,26 @@ +(ns euler.level1.problem008-spec + (:require + [speclj.core :refer :all] + [euler.level1.problem008 :refer :all])) + +; https://projecteuler.net/problem=8 + +(describe "Euler Problem #8" + + (it "segment-by-digits" + (should= "7316" (first (segment-by-digits 4))) + (should= "3167" (second (segment-by-digits 4))) + (should= "3450" (last (segment-by-digits 4))) + ) + + (it "digits-product" + (should= (* 2 3 4) (digits-product 234)) + ) + + (it "Solves #8" + (should= 5832 (euler-8 4)) + (should= 23514624000 (euler-8 13)) + ) + ) + +(run-specs) diff --git a/src/euler/level1/bowling.clj b/src/euler/level1/bowling.clj new file mode 100644 index 0000000..4e49116 --- /dev/null +++ b/src/euler/level1/bowling.clj @@ -0,0 +1,24 @@ +(ns euler.level1.bowling) + +(defn sum [nums] + (reduce + nums)) + +(defn spare? [rolls] + (= (sum (take 2 rolls)) 10)) + +(defn strike? [rolls] + (= (first rolls) 10)) + +(defn ->frames [rolls] + (if (empty? rolls) + [] + (cons + (if (or (spare? rolls) (strike? rolls)) + (take 3 rolls) + (take 2 rolls)) + (lazy-seq (->frames (if (strike? rolls) + (drop 1 rolls) + (drop 2 rolls))))))) + +(defn score [rolls] + (sum (flatten (take 10 (->frames rolls))))) \ No newline at end of file diff --git a/src/euler/level1/problem001.clj b/src/euler/level1/problem001.clj index 9458aa3..95759b0 100644 --- a/src/euler/level1/problem001.clj +++ b/src/euler/level1/problem001.clj @@ -1,4 +1,10 @@ (ns euler.level1.problem001) -(defn euler-1 [n] +(defn multiple-of-3-or-5? [n] + (or (zero? (mod n 3)) (zero? (mod n 5))) ) + +(defn euler-1 [n] + (->> (range n) + (filter multiple-of-3-or-5?) + (apply +))) diff --git a/src/euler/level1/problem002.clj b/src/euler/level1/problem002.clj new file mode 100644 index 0000000..d509772 --- /dev/null +++ b/src/euler/level1/problem002.clj @@ -0,0 +1,13 @@ +(ns euler.level1.problem002) + + +(defn fib [n] + (->> [0 1] + (iterate (fn [[a b]] [b (+ a b)])) + (map first) + (drop 2) + (take n))) + +(defn euler-2 [n] + (reduce + (filter even? (fib n))) + ) diff --git a/src/euler/level1/problem003.clj b/src/euler/level1/problem003.clj new file mode 100644 index 0000000..27b75f5 --- /dev/null +++ b/src/euler/level1/problem003.clj @@ -0,0 +1,16 @@ +(ns euler.level1.problem003) + +(defn smallest-factor [n] + (first (filter + (fn[x] (= (mod n x) 0)) + ;#(= (mod n %) 0) + (iterate inc 2)))) + +(defn factorize [n] + (let [other (/ n (smallest-factor n))] + (if (= other 1) + n + (factorize other)))) + +(defn euler-3 [n] + (factorize n)) diff --git a/src/euler/level1/problem004.clj b/src/euler/level1/problem004.clj new file mode 100644 index 0000000..c051b8c --- /dev/null +++ b/src/euler/level1/problem004.clj @@ -0,0 +1,26 @@ +(ns euler.level1.problem004) + +(defn palindrome? [s] + (let [s (str s) + len (count s) + last (dec len)] + ;(= (seq s) (reverse s)) + (if (<= len 1) + true + (and + (= (get s 0) (get s last)) + (palindrome? (subs s 1 last)))))) + +(defn products-of-n-digit-numbers [n] + (let [n-digit-nos + (range + (int (Math/pow 10 (- n 1))) + (int (Math/pow 10 n)))] + (flatten + (map (fn [x] + (map (fn [y] (* x y)) n-digit-nos)) n-digit-nos)))) + +(defn euler-4 [n] + (reduce + max + (filter palindrome? (products-of-n-digit-numbers n)))) diff --git a/src/euler/level1/problem005.clj b/src/euler/level1/problem005.clj new file mode 100644 index 0000000..94a1da4 --- /dev/null +++ b/src/euler/level1/problem005.clj @@ -0,0 +1,41 @@ +(ns euler.level1.problem005) + +(defn take-until + "Returns a lazy sequence of successive items from coll until + (pred item) returns true, including that item. pred must be + free of side-effects." + [pred coll] + (lazy-seq + (when-let [s (seq coll)] + (if (pred (first s)) + (cons (first s) nil) + (cons (first s) (take-until pred (rest s))))))) + +(defn divisible? [o divisors] + (if (= o 0) + false + (= + (count divisors) + (count + (filter + zero? + (map + (fn [divisor] + (mod o divisor)) divisors) + ) + ) + ) + ) + ) + + +(defn euler-5 [n] + (let [divisors (range 1 (+ n 1))] + (last + (take-until + (fn [n] + (divisible? n divisors)) + (iterate (fn [x] (+ x 210)) 0)) + ) + ) + ) diff --git a/src/euler/level1/problem006.clj b/src/euler/level1/problem006.clj new file mode 100644 index 0000000..e33a047 --- /dev/null +++ b/src/euler/level1/problem006.clj @@ -0,0 +1,16 @@ +(ns euler.level1.problem006) + +(defn square [n] + (Math/pow n 2)) + +(defn euler-6 [n] + (let [r (map inc (range n))] + (int (- + (square + (reduce + r)) + (reduce + + (map square r) + ) + ) + )) + ) diff --git a/src/euler/level1/problem007.clj b/src/euler/level1/problem007.clj new file mode 100644 index 0000000..668d309 --- /dev/null +++ b/src/euler/level1/problem007.clj @@ -0,0 +1,34 @@ +(ns euler.level1.problem007 + (:require + [euler.level1.problem005 :refer :all]) + ) + +(defn prime? [n] + (let [divisors (range 2 n)] + (empty? + (filter + zero? + (map + (fn [divisor] + (mod n divisor)) divisors) + ) + ) + ) + ) + +(defn next-prime [n] + (inc + (or + (last + (take-while (fn [n] (not (prime? n))) + (iterate inc (inc n))) + ) + n + ) + ) + ) + +(defn euler-7 [n] + (last (take n (iterate + next-prime 2))) + ) diff --git a/src/euler/level1/problem008.clj b/src/euler/level1/problem008.clj new file mode 100644 index 0000000..029aed6 --- /dev/null +++ b/src/euler/level1/problem008.clj @@ -0,0 +1,48 @@ +(ns euler.level1.problem008 + (:require [clojure.string :as string])) + +(def the-number (string/replace "73167176531330624919225119674426574742355349194934 + 96983520312774506326239578318016984801869478851843 + 85861560789112949495459501737958331952853208805511 + 12540698747158523863050715693290963295227443043557 + 66896648950445244523161731856403098711121722383113 + 62229893423380308135336276614282806444486645238749 + 30358907296290491560440772390713810515859307960866 + 70172427121883998797908792274921901699720888093776 + 65727333001053367881220235421809751254540594752243 + 52584907711670556013604839586446706324415722155397 + 53697817977846174064955149290862569321978468622482 + 83972241375657056057490261407972968652414535100474 + 82166370484403199890008895243450658541227588666881 + 16427171479924442928230863465674813919123162824586 + 17866458359124566529476545682848912883142607690042 + 24219022671055626321111109370544217506941658960408 + 07198403850962455444362981230987879927244284909188 + 84580156166097919133875499200524063689912560717606 + 05886116467109405077541002256983155200055935729725 + 71636269561882670428252483600823257530420752963450" #"\r\n|\n|\r| " "")) + +(defn segment-by-digits [n] + (map + (fn [i] + (subs the-number (- i n) i)) + (range n (inc (count the-number)))) + ) + +(defn digits-product [n] + (reduce + (fn [cum char] + (* (- (int char) (int \0)) cum)) + 1 + (str n)) + ) + +(defn euler-8 [n] + (first + (sort > + (map + digits-product + (segment-by-digits n)) + ) + ) + )