aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-08-21 00:13:01 +0100
committerGitHub <noreply@github.com>2021-08-21 00:13:01 +0100
commit636e35fa1cf2af5d808dee8ee67c99105212f8b6 (patch)
treeca495cef70270137f0699edb28a673b4ba4e9ac7
parent656ca1a3046b5e0cb306f27cbbe79875071a8976 (diff)
parentc7e2cecd699ec6e66c65e4632a8be45b13930729 (diff)
downloadperlweeklychallenge-club-636e35fa1cf2af5d808dee8ee67c99105212f8b6.tar.gz
perlweeklychallenge-club-636e35fa1cf2af5d808dee8ee67c99105212f8b6.tar.bz2
perlweeklychallenge-club-636e35fa1cf2af5d808dee8ee67c99105212f8b6.zip
Merge pull request #4750 from tylerw/tw/challenge-126
Challenge 126
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/README.md14
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/bb.edn6
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/deps.edn28
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/pom.xml6
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/resources/matrix.txt5
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/core.clj12
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/matrix_util.clj44
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t1.clj23
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/src/tw/weekly/c126/t2.clj44
-rw-r--r--challenge-126/tyler-wardhaugh/clojure/test/tw/weekly/c126_test.clj21
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)))))