diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2022-11-20 21:52:13 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-20 21:52:13 +0000 |
| commit | c64e83912f3b4135bdd45f9e8c473285089e6d72 (patch) | |
| tree | a8c936998101fad714af946ebc15455968883716 | |
| parent | 07cf8dc598ab7c592e03457334e9bd72de2a7f40 (diff) | |
| parent | c35f713f4f3adf7099264f94ff54eb3065b0f7db (diff) | |
| download | perlweeklychallenge-club-c64e83912f3b4135bdd45f9e8c473285089e6d72.tar.gz perlweeklychallenge-club-c64e83912f3b4135bdd45f9e8c473285089e6d72.tar.bz2 perlweeklychallenge-club-c64e83912f3b4135bdd45f9e8c473285089e6d72.zip | |
Merge pull request #7109 from tylerw/tw/challenge-191
Ch191: implement Tasks 1 & 2 in Clojure
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/README.md | 41 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/bb.edn | 68 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/build.clj | 19 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/deps.edn | 15 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/src/c191/t1.clj | 17 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/src/c191/t2.clj | 41 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/test/c191/t1_test.clj | 15 | ||||
| -rw-r--r-- | challenge-191/tyler-wardhaugh/clojure/test/c191/t2_test.clj | 11 |
8 files changed, 227 insertions, 0 deletions
diff --git a/challenge-191/tyler-wardhaugh/clojure/README.md b/challenge-191/tyler-wardhaugh/clojure/README.md new file mode 100644 index 0000000000..56385ea8ab --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/README.md @@ -0,0 +1,41 @@ +# c191 + +The Weekly Challenge — #191 — Tyler Wardhaugh + +## Usage + +Clojure ([installation instructions](https://clojure.org/guides/getting_started#_clojure_installer_and_cli_tools)) required for `clojure` commands; Babashka ([installation instructions](https://github.com/babashka/babashka#quickstart)) required for the `bb` commands. + +Run Task #1: + + $ clojure -M:t1 COLL + # ... or ... + $ bb run task-1 COLL + + # Alternatively, to run it via Babashka: + $ bb run task-1-bb COLL + +Run Task #2: + + $ clojure -M:t2 N + # ... or ... + $ bb run task-2 N + + # Alternatively, to run it via Babashka: + $ bb run task-2-bb N + +Run the project's tests (which are samples from the task descriptions): + + $ clojure -T:build test + # ... or ... + $ bb run test + +View available tasks Babashka can run: + + $ bb tasks + +## License + +Copyright © 2022 Tyler Wardhaugh + +Distributed under the Eclipse Public License version 1.0. diff --git a/challenge-191/tyler-wardhaugh/clojure/bb.edn b/challenge-191/tyler-wardhaugh/clojure/bb.edn new file mode 100644 index 0000000000..ee227e4c53 --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/bb.edn @@ -0,0 +1,68 @@ +{ + :paths ["src" "resources"] + :deps {c191/c191 {:local/root "."}} + + :tasks + { + :requires ([clojure.java.io :as io] + [clojure.edn :as edn] + [babashka.fs :as fs]) + :init (do + (defn get-first-form + [file] + (with-open [r (-> file fs/file io/reader) + pr (java.io.PushbackReader. r)] + (edn/read pr))) + + (defn get-task-ns + [task] + (let [glob-target (format "src/*/%s.clj" (name task)) + file (->> glob-target (fs/glob ".") first)] + (-> file get-first-form second str))) + + (defn run-task-clj + [task args] + (apply clojure (str "-M:" task) args)) + + (defn run-task-bb + ([task args] (run-task-bb task args (get-task-ns task))) + ([task args task-ns] + (let [bb-cmd (format "bb -m %s " task-ns)] + (apply shell bb-cmd args)))) + + (defn bb-no-go + [task & _] + (binding [*out* *err*] + (let [task-num (-> task name last (Character/digit 10))] + (println + (str "error: can't run Task " task-num + " via Babashka because it depends" + " on some incompatible libraries.")))) + (System/exit 1))) + + clean {:doc "Clean out temporary files" + :task (do (clojure "-T:build" "clean") + (run! fs/delete-tree + [".nrepl-port" ".cpcache" ".lsp" ".clj-kondo"]))} + + generate-jar {:doc "Generate JAR file" + :task (clojure "-X:jar")} + + test {:doc "Run tests" + :task (clojure "-T:build test")} + + c**** {:doc "CHALLENGE TASKS"} + + task-1 {:doc "Run Task 1 (via clojure)" + :task (run-task-clj :t1 *command-line-args*)} + + task-1-bb {:doc "Run Task 1 (via Babashka)" + :task (run-task-bb :t1 *command-line-args*)} + + task-2 {:doc "Run Task 2 (via clojure)" + :task (run-task-clj :t2 *command-line-args*)} + + task-2-bb {:doc "Run Task 2 (via Babashka)" + :task (run-task-bb :t2 *command-line-args*)} + } +} diff --git a/challenge-191/tyler-wardhaugh/clojure/build.clj b/challenge-191/tyler-wardhaugh/clojure/build.clj new file mode 100644 index 0000000000..6a8c4c19e5 --- /dev/null +++ b/challenge-191/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.c191/c191) +(def version "0.1.0-SNAPSHOT") +(def main 'c191.c191) + +(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-191/tyler-wardhaugh/clojure/deps.edn b/challenge-191/tyler-wardhaugh/clojure/deps.edn new file mode 100644 index 0000000000..bbf2435dec --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/deps.edn @@ -0,0 +1,15 @@ +{:paths ["src" "resources"] + :deps {org.clojure/clojure {:mvn/version "1.11.1"}} + :aliases + {:t1 {:main-opts ["-m" "c191.t1"]} + :t2 {:main-opts ["-m" "c191.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 + ;; need deps-deploy for clojars.org deployment: + :deps/root "slim"}} + :ns-default build} + :test {:extra-paths ["test"] + :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"} + io.github.cognitect-labs/test-runner + {:git/tag "v0.5.1" :git/sha "dfb30dd"}}}}} diff --git a/challenge-191/tyler-wardhaugh/clojure/src/c191/t1.clj b/challenge-191/tyler-wardhaugh/clojure/src/c191/t1.clj new file mode 100644 index 0000000000..5539037748 --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/src/c191/t1.clj @@ -0,0 +1,17 @@ +(ns c191.t1 + (:require [clojure.edn :as edn])) + +(def DEFAULT-INPUT [[1 2 3 4]]) + +(defn twice-largest + [coll] + (let [[biggest second-biggest] (sort > coll)] + (when (and biggest second-biggest) + (<= (* 2 second-biggest) biggest)))) + +(defn -main + "Run Task 1 with a given input COLL, defaulting to the first example from + the task description." + [& args] + (let [[COLL] (or (some->> args (map edn/read-string)) DEFAULT-INPUT)] + (println (if (twice-largest COLL) 1 -1)))) diff --git a/challenge-191/tyler-wardhaugh/clojure/src/c191/t2.clj b/challenge-191/tyler-wardhaugh/clojure/src/c191/t2.clj new file mode 100644 index 0000000000..ca02691adc --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/src/c191/t2.clj @@ -0,0 +1,41 @@ +(ns c191.t2 + (:require [clojure.edn :as edn])) + +(def DEFAULT-INPUT [2]) + +; adapted from: https://rosettacode.org/wiki/Determinant_and_permanent#Common_Lisp +(defn permanent' + [mf rows skip-cols] + (let [source (range (count (first rows))) + f (fn [result col] + (if (skip-cols col) + result + (if (nil? (next rows)) + (reduced (nth (first rows) col)) + (+ result (* (nth (first rows) col) + (mf mf (next rows) (conj skip-cols col)))))))] + (reduce f 0 source))) + +(let [mf (memoize permanent')] + (def permanent #(mf mf % #{}))) + +(defn generate-cute-matrix + [n] + (->> (for [i (range 1 (inc n)) + j (range 1 (inc n))] + (if (or (zero? (mod i j)) (zero? (mod j i))) 1 0)) + (partition n))) + +; adapted from: https://oeis.org/A320843 ("PROG" entry) +(defn cute-list + [n] + (if (zero? n) + 1 + (-> n generate-cute-matrix permanent))) + +(defn -main + "Run Task 2 with a given input N, defaulting to the first example from + the task description." + [& args] + (let [[N] (or (some->> args (map edn/read-string)) DEFAULT-INPUT)] + (println (cute-list N)))) diff --git a/challenge-191/tyler-wardhaugh/clojure/test/c191/t1_test.clj b/challenge-191/tyler-wardhaugh/clojure/test/c191/t1_test.clj new file mode 100644 index 0000000000..4a034f8a25 --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/test/c191/t1_test.clj @@ -0,0 +1,15 @@ +(ns c191.t1-test + (:require [clojure.test :refer [deftest is testing]] + [c191.t1 :refer [twice-largest]])) + +(deftest task-1 + (testing "Task 1 produces the correct results (description)" + (is (false? (twice-largest [1 2 3 4]))) + (is (true? (twice-largest [1 2 0 5]))) + (is (true? (twice-largest [2 6 3 1]))) + (is (false? (twice-largest [4 5 2 3]))))) + +(deftest task-1 + (testing "Additional tests for twice-largest" + (is (nil? (twice-largest [1]))) + (is (nil? (twice-largest []))))) diff --git a/challenge-191/tyler-wardhaugh/clojure/test/c191/t2_test.clj b/challenge-191/tyler-wardhaugh/clojure/test/c191/t2_test.clj new file mode 100644 index 0000000000..7c242c795c --- /dev/null +++ b/challenge-191/tyler-wardhaugh/clojure/test/c191/t2_test.clj @@ -0,0 +1,11 @@ +(ns c191.t2-test + (:require [clojure.test :refer [deftest is testing]] + [c191.t2 :refer [cute-list]])) + +; "Cute List" results for n = 0 .. 15 +; from: https://oeis.org/A320843/list +(def A320843 [1 1 2 3 8 10 36 41 132 250 700 750 4010 4237 10680 24679]) + +(deftest task-2 + (testing "Task 2 produces the correct results" + (is (= A320843 (map cute-list (range 16)))))) |
