aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/.projections.json10
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/README.md14
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/bb.edn7
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/deps.edn3
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/pom.xml13
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/core.clj12
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t1.clj38
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t2.clj52
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t1_test.clj12
-rw-r--r--challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t2_test.clj12
10 files changed, 158 insertions, 15 deletions
diff --git a/challenge-134/tyler-wardhaugh/clojure/.projections.json b/challenge-134/tyler-wardhaugh/clojure/.projections.json
new file mode 100644
index 0000000000..fd1070320a
--- /dev/null
+++ b/challenge-134/tyler-wardhaugh/clojure/.projections.json
@@ -0,0 +1,10 @@
+{
+ "src/*.clj": {
+ "alternate": "test/{}_test.clj",
+ "type": "source"
+ },
+ "test/*_test.clj": {
+ "alternate": "src/{}.clj",
+ "type": "test"
+ }
+} \ No newline at end of file
diff --git a/challenge-134/tyler-wardhaugh/clojure/README.md b/challenge-134/tyler-wardhaugh/clojure/README.md
index 7455be8203..1293119417 100644
--- a/challenge-134/tyler-wardhaugh/clojure/README.md
+++ b/challenge-134/tyler-wardhaugh/clojure/README.md
@@ -1,7 +1,7 @@
-# tw.weekly.c133
+# tw.weekly.c134
-The Weekly Challenge - #133 - Tyler Wardhaugh
+The Weekly Challenge - #134 - 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.c133.core
+ $ clojure -M -m tw.weekly.c134.core
# ... or ...
$ bb run both
@@ -21,15 +21,13 @@ Run the project's tests (which are samples from the task descriptions):
Run Task #1 with input
- $ clojure -M -m tw.weekly.c133.t1 N
- # ... or ...
- $ bb run task-1 N
+ $ clojure -M -m tw.weekly.c134.t1 N
Run Task #2 with input:
- $ clojure -M -m tw.weekly.c133.t2 N
+ $ clojure -M -m tw.weekly.c134.t2 M N
# ... or ...
- $ bb run task-2 N
+ $ bb run task-2 M N
View available tasks Babashka can run:
diff --git a/challenge-134/tyler-wardhaugh/clojure/bb.edn b/challenge-134/tyler-wardhaugh/clojure/bb.edn
index 4cd11817b8..129b8ba62c 100644
--- a/challenge-134/tyler-wardhaugh/clojure/bb.edn
+++ b/challenge-134/tyler-wardhaugh/clojure/bb.edn
@@ -31,7 +31,8 @@
(apply shell bb-cmd args))))
clean {:doc "Clean out temporary files"
- :task (run! fs/delete-tree [".nrepl-port" ".cpcache" ".lsp"])}
+ :task (run! fs/delete-tree
+ [".nrepl-port" ".cpcache" ".lsp" ".clj-kondo"])}
generate-pom {:doc "Generate POM file"
:task (clojure "-X:deps mvn-pom")}
@@ -63,7 +64,9 @@
:task (run-task :t1 *command-line-args*)}
task-1-bb {:doc "Run Task 1 (via Babashka)"
- :task (run-task-bb :t1 *command-line-args*)}
+ :task (binding [*out* *err*]
+ (println "error: can't run Task 1 via Babashka because it depends on some incompatible libraries.")
+ (System/exit 1))}
task-2 {:doc "Run Task 2 (via clojure)"
:task (run-task :t2 *command-line-args*)}
diff --git a/challenge-134/tyler-wardhaugh/clojure/deps.edn b/challenge-134/tyler-wardhaugh/clojure/deps.edn
index 5b1400b27e..99b46a9e15 100644
--- a/challenge-134/tyler-wardhaugh/clojure/deps.edn
+++ b/challenge-134/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"}
+ org.clojure/math.combinatorics {:mvn/version "0.1.6"}}
:aliases
{:test {:extra-paths ["test"]
:extra-deps {org.clojure/test.check {:mvn/version "1.1.0"}
diff --git a/challenge-134/tyler-wardhaugh/clojure/pom.xml b/challenge-134/tyler-wardhaugh/clojure/pom.xml
index fce28c3b21..85869d7a3f 100644
--- a/challenge-134/tyler-wardhaugh/clojure/pom.xml
+++ b/challenge-134/tyler-wardhaugh/clojure/pom.xml
@@ -2,11 +2,11 @@
<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.c133</artifactId>
+ <artifactId>tw.weekly.c134</artifactId>
<version>0.1.0-SNAPSHOT</version>
- <name>tw.weekly.c133</name>
- <description>Challenge #133</description>
- <url>https://github.com/tw.weekly/tw.weekly.c133</url>
+ <name>tw.weekly.c134</name>
+ <description>Challenge #134</description>
+ <url>https://github.com/tw.weekly/tw.weekly.c134</url>
<licenses>
<license>
<name>Eclipse Public License</name>
@@ -24,6 +24,11 @@
<artifactId>clojure</artifactId>
<version>1.10.3</version>
</dependency>
+ <dependency>
+ <groupId>org.clojure</groupId>
+ <artifactId>math.combinatorics</artifactId>
+ <version>0.1.6</version>
+ </dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
diff --git a/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/core.clj b/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/core.clj
new file mode 100644
index 0000000000..4f10a1dcc8
--- /dev/null
+++ b/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/core.clj
@@ -0,0 +1,12 @@
+(ns tw.weekly.c134.core
+ (:require [tw.weekly.c134.t1 :as t1])
+ (:require [tw.weekly.c134.t2 :as t2])
+ (:gen-class))
+
+(defn -main
+ "Run all tasks"
+ [& _]
+ (println "Task #1:")
+ (t1/-main)
+ (println "\nTask #2:")
+ (t2/-main))
diff --git a/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t1.clj b/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t1.clj
new file mode 100644
index 0000000000..553d738f58
--- /dev/null
+++ b/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t1.clj
@@ -0,0 +1,38 @@
+(ns tw.weekly.c134.t1
+ (:require [clojure.edn :as edn]
+ [clojure.pprint :refer [cl-format]]
+ [clojure.math.combinatorics :as combo]))
+
+;;;
+; Task description for TASK #1 › Pandigital Numbers
+;;;
+(def DEFAULT-INPUT [5])
+(def FIRST-PANDIGITAL 1023456789)
+(def MAX-FACTORIAL 8)
+
+(def factorials (map #(reduce * (range % 1 -1)) (range (inc MAX-FACTORIAL))))
+
+(let [pan (->> FIRST-PANDIGITAL str (mapv #(Character/digit % 10)))
+ panlen (count pan)]
+ (defn split-pandigital
+ [n]
+ (-> (fn [_ i]
+ (when (> (nth factorials i) n)
+ (reduced [(apply str (subvec pan 0 (- panlen i)))
+ (subvec pan (- panlen i))])))
+ (reduce (range panlen)))))
+
+(defn pandigitals
+ [n]
+ {:pre [(<= n (last factorials))]}
+ (let [[head tails] (split-pandigital n)
+ source (combo/permutations tails)
+ xf (comp (map (partial apply str head)) (take n))]
+ (sequence xf source)))
+
+(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)]
+ (cl-format true "~{~a~%~}" (pandigitals N))))
diff --git a/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t2.clj b/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t2.clj
new file mode 100644
index 0000000000..8cd893303d
--- /dev/null
+++ b/challenge-134/tyler-wardhaugh/clojure/src/tw/weekly/c134/t2.clj
@@ -0,0 +1,52 @@
+(ns tw.weekly.c134.t2
+ (:require [clojure.edn :as edn]
+ [clojure.string :as str]
+ [clojure.pprint :refer [cl-format print-table]]))
+
+;;;
+; Task description for TASK #2 › Distinct Terms Count
+;;;
+(def DEFAULT-INPUT [3 3])
+
+;;;
+; Clojure provides a built in pretty printer for tables, which is similar to
+; the output requested in the challenge, so let's use that and modify it as
+; necessary.
+;
+; First we transform the input into what the pretty printer expects by
+; converting a table (list-of-lists) to a list of sorted maps where the key is
+; the index and value is unchanged, after prepending each with the inner list
+; count (starting from 1). After feeding that into the printer, we capture it
+; and modify it to our needs.
+;;;
+(defn table-str
+ "Return a pretty-printable representation of table."
+ [table]
+ (let [xf (map-indexed
+ (fn [i v] (into (sorted-map)
+ (map-indexed vector)
+ (conj (seq v) (inc i)))))]
+ (-> (with-out-str (print-table (sequence xf table)))
+ (str/replace-first \0 \x)
+ (str/replace #"(?m)(^\||\|$)" " ")
+ (str/replace #"(?<=\+.*)\+" "-")
+ (str/replace #"(?<=\|.*)\|" " "))))
+
+(defn gen-mult-table
+ "Return a vector of [table distinct-terms], where table is a list-of-lists
+ representing the multiplication table of MxN and distinct-terms is a set of
+ all the terms in said table."
+ [M N]
+ (let [base (for [m (range M), n (range N)] (* (inc m) (inc n)))]
+ (vector (partition N base) (set base))))
+
+(defn -main
+ "Run Task 1 with a given input M and N, defaulting to the first example from
+ the task description."
+ [& args]
+ (let [[M N] (or (some->> args (map edn/read-string)) DEFAULT-INPUT)
+ [table distinct-terms] (gen-mult-table M N)]
+ (cl-format true "~a~%Distinct Terms: ~{~a~^, ~}~%Count: ~a~%"
+ (table-str table)
+ (sort distinct-terms)
+ (count distinct-terms))))
diff --git a/challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t1_test.clj b/challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t1_test.clj
new file mode 100644
index 0000000000..f0c541e6dc
--- /dev/null
+++ b/challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t1_test.clj
@@ -0,0 +1,12 @@
+(ns tw.weekly.c134.t1-test
+ (:require [clojure.test :refer [deftest is testing]]
+ [tw.weekly.c134.t1 :refer [pandigitals]]))
+
+(deftest examples
+ (testing "Examples from description"
+ (is (= ["1023456789"
+ "1023456798"
+ "1023456879"
+ "1023456897"
+ "1023456978"]
+ (pandigitals 5)))))
diff --git a/challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t2_test.clj b/challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t2_test.clj
new file mode 100644
index 0000000000..befa10895e
--- /dev/null
+++ b/challenge-134/tyler-wardhaugh/clojure/test/tw/weekly/c134/t2_test.clj
@@ -0,0 +1,12 @@
+(ns tw.weekly.c134.t2-test
+ (:require [clojure.test :refer [deftest is testing]]
+ [tw.weekly.c134.t2 :refer [gen-mult-table]]))
+
+(deftest examples
+ (testing "Examples from description"
+ (is (= ['((1 2 3) (2 4 6) (3 6 9))
+ #{1 4 6 3 2 9}]
+ (gen-mult-table 3 3)))
+ (is (= ['((1 2 3 4 5) (2 4 6 8 10) (3 6 9 12 15))
+ #{1 4 15 6 3 12 2 9 5 10 8}]
+ (gen-mult-table 3 5)))))