aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Wardhaugh <tyler.wardhaugh@gmail.com>2023-05-13 21:22:46 -0700
committerTyler Wardhaugh <tyler.wardhaugh@gmail.com>2023-05-14 00:42:01 -0700
commitde77364dc67d21c432d27b0e97d702b9f0fc1c2c (patch)
tree9e5957badad407bbd8dbe036b7d8e34d0a7eb637
parentf050177981b6b6366ce13693e509abdcb301453f (diff)
downloadperlweeklychallenge-club-de77364dc67d21c432d27b0e97d702b9f0fc1c2c.tar.gz
perlweeklychallenge-club-de77364dc67d21c432d27b0e97d702b9f0fc1c2c.tar.bz2
perlweeklychallenge-club-de77364dc67d21c432d27b0e97d702b9f0fc1c2c.zip
Ch216: solve Tasks 1 & 2 in Clojure
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/README.md16
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/bb.edn2
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/build.clj19
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/deps.edn4
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/src/c216/t1.clj23
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/src/c216/t2.clj54
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/test/c216/t1_test.clj12
-rw-r--r--challenge-216/tyler-wardhaugh/clojure/test/c216/t2_test.clj10
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"])))))