From 02b345b78a2d9e5f3e6b56bb87e5508057512f0d Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Thu, 19 Aug 2021 16:15:05 -0700 Subject: Ch126: prep for challenge --- challenge-126/tyler-wardhaugh/clojure/README.md | 12 ++++----- challenge-126/tyler-wardhaugh/clojure/bb.edn | 2 +- challenge-126/tyler-wardhaugh/clojure/deps.edn | 29 +++++++++------------- challenge-126/tyler-wardhaugh/clojure/pom.xml | 5 ---- .../clojure/src/tw/weekly/c126/core.clj | 12 +++++++++ .../clojure/src/tw/weekly/c126/t1.clj | 14 +++++++++++ .../clojure/src/tw/weekly/c126/t2.clj | 16 ++++++++++++ .../clojure/test/tw/weekly/c126_test.clj | 4 +++ 8 files changed, 65 insertions(+), 29 deletions(-) create mode 100644 challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/core.clj create mode 100644 challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj create mode 100644 challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj create mode 100644 challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj diff --git a/challenge-126/tyler-wardhaugh/clojure/README.md b/challenge-126/tyler-wardhaugh/clojure/README.md index 83da1a729e..118d7b558d 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,7 +9,7 @@ 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 @@ -21,15 +21,15 @@ Run the project's tests (which are samples from the task descriptions): 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 # ... or ... - $ bb run task-2 T + $ bb run task-2 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..0c49645ba4 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"} diff --git a/challenge-126/tyler-wardhaugh/clojure/deps.edn b/challenge-126/tyler-wardhaugh/clojure/deps.edn index db7a47ac68..5b1400b27e 100644 --- a/challenge-126/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-126/tyler-wardhaugh/clojure/deps.edn @@ -1,19 +1,14 @@ {:paths ["src" "resources"] - :deps {org.clojure/clojure {:mvn/version "1.10.3"} - org.clojure/math.numeric-tower {:mvn/version "0.0.4"}} + :deps {org.clojure/clojure {:mvn/version "1.10.3"}} :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..16891bbc7c 100644 --- a/challenge-126/tyler-wardhaugh/clojure/pom.xml +++ b/challenge-126/tyler-wardhaugh/clojure/pom.xml @@ -24,11 +24,6 @@ clojure 1.10.3 - - org.clojure - math.numeric-tower - 0.0.4 - src 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/t1.clj b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj new file mode 100644 index 0000000000..fb03cd9b88 --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj @@ -0,0 +1,14 @@ +(ns tw.weekly.c126.t1 + (:require [clojure.edn :as edn])) + +;;; +; Task description for TASK #1 › Count Numbers +;;; +(def DEFAULT-INPUT []) + +(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)] + )) 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..2861e120b7 --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj @@ -0,0 +1,16 @@ +(ns tw.weekly.c126.t2 + (:require [clojure.edn :as edn] + [clojure.string :as str] + [clojure.math.numeric-tower :refer [abs]])) + +;;; +; Task description for TASK #2 › Clock Angle +;;; +(def DEFAULT-INPUT []) + +(defn -main + "Run Task 2 with a given input N, defaulting to the first example from the + task description." + [& args] + (let [[T] (or args DEFAULT-INPUT)] + )) 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..e234c0c841 --- /dev/null +++ b/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj @@ -0,0 +1,4 @@ +(ns tw.weekly.c126-test + (:require [clojure.test :refer [deftest is testing]] + #_[tw.weekly.c126.t1 :refer []] + #_[tw.weekly.c126.t2 :refer []])) -- cgit From c59cc827374bbf39f4e0c999aa73c86667541210 Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Thu, 19 Aug 2021 16:50:48 -0700 Subject: Ch126 (Clojure): Task 1 --- .../tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj | 15 ++++++++++++--- .../tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj | 9 ++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) 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 index fb03cd9b88..54531042fb 100644 --- a/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj @@ -1,14 +1,23 @@ (ns tw.weekly.c126.t1 - (:require [clojure.edn :as edn])) + (:require [clojure.edn :as edn] + [clojure.string :as str] + [clojure.pprint :refer [cl-format]])) ;;; ; Task description for TASK #1 › Count Numbers ;;; -(def DEFAULT-INPUT []) +(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/test/tw/weekly/c126_test.clj b/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj index e234c0c841..9e7089159c 100644 --- a/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj +++ b/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj @@ -1,4 +1,11 @@ (ns tw.weekly.c126-test (:require [clojure.test :refer [deftest is testing]] - #_[tw.weekly.c126.t1 :refer []] + [tw.weekly.c126.t1 :refer [count-numbers]] #_[tw.weekly.c126.t2 :refer []])) + +(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))))) -- cgit From c7e2cecd699ec6e66c65e4632a8be45b13930729 Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Fri, 20 Aug 2021 15:01:54 -0700 Subject: Ch126 (Clojure): Task 2 --- challenge-126/tyler-wardhaugh/clojure/README.md | 6 +-- challenge-126/tyler-wardhaugh/clojure/bb.edn | 4 +- challenge-126/tyler-wardhaugh/clojure/deps.edn | 3 +- challenge-126/tyler-wardhaugh/clojure/pom.xml | 5 +++ .../tyler-wardhaugh/clojure/resources/matrix.txt | 5 +++ .../clojure/src/tw/weekly/c126/matrix_util.clj | 44 ++++++++++++++++++++++ .../clojure/src/tw/weekly/c126/t2.clj | 40 +++++++++++++++++--- .../clojure/test/tw/weekly/c126_test.clj | 12 +++++- 8 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 challenge-126/tyler-wardhaugh/clojure/resources/matrix.txt create mode 100644 challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/matrix_util.clj diff --git a/challenge-126/tyler-wardhaugh/clojure/README.md b/challenge-126/tyler-wardhaugh/clojure/README.md index 118d7b558d..99185b88b1 100644 --- a/challenge-126/tyler-wardhaugh/clojure/README.md +++ b/challenge-126/tyler-wardhaugh/clojure/README.md @@ -15,7 +15,7 @@ Run the project directly (shows default output from both tasks): Run the project's tests (which are samples from the task descriptions): - $ clojure -M:test:runner + $ clojure -X:test # ... or ... $ bb run test @@ -27,9 +27,9 @@ Run Task #1 with input Run Task #2 with input: - $ clojure -M -m tw.weekly.c126.t2 + $ clojure -M -m tw.weekly.c126.t2 F # ... or ... - $ bb run task-2 + $ 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 0c49645ba4..463fcb5d14 100644 --- a/challenge-126/tyler-wardhaugh/clojure/bb.edn +++ b/challenge-126/tyler-wardhaugh/clojure/bb.edn @@ -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 5b1400b27e..54198fdfe8 100644 --- a/challenge-126/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-126/tyler-wardhaugh/clojure/deps.edn @@ -1,5 +1,6 @@ {:paths ["src" "resources"] - :deps {org.clojure/clojure {:mvn/version "1.10.3"}} + :deps {org.clojure/clojure {:mvn/version "1.10.3"} + net.mikera/core.matrix {:mvn/version "0.62.0"}} :aliases {:test {:extra-paths ["test"] :extra-deps {org.clojure/test.check {:mvn/version "1.1.0"} diff --git a/challenge-126/tyler-wardhaugh/clojure/pom.xml b/challenge-126/tyler-wardhaugh/clojure/pom.xml index 16891bbc7c..968dd8f7e9 100644 --- a/challenge-126/tyler-wardhaugh/clojure/pom.xml +++ b/challenge-126/tyler-wardhaugh/clojure/pom.xml @@ -24,6 +24,11 @@ clojure 1.10.3 + + net.mikera + core.matrix + 0.62.0 + src 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/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/t2.clj b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj index 2861e120b7..e85360bcaa 100644 --- a/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj +++ b/challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj @@ -1,16 +1,44 @@ (ns tw.weekly.c126.t2 (:require [clojure.edn :as edn] + [clojure.java.io :as io] [clojure.string :as str] - [clojure.math.numeric-tower :refer [abs]])) + [clojure.core.matrix :as m] + [tw.weekly.c126.matrix-util :as mu])) ;;; -; Task description for TASK #2 › Clock Angle +; Task description for TASK #2 › Minesweeper Game ;;; -(def DEFAULT-INPUT []) +(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 N, defaulting to the first example from the + "Run Task 2 with a given input, defaulting to the first example from the task description." [& args] - (let [[T] (or args DEFAULT-INPUT)] - )) + (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 index 9e7089159c..e7ade128ef 100644 --- a/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj +++ b/challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj @@ -1,7 +1,7 @@ (ns tw.weekly.c126-test (:require [clojure.test :refer [deftest is testing]] [tw.weekly.c126.t1 :refer [count-numbers]] - #_[tw.weekly.c126.t2 :refer []])) + [tw.weekly.c126.t2 :as t2])) (deftest task-1 (testing "Task 1, Count Numbers" @@ -9,3 +9,13 @@ (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))))) -- cgit