diff options
| author | Tyler Wardhaugh <tyler.wardhaugh@gmail.com> | 2023-05-13 21:22:46 -0700 |
|---|---|---|
| committer | Tyler Wardhaugh <tyler.wardhaugh@gmail.com> | 2023-05-14 00:42:01 -0700 |
| commit | de77364dc67d21c432d27b0e97d702b9f0fc1c2c (patch) | |
| tree | 9e5957badad407bbd8dbe036b7d8e34d0a7eb637 | |
| parent | f050177981b6b6366ce13693e509abdcb301453f (diff) | |
| download | perlweeklychallenge-club-de77364dc67d21c432d27b0e97d702b9f0fc1c2c.tar.gz perlweeklychallenge-club-de77364dc67d21c432d27b0e97d702b9f0fc1c2c.tar.bz2 perlweeklychallenge-club-de77364dc67d21c432d27b0e97d702b9f0fc1c2c.zip | |
Ch216: solve Tasks 1 & 2 in Clojure
8 files changed, 129 insertions, 11 deletions
diff --git a/challenge-216/tyler-wardhaugh/clojure/README.md b/challenge-216/tyler-wardhaugh/clojure/README.md index acccb9d7f1..530c7479c2 100644 --- a/challenge-216/tyler-wardhaugh/clojure/README.md +++ b/challenge-216/tyler-wardhaugh/clojure/README.md @@ -1,6 +1,6 @@ -# c209 +# c216 -The Weekly Challenge — #209 — Tyler Wardhaugh +The Weekly Challenge — #216 — Tyler Wardhaugh ## Usage @@ -8,21 +8,21 @@ Clojure ([installation instructions](https://clojure.org/guides/getting_started# Run Task #1: - $ clojure -M:t1 COLL + $ clojure -M:t1 REG COLL # ... or ... - $ bb run task-1 COLL + $ bb run task-1 REG COLL # Alternatively, to run it via Babashka: - $ bb run task-1-bb COLL + $ bb run task-1-bb REG COLL Run Task #2: - $ clojure -M:t2 COLL + $ clojure -M:t2 WORD COLL # ... or ... - $ bb run task-2 COLL + $ bb run task-2 WORD COLL # Alternatively, to run it via Babashka: - $ bb run task-2-bb COLL + $ bb run task-2-bb WORD COLL Run the project's tests (which are samples from the task descriptions): diff --git a/challenge-216/tyler-wardhaugh/clojure/bb.edn b/challenge-216/tyler-wardhaugh/clojure/bb.edn index 7acc226111..f62b373e9f 100644 --- a/challenge-216/tyler-wardhaugh/clojure/bb.edn +++ b/challenge-216/tyler-wardhaugh/clojure/bb.edn @@ -1,6 +1,6 @@ { :paths ["src" "resources"] - :deps {c209/c209 {:local/root "."}} + :deps {c216/c216 {:local/root "."}} :tasks { diff --git a/challenge-216/tyler-wardhaugh/clojure/build.clj b/challenge-216/tyler-wardhaugh/clojure/build.clj new file mode 100644 index 0000000000..a089c2dbd1 --- /dev/null +++ b/challenge-216/tyler-wardhaugh/clojure/build.clj @@ -0,0 +1,19 @@ +(ns build + (:refer-clojure :exclude [test]) + (:require [org.corfield.build :as bb])) + +(def lib 'net.clojars.c216/c216) +(def version "0.1.0-SNAPSHOT") +(def main 'c216.c216) + +(defn test "Run the tests." [opts] + (bb/run-tests opts)) + +(def clean bb/clean) + +(defn ci "Run the CI pipeline of tests (and build the uberjar)." [opts] + (-> opts + (assoc :lib lib :version version :main main) + (bb/run-tests) + (bb/clean) + (bb/uber))) diff --git a/challenge-216/tyler-wardhaugh/clojure/deps.edn b/challenge-216/tyler-wardhaugh/clojure/deps.edn index 74c8d4ec8e..0459e1f12d 100644 --- a/challenge-216/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-216/tyler-wardhaugh/clojure/deps.edn @@ -1,8 +1,8 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.11.1"}} :aliases - {:t1 {:main-opts ["-m" "c209.t1"]} - :t2 {:main-opts ["-m" "c209.t2"]} + {:t1 {:main-opts ["-m" "c216.t1"]} + :t2 {:main-opts ["-m" "c216.t2"]} :build {:deps {io.github.seancorfield/build-clj {:git/tag "v0.8.3" :git/sha "7ac1f8d" ;; since we're building an app uberjar, we do not diff --git a/challenge-216/tyler-wardhaugh/clojure/src/c216/t1.clj b/challenge-216/tyler-wardhaugh/clojure/src/c216/t1.clj new file mode 100644 index 0000000000..88c13102d6 --- /dev/null +++ b/challenge-216/tyler-wardhaugh/clojure/src/c216/t1.clj @@ -0,0 +1,23 @@ +(ns c216.t1 + (:require + [clojure.edn :as edn] + [clojure.set :as set] + [clojure.string :as str])) + +(def DEFAULT-INPUT ["AB1 2CD" ["abc" "abcd" "bcd"]]) + +(defn registration-number + [reg coll] + (let [clean-reg (into #{} + (comp + (filter #(Character/isLetter %)) + (map (comp first str/lower-case))) + reg)] + (filter #(set/subset? clean-reg (set %)) coll))) + +(defn -main + "Run Task 1 with a given input REG & COLL, defaulting to the first example + from the task description." + [& args] + (let [[reg coll] (or (some->> args (map edn/read-string)) DEFAULT-INPUT)] + (prn (registration-number reg coll)))) diff --git a/challenge-216/tyler-wardhaugh/clojure/src/c216/t2.clj b/challenge-216/tyler-wardhaugh/clojure/src/c216/t2.clj new file mode 100644 index 0000000000..2be7755997 --- /dev/null +++ b/challenge-216/tyler-wardhaugh/clojure/src/c216/t2.clj @@ -0,0 +1,54 @@ +(ns c216.t2 + (:require + [clojure.edn :as edn] + [clojure.set :as set])) + +(def DEFAULT-INPUT ["peon" ["perl" "raku" "python"]]) + +(defn dict-weight + [dict] + (reduce + 0 (vals dict))) + +(defn dict-common-keys + [a b] + (set/intersection (set (keys a)) (set (keys b)))) + +(defn dict-left-keys + [a b] + (select-keys b (dict-common-keys a b))) + +(defn dict-intersect + [a b] + (let [common-b (dict-left-keys a b) + before (+ (dict-weight a) (dict-weight common-b)) + after (dict-weight (merge-with - a common-b))] + [(- before after) common-b])) + +(defn dict-minus + [a b] + (->> (dict-left-keys a b) + (merge-with - a) + (into {} (filter (fn [[_ v]] (pos? v)))))) + +(defn word-stickers + [word coll] + (if (seq (set/difference (set word) (transduce (map set) set/union coll))) + 0 + (let [counts (into [] (map frequencies) coll) + letters (frequencies word)] + (loop [letters letters + result 0] + (if (empty? letters) + result + (let [best (->> counts + (map #(dict-intersect letters %)) + (apply max-key first) + second)] + (recur (dict-minus letters best) (inc result)))))))) + +(defn -main + "Run Task 2 with a given input WORD & COLL, defaulting to the first example + from the task description." + [& args] + (let [[word coll] (or (some->> args (map edn/read-string)) DEFAULT-INPUT)] + (println (word-stickers word coll)))) diff --git a/challenge-216/tyler-wardhaugh/clojure/test/c216/t1_test.clj b/challenge-216/tyler-wardhaugh/clojure/test/c216/t1_test.clj new file mode 100644 index 0000000000..ee78084a03 --- /dev/null +++ b/challenge-216/tyler-wardhaugh/clojure/test/c216/t1_test.clj @@ -0,0 +1,12 @@ +(ns c216.t1-test + (:require [clojure.test :refer [deftest is testing]] + [c216.t1 :refer [registration-number]])) + +(deftest task-1 + (testing "Task 1 produces the correct results from examples in the description" + (is (= ["abcd"] + (registration-number "AB1 2CD" ["abc" "abcd" "bcd"]))) + (is (= ["job" "bjorg"] + (registration-number "007 JB" ["job" "james" "bjorg"]))) + (is (= ["crack" "rac"] + (registration-number "C7 RA2" ["crack" "road" "rac"]))))) diff --git a/challenge-216/tyler-wardhaugh/clojure/test/c216/t2_test.clj b/challenge-216/tyler-wardhaugh/clojure/test/c216/t2_test.clj new file mode 100644 index 0000000000..47b4437c95 --- /dev/null +++ b/challenge-216/tyler-wardhaugh/clojure/test/c216/t2_test.clj @@ -0,0 +1,10 @@ +(ns c216.t2-test + (:require [clojure.test :refer [deftest is testing]] + [c216.t2 :refer [word-stickers]])) + +(deftest task-2 + (testing "Task 2 produces the correct results from examples in the description" + (is (= 2 (word-stickers "peon" ["perl" "raku" "python"]))) + (is (= 3 (word-stickers "goat" ["love" "hate" "angry"]))) + (is (= 4 (word-stickers "accommodation" ["come" "nation" "delta"]))) + (is (= 0 (word-stickers "accommodation" ["come" "country" "delta"]))))) |
