diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-08-21 00:13:01 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-21 00:13:01 +0100 |
| commit | 636e35fa1cf2af5d808dee8ee67c99105212f8b6 (patch) | |
| tree | ca495cef70270137f0699edb28a673b4ba4e9ac7 | |
| parent | 656ca1a3046b5e0cb306f27cbbe79875071a8976 (diff) | |
| parent | c7e2cecd699ec6e66c65e4632a8be45b13930729 (diff) | |
| download | perlweeklychallenge-club-636e35fa1cf2af5d808dee8ee67c99105212f8b6.tar.gz perlweeklychallenge-club-636e35fa1cf2af5d808dee8ee67c99105212f8b6.tar.bz2 perlweeklychallenge-club-636e35fa1cf2af5d808dee8ee67c99105212f8b6.zip | |
Merge pull request #4750 from tylerw/tw/challenge-126
Challenge 126
10 files changed, 175 insertions, 28 deletions
diff --git a/challenge-126/tyler-wardhaugh/clojure/README.md b/challenge-126/tyler-wardhaugh/clojure/README.md index 83da1a729e..99185b88b1 100644 --- a/challenge-126/tyler-wardhaugh/clojure/README.md +++ b/challenge-126/tyler-wardhaugh/clojure/README.md @@ -1,7 +1,7 @@ -# tw.weekly.c120 +# tw.weekly.c126 -The Weekly Challenge - #120 - Tyler Wardhaugh +The Weekly Challenge - #126 - Tyler Wardhaugh ## Usage @@ -9,27 +9,27 @@ Clojure ([installation instructions](https://clojure.org/guides/getting_started# Run the project directly (shows default output from both tasks): - $ clojure -M -m tw.weekly.c120.core + $ clojure -M -m tw.weekly.c126.core # ... or ... $ bb run both Run the project's tests (which are samples from the task descriptions): - $ clojure -M:test:runner + $ clojure -X:test # ... or ... $ bb run test Run Task #1 with input - $ clojure -M -m tw.weekly.c120.t1 N + $ clojure -M -m tw.weekly.c126.t1 N # ... or ... $ bb run task-1 N Run Task #2 with input: - $ clojure -M -m tw.weekly.c120.t2 T + $ clojure -M -m tw.weekly.c126.t2 F # ... or ... - $ bb run task-2 T + $ bb run task-2 F View available tasks Babashka can run: diff --git a/challenge-126/tyler-wardhaugh/clojure/bb.edn b/challenge-126/tyler-wardhaugh/clojure/bb.edn index d6814eab4a..463fcb5d14 100644 --- a/challenge-126/tyler-wardhaugh/clojure/bb.edn +++ b/challenge-126/tyler-wardhaugh/clojure/bb.edn @@ -55,7 +55,7 @@ p/check))} test {:doc "Run tests" - :task (clojure "-M:test:runner")} + :task (clojure "-X:test")} c**** {:doc "CHALLENGE TASKS"} @@ -69,7 +69,9 @@ :task (run-task :t2 *command-line-args*)} task-2-bb {:doc "Run Task 2 (via Babashka)" - :task (run-task-bb :t2 *command-line-args*)} + :task (binding [*out* *err*] + (println "error: can't run Task 2 via Babashka because it depends on some incompatible libraries.") + (System/exit 1))} both {:doc "Run both tasks (via clojure)" :task (do diff --git a/challenge-126/tyler-wardhaugh/clojure/deps.edn b/challenge-126/tyler-wardhaugh/clojure/deps.edn index db7a47ac68..54198fdfe8 100644 --- a/challenge-126/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-126/tyler-wardhaugh/clojure/deps.edn @@ -1,19 +1,15 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.10.3"} - org.clojure/math.numeric-tower {:mvn/version "0.0.4"}} + 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 "705ad25bbf0228b1c38d0244a36001c2987d7337"}} - :main-opts ["-m" "cognitect.test-runner" - "-d" "test"]} - - :jar - {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.0.216"}} - :exec-fn hf.depstar/jar - :exec-args {:jar "tw-weekly.jar" :sync-pom true}}}} + {:test {:extra-paths ["test"] + :extra-deps {org.clojure/test.check {:mvn/version "1.1.0"} + io.github.cognitect-labs/test-runner + {:git/url "https://github.com/cognitect-labs/test-runner" + :sha "62ef1de18e076903374306060ac0e8a752e57c86"}} + :exec-fn cognitect.test-runner.api/test} + :jar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.1.278"}} + :exec-fn hf.depstar/uberjar + :exec-args {:aot true + :jar "tw-weekly.jar" + :sync-pom true}}}} diff --git a/challenge-126/tyler-wardhaugh/clojure/pom.xml b/challenge-126/tyler-wardhaugh/clojure/pom.xml index ed18485e7e..968dd8f7e9 100644 --- a/challenge-126/tyler-wardhaugh/clojure/pom.xml +++ b/challenge-126/tyler-wardhaugh/clojure/pom.xml @@ -25,9 +25,9 @@ <version>1.10.3</version> </dependency> <dependency> - <groupId>org.clojure</groupId> - <artifactId>math.numeric-tower</artifactId> - <version>0.0.4</version> + <groupId>net.mikera</groupId> + <artifactId>core.matrix</artifactId> + <version>0.62.0</version> </dependency> </dependencies> <build> diff --git a/challenge-126/tyler-wardhaugh/clojure/resources/matrix.txt b/challenge-126/tyler-wardhaugh/clojure/resources/matrix.txt new file mode 100644 index 0000000000..e211219443 --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/resources/matrix.txt @@ -0,0 +1,5 @@ +x * * * x * x x x x +* * * * * * * * * x +* * * * x * x * x * +* * * x x * * * * * +x * * * x * * * * x diff --git a/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/core.clj b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/core.clj new file mode 100644 index 0000000000..0a8a8dd20e --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/core.clj @@ -0,0 +1,12 @@ +(ns tw.weekly.c126.core + (:require [tw.weekly.c126.t1 :as t1]) + (:require [tw.weekly.c126.t2 :as t2]) + (:gen-class)) + +(defn -main + "Run all tasks" + [& _] + (println "Task #1:") + (t1/-main) + (println "\nTask #2:") + (t2/-main)) diff --git a/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/matrix_util.clj b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/matrix_util.clj new file mode 100644 index 0000000000..63da586c8d --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/matrix_util.clj @@ -0,0 +1,44 @@ +(ns tw.weekly.c126.matrix-util + (:require [clojure.java.io :as io] + [clojure.pprint :as pp] + [clojure.string :as str] + [clojure.core.matrix :as m])) + +(defn parse-matrix-file + "Parse a matrix file and return a matrix" + ([matrix-file] + (parse-matrix-file matrix-file (comp))) + ([matrix-file xf] + (with-open [in (io/reader matrix-file)] + (into [] xf (line-seq in))))) + +(defn extend-matrix + "Surround the matrix in a 'border' of 0s. That is, add rows before the first and after the last rows and add columns before + the first and after the last columns." + [mat] + (let [n (m/dimension-count mat 1) + blank-row (vec (repeat (+ n 2) 0)) + step-1 (reduce (fn [mat v] (conj mat (vec (concat [0] v [0])))) [blank-row] mat)] + (conj step-1 blank-row))) + +(defn rotate-matrix + "Rotate a matrix counterclockwise" + [mat] + (-> mat m/transpose reverse)) + +(defn print-matrix + ([mat] + (print-matrix mat true)) + ([mat stream] + (pp/cl-format stream "~{~{~a~^ ~}~%~}" mat))) + +(defn pprint-matrix + "Pretty print a matrix" + [mat] + (let [ks (range (m/dimension-count mat 1)) + tbl (with-out-str + (pp/print-table ks (map (partial zipmap ks) mat)))] + (-> tbl + (str/split #"\n") + (->> (drop 3) + (run! println))))) diff --git a/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj new file mode 100644 index 0000000000..54531042fb --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj @@ -0,0 +1,23 @@ +(ns tw.weekly.c126.t1 + (:require [clojure.edn :as edn] + [clojure.string :as str] + [clojure.pprint :refer [cl-format]])) + +;;; +; Task description for TASK #1 › Count Numbers +;;; +(def DEFAULT-INPUT [15]) + +(defn count-numbers + [n] + (let [xf (remove #(str/includes? (str %1) "1")) + ed (eduction xf (range 2 (inc n))) + msg "There are ~a numbers between 1 and ~a that don't contain digit 1.~%~{~a~^, ~}"] + (cl-format nil msg (count (seq ed)) n ed))) + +(defn -main + "Run Task 1 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 (count-numbers N)))) diff --git a/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj new file mode 100644 index 0000000000..e85360bcaa --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj @@ -0,0 +1,44 @@ +(ns tw.weekly.c126.t2 + (:require [clojure.edn :as edn] + [clojure.java.io :as io] + [clojure.string :as str] + [clojure.core.matrix :as m] + [tw.weekly.c126.matrix-util :as mu])) + +;;; +; Task description for TASK #2 › Minesweeper Game +;;; +(def DEFAULT-INPUT [(io/resource "matrix.txt")]) +(def MINE \x) +(def FREE \*) + +(defn parse + [f] + (->> (mu/parse-matrix-file + f + (map (comp + #(map edn/read-string %) + #(str/split % #" ") + #(str/escape % {MINE -1, FREE 0})))) + (m/array :ndarry))) + +(defn count-neighboring-mines [mat] + (let [emat (mu/extend-matrix mat)] + (fn [[i j] v] + (if (neg? v) + MINE + (->> (m/submatrix emat i 3 j 3) + m/eseq + (filter neg?) + count))))) + +(defn minesweeper + [mat] + (m/emap-indexed (count-neighboring-mines mat) mat)) + +(defn -main + "Run Task 2 with a given input, defaulting to the first example from the + task description." + [& args] + (let [[F] (or (some->> args (map (comp io/file edn/read-string))) DEFAULT-INPUT)] + (-> F parse minesweeper mu/print-matrix))) diff --git a/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj b/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj new file mode 100644 index 0000000000..e7ade128ef --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj @@ -0,0 +1,21 @@ +(ns tw.weekly.c126-test + (:require [clojure.test :refer [deftest is testing]] + [tw.weekly.c126.t1 :refer [count-numbers]] + [tw.weekly.c126.t2 :as t2])) + +(deftest task-1 + (testing "Task 1, Count Numbers" + (is (= "There are 8 numbers between 1 and 15 that don't contain digit 1.\n2, 3, 4, 5, 6, 7, 8, 9" + (count-numbers 15))) + (is (= "There are 13 numbers between 1 and 25 that don't contain digit 1.\n2, 3, 4, 5, 6, 7, 8, 9, 20, 22, 23, 24, 25" + (count-numbers 25))))) + +(deftest task-2 + (testing "Task 2, Minesweeper Game" + (is (= + [[\x 1 0 1 \x 2 \x \x \x \x] + [1 1 0 2 2 4 3 5 5 \x] + [0 0 1 3 \x 3 \x 2 \x 2] + [1 1 1 \x \x 4 1 2 2 2] + [\x 1 1 3 \x 2 0 0 1 \x]] + (-> t2/DEFAULT-INPUT first t2/parse t2/minesweeper))))) |
