diff options
11 files changed, 231 insertions, 21 deletions
diff --git a/challenge-076/tyler-wardhaugh/clojure/README.md b/challenge-076/tyler-wardhaugh/clojure/README.md index 4bc8af0088..a46a7a9fc9 100644 --- a/challenge-076/tyler-wardhaugh/clojure/README.md +++ b/challenge-076/tyler-wardhaugh/clojure/README.md @@ -1,25 +1,25 @@ -# tw.weekly.c75 +# tw.weekly.c76 -The Weekly Challenge - #075 - Tyler Wardhaugh +The Weekly Challenge - #076 - Tyler Wardhaugh ## Usage Run the project directly (shows default output from both tasks): - $ clojure -m tw.weekly.c75 + $ clojure -m tw.weekly.c76 Run the project's tests (which are samples from the task descriptions): $ clojure -A:test:runner -Run Task #1 with input (SUM COIN [COIN]...) +Run Task #1 with input - $ clojure -m tw.weekly.ch-1 6 1 2 4 + $ clojure -m tw.weekly.ch-1 Run Task #2 with input: - $ clojure -m tw.weekly.ch-2 2 1 4 5 3 7 + $ clojure -m tw.weekly.ch-2 ## Project Template diff --git a/challenge-076/tyler-wardhaugh/clojure/deps.edn b/challenge-076/tyler-wardhaugh/clojure/deps.edn index 6f74027036..fff9b934dc 100644 --- a/challenge-076/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-076/tyler-wardhaugh/clojure/deps.edn @@ -1,15 +1,16 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.10.1"} - metametadata/multiset {:mvn/version "0.1.1"}} + com.hypirion/primes {:mvn/version "0.2.2"} + org.clojure/math.combinatorics {:mvn/version "0.1.6"} + net.mikera/core.matrix {:mvn/version "0.62.0"}} :aliases {:test {:extra-paths ["test"] :extra-deps {org.clojure/test.check {:mvn/version "1.0.0"}}} - :runner - {:extra-deps {com.cognitect/test-runner - {:git/url "https://github.com/cognitect-labs/test-runner" - :sha "f7ef16dc3b8332b0d77bc0274578ad5270fbfedd"}} - :main-opts ["-m" "cognitect.test-runner" - "-d" "test"]} + :runner {:extra-deps {com.cognitect/test-runner + {:git/url "https://github.com/cognitect-labs/test-runner" + :sha "f7ef16dc3b8332b0d77bc0274578ad5270fbfedd"}} + :main-opts ["-m" "cognitect.test-runner" + "-d" "test"]} :uberjar {:extra-deps {seancorfield/depstar {:mvn/version "1.0.94"}} - :main-opts ["-m" "hf.depstar.uberjar" "tw.weekly.c75.jar" - "-C" "-m" "tw.weekly.c75"]}}} + :main-opts ["-m" "hf.depstar.uberjar" "tw.weekly.c76.jar" + "-C" "-m" "tw.weekly.c76"]}}} diff --git a/challenge-076/tyler-wardhaugh/clojure/pom.xml b/challenge-076/tyler-wardhaugh/clojure/pom.xml index 7e0da3dd93..5f42d66326 100644 --- a/challenge-076/tyler-wardhaugh/clojure/pom.xml +++ b/challenge-076/tyler-wardhaugh/clojure/pom.xml @@ -2,10 +2,10 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>tw.weekly</groupId> - <artifactId>tw.weekly.c75</artifactId> + <artifactId>tw.weekly.c76</artifactId> <version>0.1.0-SNAPSHOT</version> - <name>tw.weekly.c75</name> - <description>The Weekly Challenge - #075</description> + <name>tw.weekly.c76</name> + <description>The Weekly Challenge - #076</description> <url>https://github.com/manwar/perlweeklychallenge-club</url> <licenses> <license> @@ -25,9 +25,19 @@ <version>1.10.1</version> </dependency> <dependency> - <groupId>metametadata</groupId> - <artifactId>multiset</artifactId> - <version>0.1.1</version> + <groupId>com.hypirion</groupId> + <artifactId>primes</artifactId> + <version>0.2.2</version> + </dependency> + <dependency> + <groupId>org.clojure</groupId> + <artifactId>math.combinatorics</artifactId> + <version>0.1.6</version> + </dependency> + <dependency> + <groupId>net.mikera</groupId> + <artifactId>core.matrix</artifactId> + <version>0.62.0</version> </dependency> </dependencies> <build> diff --git a/challenge-076/tyler-wardhaugh/clojure/resources/dict.txt b/challenge-076/tyler-wardhaugh/clojure/resources/dict.txt new file mode 100644 index 0000000000..c0d8215b4a --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/resources/dict.txt @@ -0,0 +1,53 @@ +argos +margo +patna +traci +tracie +aimed +align +antes +arose +ashed +blunt +blunts +broad +buries +clove +cloven +constitution +constitutions +croon +depart +departed +enter +filch +garlic +goats +grieve +grieves +hazard +liens +malign +malignant +malls +midst +ought +ovary +parted +pudgiest +quash +quashed +ruses +shrine +shrines +social +socializing +spasm +spasmodic +succor +succors +theorem +theorems +virus +viruses +wigged diff --git a/challenge-076/tyler-wardhaugh/clojure/resources/grid.txt b/challenge-076/tyler-wardhaugh/clojure/resources/grid.txt new file mode 100644 index 0000000000..31cf2e0fd8 --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/resources/grid.txt @@ -0,0 +1,19 @@ +B I D E M I A T S U C C O R S T +L D E G G I W Q H O D E E H D P +U S E I R U B U T E A S L A G U +N G N I Z I L A I C O S C N U D +T G M I D S T S A R A R E I F G +S R E N M D C H A S I V E E L I +S C S H A E U E B R O A D M T E +H W O V L P E D D L A I U L S S +R Y O N L A S F C S T A O G O T +I G U S S R R U G O V A R Y O C +N R G P A T N A N G I L A M O O +E I H A C E I V I R U S E S E D +S E T S U D T T G A R L I C N H +H V R M X L W I U M S N S O T B +A E A O F I L C H T O D C A E U +Z S C D F E C A A I I R L N R F +A R I I A N Y U T O O O U T P F +R S E C I S N A B O S C N E R A +D R S M P C U U N E L T E S I L diff --git a/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/c76.clj b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/c76.clj new file mode 100644 index 0000000000..e155b703fb --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/c76.clj @@ -0,0 +1,12 @@ +(ns tw.weekly.c76 + (:require [tw.weekly.ch-1 :as ch-1]) + (:require [tw.weekly.ch-2 :as ch-2]) + (:gen-class)) + +(defn -main + "Run both tasks." + [& args] + (println "Task #1") + (ch-1/-main) + (println "\n\nTask #2") + (ch-2/-main)) diff --git a/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch-1.clj b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch-1.clj new file mode 120000 index 0000000000..924a7a086e --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch-1.clj @@ -0,0 +1 @@ +ch_1.clj
\ No newline at end of file diff --git a/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch-2.clj b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch-2.clj new file mode 120000 index 0000000000..5a32e17ef9 --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch-2.clj @@ -0,0 +1 @@ +ch_2.clj
\ No newline at end of file diff --git a/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch_1.clj b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch_1.clj new file mode 100644 index 0000000000..300b89c7ff --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch_1.clj @@ -0,0 +1,37 @@ +(ns tw.weekly.ch-1 + (:require [clojure.edn :as edn]) + (:require [clojure.math.combinatorics :as combo]) + (:require [com.hypirion.primes :as p])) + +; My initial attempt, which I've preserved here. +(defn find-min-primes-to-sum-brute-force + "Find the minimum number of prime numbers required, whose summation gives you the argument provided, by brute force." + [n] + (if (p/prime? n) [n] + (as-> n x + (p/take-below x) + (combo/partitions x :min 2 :max 3) + (mapcat identity x) + (filter #(= n (reduce + %)) x) + (sort-by count x) + (first x)))) + +; basis for algorithm: +; https://stackoverflow.com/a/35756072 +; StackOverflow answer by user448810 +(defn find-min-primes-to-sum + "Find the minimum number of prime numbers required, whose summation gives you the argument provided." + [n] + (cond + (p/prime? n) [n] + (even? n) (let [f (juxt #(- n %) identity)] (->> (p/primes) (filter #(p/prime? (- n %))) first f)) + (and (odd? n) (p/prime? (- n 2))) [2 (- n 2)] + :else (conj 3 (find-min-primes-to-sum (- n 3))))) + +(defn -main + "Run Task 1 with a number N, defaulting to the number given in the task example, 9." + [& args] + (let [N (or (some-> args first edn/read-string) 9)] + (let [solution (find-min-primes-to-sum N)] + (printf "%d prime number(s) are the minimum number required to sum to %d.\n" (count solution) N) + (println solution)))) diff --git a/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch_2.clj b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch_2.clj new file mode 100644 index 0000000000..cd5109aab1 --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/src/tw/weekly/ch_2.clj @@ -0,0 +1,59 @@ +(ns tw.weekly.ch-2 + (:require [clojure.edn :as edn]) + (:require [clojure.java.io :as io]) + (:require [clojure.string :as str]) + (:require [clojure.core.matrix :as mat])) + +(def min-word-length 5) + +(defn parse-grid-file + "Parse grid file and return a multidimensional vector of chars." + [grid-file] + (with-open [rdr (io/reader grid-file)] + (-> rdr + line-seq + seq + (->> (map #(remove (fn [c] (Character/isWhitespace c)) %))) + to-array-2d))) + +(defn parse-dict-file + "Parse dictionary and return a vector of words." + [dict-file] + (with-open [rdr (io/reader dict-file)] + (->> (line-seq rdr) + (filter #(>= (count %) min-word-length)) + (map str/trim-newline) + (map str/upper-case) + (into [])))) + +(defn build-lines + "Return a set of lines in a word grid that could contain valid words." + [grid] + (let [[m n] (mat/shape grid) + transposed (mat/transpose grid) + rotated (mapv #(vec (reverse (mat/get-row transposed %))) (range n)) + get-diags (fn [g d] (map #(mat/diagonal g %) (range (- d) d))) + diag-across (get-diags grid m) + diag-down (get-diags rotated n)] + (->> [grid transposed diag-across diag-down] + (mapcat #(into [] (comp (map str/join) (remove (partial = ""))) %)) + (mapcat (juxt identity str/reverse)) + (into #{})))) + +(defn word-search + "Return a sequence of words found in a grid from a dictionary." + [grid dict] + (let [all-lines (build-lines grid)] + (->> dict + (mapcat (fn [word] (keep #(when (str/includes? % word) word) all-lines)))))) + +(defn -main + "Run Task 2 with a grid file and a dictionary file, defaulting to the ones in the resources directory." + [& args] + (let [grid-file (or (some-> args first edn/read-string) (io/resource "grid.txt")) + dict-file (or (some-> args second edn/read-string) (io/resource "dict.txt")) + grid (parse-grid-file grid-file) + dict (parse-dict-file dict-file) + words (word-search grid dict)] + (printf "%d word(s) from the dictionary of %d word(s) found in the grid:\n" (count words) (count dict)) + (doseq [word words] (println word)))) diff --git a/challenge-076/tyler-wardhaugh/clojure/test/tw/weekly/c76_test.clj b/challenge-076/tyler-wardhaugh/clojure/test/tw/weekly/c76_test.clj new file mode 100644 index 0000000000..003ce81591 --- /dev/null +++ b/challenge-076/tyler-wardhaugh/clojure/test/tw/weekly/c76_test.clj @@ -0,0 +1,17 @@ +(ns tw.weekly.c76-test + (:require [clojure.test :refer :all] + [clojure.java.io :as io] + [tw.weekly.ch-1 :refer [find-min-primes-to-sum find-min-primes-to-sum-brute-force]] + [tw.weekly.ch-2 :refer [parse-dict-file parse-grid-file word-search]])) + +(deftest ch-1 + (testing "Task 1" + (is (= 2 (count (find-min-primes-to-sum 9)) (count (find-min-primes-to-sum-brute-force 9)))) + (is (= 2 (count (find-min-primes-to-sum 34)) (count (find-min-primes-to-sum-brute-force 34)))))) + +(deftest ch-2 + (testing "Task 2" + (let [grid (parse-grid-file (io/resource "grid.txt")) + dict (parse-dict-file (io/resource "dict.txt")) + words (word-search grid dict)] + (is (= (into #{} dict) (into #{} words)))))) |
