diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-02-19 05:07:09 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-19 05:07:09 +0000 |
| commit | 0d4700b6ebc0749902dd1c9f6a1a05e7cd858513 (patch) | |
| tree | 9818fd589dd74e65a20dfc9022e5c858f6413fcd | |
| parent | a459dbb9ffad17d72463e92ef8eaa1da29901751 (diff) | |
| parent | a98c4f60d9388ffea5c78144e2126fbc3328c114 (diff) | |
| download | perlweeklychallenge-club-0d4700b6ebc0749902dd1c9f6a1a05e7cd858513.tar.gz perlweeklychallenge-club-0d4700b6ebc0749902dd1c9f6a1a05e7cd858513.tar.bz2 perlweeklychallenge-club-0d4700b6ebc0749902dd1c9f6a1a05e7cd858513.zip | |
Merge pull request #3564 from tylerw/tw/challenge-100
Challenge 100
20 files changed, 339 insertions, 27 deletions
diff --git a/challenge-100/tyler-wardhaugh/clojure/README.md b/challenge-100/tyler-wardhaugh/clojure/README.md index 74a213f563..f978c858a6 100644 --- a/challenge-100/tyler-wardhaugh/clojure/README.md +++ b/challenge-100/tyler-wardhaugh/clojure/README.md @@ -1,13 +1,13 @@ -# tw.weekly.c99 +# tw.weekly.c100 -The Weekly Challenge - #099 - Tyler Wardhaugh +The Weekly Challenge - #100 - Tyler Wardhaugh ## Usage Run the project directly (shows default output from both tasks): - $ clojure -M -m tw.weekly.c99.core + $ clojure -M -m tw.weekly.c100.core Run the project's tests (which are samples from the task descriptions): @@ -15,11 +15,11 @@ Run the project's tests (which are samples from the task descriptions): Run Task #1 with input - $ clojure -M -m tw.weekly.c99.t1 S P + $ clojure -M -m tw.weekly.c100.t1 T Run Task #2 with input: - $ clojure -M -m tw.weekly.c99.t2 S T + $ clojure -M -m tw.weekly.c100.t2 T ## Project Template diff --git a/challenge-100/tyler-wardhaugh/clojure/deps.edn b/challenge-100/tyler-wardhaugh/clojure/deps.edn index 4234dbc188..c245240206 100644 --- a/challenge-100/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-100/tyler-wardhaugh/clojure/deps.edn @@ -1,6 +1,6 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.10.1"} - net.mikera/core.matrix {:mvn/version "0.62.0"}} + clojure.java-time {:mvn/version "0.3.2"}} :aliases {:test {:extra-paths ["test"] :extra-deps {org.clojure/test.check {:mvn/version "1.0.0"}}} @@ -11,5 +11,5 @@ :main-opts ["-m" "cognitect.test-runner" "-d" "test"]} :uberjar {:extra-deps {seancorfield/depstar {:mvn/version "1.0.99"}} - :main-opts ["-m" "hf.depstar.uberjar" "tw.weekly.c99.jar" - "-C" "-m" "tw.weekly.c99"]}}} + :main-opts ["-m" "hf.depstar.uberjar" "tw.weekly.c100.jar" + "-C" "-m" "tw.weekly.c100"]}}} diff --git a/challenge-100/tyler-wardhaugh/clojure/pom.xml b/challenge-100/tyler-wardhaugh/clojure/pom.xml index aafdb47364..eb6b9afc9c 100644 --- a/challenge-100/tyler-wardhaugh/clojure/pom.xml +++ b/challenge-100/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.c99</artifactId> + <artifactId>tw.weekly.c100</artifactId> <version>0.1.0-SNAPSHOT</version> - <name>tw.weekly.c99</name> - <description>Challenge #099</description> - <url>https://github.com/tw.weekly/tw.weekly.c99</url> + <name>tw.weekly.c100</name> + <description>Challenge #100</description> + <url>https://github.com/tw.weekly/tw.weekly.c100</url> <licenses> <license> <name>Eclipse Public License</name> @@ -19,9 +19,9 @@ </developer> </developers> <scm> - <url>https://github.com/tw.weekly/tw.weekly.c99</url> - <connection>scm:git:git://github.com/tw.weekly/tw.weekly.c99.git</connection> - <developerConnection>scm:git:ssh://git@github.com/tw.weekly/tw.weekly.c99.git</developerConnection> + <url>https://github.com/tw.weekly/tw.weekly.c100</url> + <connection>scm:git:git://github.com/tw.weekly/tw.weekly.c100.git</connection> + <developerConnection>scm:git:ssh://git@github.com/tw.weekly/tw.weekly.c100.git</developerConnection> <tag>HEAD</tag> </scm> <dependencies> @@ -30,11 +30,6 @@ <artifactId>clojure</artifactId> <version>1.10.1</version> </dependency> - <dependency> - <groupId>net.mikera</groupId> - <artifactId>core.matrix</artifactId> - <version>0.62.0</version> - </dependency> </dependencies> <build> <sourceDirectory>src</sourceDirectory> diff --git a/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/core.clj b/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/core.clj new file mode 100644 index 0000000000..55af76517a --- /dev/null +++ b/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/core.clj @@ -0,0 +1,12 @@ +(ns tw.weekly.c100.core + (:require [tw.weekly.c100.t1 :as t1]) + (:require [tw.weekly.c100.t2 :as t2]) + (:gen-class)) + +(defn -main + "Run all tasks" + [& _] + (println "Task #1:") + (t1/-main) + (println "\nTask #2:") + (t2/-main)) diff --git a/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/t1.clj b/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/t1.clj new file mode 100644 index 0000000000..c25f398dce --- /dev/null +++ b/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/t1.clj @@ -0,0 +1,34 @@ +(ns tw.weekly.c100.t1 + (:require [clojure.edn :as edn] + [clojure.string :as str] + [java-time :as j])) + +;;; +; Task description for TASK #1 › Fun Time +;;; + +(def DEFAULT-INPUT "05:15pm") + +(def FMT-12H "hh:mma") +(def FMT-24H "HH:mm") +(def TIME-MATCHER (re-pattern #"(?i)\s*(\d{1,2}:\d{1,2})\s*([ap]\.?m\.?)?\s*")) + +(defn fun-time + "Convert the given time in string s from 12 hour format to 24 hour format + and vice versa." + [s] + (let [[match hhmm ampm] (re-matches TIME-MATCHER s)] + (when match + (let [[parser timestr fmt] + (if ampm + [FMT-12H (str hhmm (str/upper-case ampm)) FMT-24H] + [FMT-24H hhmm FMT-12H]) + time (j/local-time parser timestr)] + (j/format fmt time))))) + +(defn -main + "Run Task 1 using a string T representing a 12h or 24h time, defaulting to the example + given in the task description." + [& args] + (let [T (or (some-> args first edn/read-string) DEFAULT-INPUT)] + (println (fun-time T)))) diff --git a/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/t2.clj b/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/t2.clj new file mode 100644 index 0000000000..dab8457589 --- /dev/null +++ b/challenge-100/tyler-wardhaugh/clojure/src/tw/weekly/c100/t2.clj @@ -0,0 +1,31 @@ +(ns tw.weekly.c100.t2 + (:require [clojure.edn :as edn])) + +;;; +; Task description for TASK #2 › Triangle Sum +;;; + +(def DEFAULT-INPUT [ [1], [2,4], [6,4,9], [5,1,7,2] ]) + +(defn min-row + "For a row of length n, generate n-1 numbers representing the pair of + each element in row with its right neighbor." + [coll] + (let [xf (map (partial reduce min)) + source (partition 2 1 coll)] + (sequence xf source))) + +(defn min-triangle-sum + "Find the mininum path sum for the triangle from top to bottom." + [t] + (let [f (fn [acc row] (map + (min-row acc) row))] + (->> (reverse t) + (reduce f) + first))) + +(defn -main + "Run Task 2 using a triangle T, defaulting to the example given in the + task description." + [& args] + (let [T (or (some-> args first edn/read-string) DEFAULT-INPUT)] + (println (min-triangle-sum T)))) diff --git a/challenge-100/tyler-wardhaugh/clojure/test/tw/weekly/c100_test.clj b/challenge-100/tyler-wardhaugh/clojure/test/tw/weekly/c100_test.clj new file mode 100644 index 0000000000..d9e5319d83 --- /dev/null +++ b/challenge-100/tyler-wardhaugh/clojure/test/tw/weekly/c100_test.clj @@ -0,0 +1,15 @@ +(ns tw.weekly.c100-test + (:require [clojure.test :refer [deftest is testing]] + [tw.weekly.c100.t1 :refer [fun-time]] + [tw.weekly.c100.t2 :refer [min-triangle-sum]])) + +(deftest task-1 + (testing "Task 1, Fun Time" + (is (= "17:15" (fun-time "05:15 pm"))) + (is (= "17:15" (fun-time "05:15pm"))) + (is (= "07:15PM" (fun-time "19:15"))))) + +(deftest task-2 + (testing "Task 2, Triangle Sum" + (is (= 8 (min-triangle-sum [ [1], [2,4], [6,4,9], [5,1,7,2] ]))) + (is (= 7 (min-triangle-sum [ [3], [3,1], [5,2,3], [4,3,1,3] ]))))) diff --git a/challenge-100/tyler-wardhaugh/lua/README.md b/challenge-100/tyler-wardhaugh/lua/README.md index 2d19587df0..67581457f6 100644 --- a/challenge-100/tyler-wardhaugh/lua/README.md +++ b/challenge-100/tyler-wardhaugh/lua/README.md @@ -1,17 +1,17 @@ # The Weekly Challenge -The Weekly Challenge - #099 - Tyler Wardhaugh +The Weekly Challenge - #100 - Tyler Wardhaugh ## Usage Run Task 1 with input: - $ ./run.lua ch-1 S P + $ ./run.lua ch-1 T Run Task 2: - $ ./run.lua ch-2 S T + $ ./run.lua ch-2 T Run the project's tests (all the samples from the task descriptions plus some others): diff --git a/challenge-100/tyler-wardhaugh/lua/ch-1.lua b/challenge-100/tyler-wardhaugh/lua/ch-1.lua new file mode 100755 index 0000000000..c606922174 --- /dev/null +++ b/challenge-100/tyler-wardhaugh/lua/ch-1.lua @@ -0,0 +1,53 @@ +#!/usr/bin/env lua + +local t1 = {} +t1.DEFAULT_INPUT = '05:15pm' +t1.time_12h_pat = '^%s*(%d%d):(%d%d)%s*([ap]?%.?m%.?)%s*$' +t1.time_24h_pat = '^%s*(%d%d):(%d%d)%s*$' + + +function t1.fun_time(timestr) + timestr = string.lower(timestr) + local new_timestr + + local hh, mm, ampm = timestr:match(t1.time_12h_pat) + if hh then + hh = tonumber(hh) + mm = tonumber(mm) + if ampm:find('a') then + if hh == 12 then hh = 0 end + else + if hh < 12 then hh = hh + 12 end + end + new_timestr = string.format('%02d:%02d', hh, mm) + else + hh, mm = timestr:match(t1.time_24h_pat) + hh = tonumber(hh) + mm = tonumber(mm) + ampm = 'AM' + if hh == 0 then + hh = 12 + ampm = 'AM' + elseif hh == 12 then + ampm = 'PM' + elseif hh > 12 then + ampm = 'PM' + hh = hh - 12 + end + new_timestr = string.format('%02d:%02d%s', hh, mm, ampm) + end + return new_timestr +end + +function t1.run(args) + local timestr + if #args > 0 then + timestr = args[1] + else + timestr = t1.DEFAULT_INPUT + end + + print(t1.fun_time(timestr)) +end + +return t1 diff --git a/challenge-100/tyler-wardhaugh/lua/ch-2.lua b/challenge-100/tyler-wardhaugh/lua/ch-2.lua new file mode 100755 index 0000000000..a1554af6eb --- /dev/null +++ b/challenge-100/tyler-wardhaugh/lua/ch-2.lua @@ -0,0 +1,24 @@ +local t2 = {} +t2.DEFAULT_INPUT = { {1}, {2,4}, {6,4,9}, {5,1,7,2} } + +function t2.min_triangle_sum(triangle) + local n = #triangle + + local left, right + for i = n - 1, 1, -1 do + for j = 1, i do + left = triangle[i + 1][j] + right = triangle[i + 1][j + 1] + triangle[i][j] = triangle[i][j] + math.min(left, right) + end + end + + return triangle[1][1] +end + +function t2.run(_) + local triangle = t2.DEFAULT_INPUT + print(t2.min_triangle_sum(triangle)) +end + +return t2 diff --git a/challenge-100/tyler-wardhaugh/lua/run.lua b/challenge-100/tyler-wardhaugh/lua/run.lua new file mode 100755 index 0000000000..c6e7473bee --- /dev/null +++ b/challenge-100/tyler-wardhaugh/lua/run.lua @@ -0,0 +1,9 @@ +#!/usr/bin/env lua + +local filename = arg[1] +local run_args = table.move(arg, 2, #arg, 1, {}) + +io.write(string.format("Running task from '%s' with {%s}:\n", + filename, table.concat(run_args, ", "))) + +require(filename).run(run_args) diff --git a/challenge-100/tyler-wardhaugh/lua/test.lua b/challenge-100/tyler-wardhaugh/lua/test.lua new file mode 100755 index 0000000000..fb02192b9b --- /dev/null +++ b/challenge-100/tyler-wardhaugh/lua/test.lua @@ -0,0 +1,20 @@ +#!/usr/bin/env lua + +require 'busted.runner'() + +describe("Task 1, Fun Time", function() + local t1 = require'ch-1' + it("produces correct results for the examples", function() + assert.are.same('17:15', t1.fun_time('05:15 pm')) + assert.are.same('17:15', t1.fun_time('05:15pm')) + assert.are.same('07:15PM', t1.fun_time('19:15')) + end) +end) + +describe("Task 2, Triangle Sum", function() + local t2 = require'ch-2' + it("produces correct results for the examples", function() + assert.are.same(8, t2.min_triangle_sum({ {1}, {2,4}, {6,4,9}, {5,1,7,2} })) + assert.are.same(7, t2.min_triangle_sum({ {3}, {3,1}, {5,2,3}, {4,3,1,3} })) + end) +end) diff --git a/challenge-100/tyler-wardhaugh/python/README.md b/challenge-100/tyler-wardhaugh/python/README.md index da9be25946..d540b43280 100644 --- a/challenge-100/tyler-wardhaugh/python/README.md +++ b/challenge-100/tyler-wardhaugh/python/README.md @@ -1,7 +1,7 @@ # The Weekly Challenge -The Weekly Challenge - #099 - Tyler Wardhaugh +The Weekly Challenge - #100 - Tyler Wardhaugh ## Usage @@ -10,11 +10,11 @@ Ensure requirements are satified (ideally in venv): Run Task 1: - $ ./ch1.py S P + $ ./ch1.py T Run Task 2: - $ ./ch2.py S T + $ ./ch2.py T Run the project's tests (all the samples from the task descriptions plus some others): @@ -22,4 +22,3 @@ Run the project's tests (all the samples from the task descriptions plus some ot ## Requirements: * [Python 3](https://www.python.org/) -* [NumPy](https://numpy.org/) diff --git a/challenge-100/tyler-wardhaugh/python/ch-1.py b/challenge-100/tyler-wardhaugh/python/ch-1.py new file mode 100755 index 0000000000..1a7b6a8093 --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/ch-1.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +"""Challenge 100, Task 1""" + +import re +import sys +from datetime import datetime + + +DEFAULT_INPUT = '05:15pm' +TIME_RE = re.compile(r""" + \A + \s*(?P<hhmm>\d{1,2}:\d{1,2}) + \s*(?P<ampm>[ap]\.?m\.?)? + \s* + \Z + """, re.I | re.X) +FMT = { + '12h': { 'parse': "%I:%M%p", 'out': '%H:%M' }, + '24h': { 'parse': "%H:%M", 'out': "%I:%M%p" }, + } + + +def fun_time(timestr): + """Convert the given time from 12 hour format to 24 hour format and vice + versa.""" + + if (m := TIME_RE.match(timestr)): + mgroup = m.groupdict() + fmt = FMT['12h'] if mgroup['ampm'] else FMT['24h'] + new_timestr = mgroup['hhmm'] + str(mgroup['ampm'] or '') + time = datetime.strptime(new_timestr, fmt['parse']) + return time.strftime(fmt['out']) + + +def main(args=None): + """Run the task""" + if args is None: + args = sys.argv[1:] + + timestr = args[0] if args else DEFAULT_INPUT + print(fun_time(timestr)) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/challenge-100/tyler-wardhaugh/python/ch-2.py b/challenge-100/tyler-wardhaugh/python/ch-2.py new file mode 100755 index 0000000000..b143f7f4fe --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/ch-2.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Challenge 100, Task 2""" + +import sys +from functools import reduce + + +DEFAULT_INPUT = [ [1], [2,4], [6,4,9], [5,1,7,2] ] + + +def min_row(row): + """For a row of length n, generate n-1 numbers representing the pair of + each element in row with its right neighbor.""" + for x, y in zip(row, row[1:]): + yield min(x, y) + + +def min_triangle_sum(triangle): + """Find the mininum path sum for the triangle from top to bottom.""" + def f(acc, row): + return [x + y for x, y in zip(min_row(acc), row)] + ans = reduce(f, reversed(triangle)) + return ans[0] + + +def main(args=None): + """Run the task""" + if args is None: + args = sys.argv[1:] + + triangle = None + if args: + import json + triangle = json.loads(args[0]) + else: + triangle = DEFAULT_INPUT + + print(min_triangle_sum(triangle)) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/challenge-100/tyler-wardhaugh/python/ch1.py b/challenge-100/tyler-wardhaugh/python/ch1.py new file mode 120000 index 0000000000..7680b02e4f --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/ch1.py @@ -0,0 +1 @@ +ch-1.py
\ No newline at end of file diff --git a/challenge-100/tyler-wardhaugh/python/ch2.py b/challenge-100/tyler-wardhaugh/python/ch2.py new file mode 120000 index 0000000000..13a132b99f --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/ch2.py @@ -0,0 +1 @@ +ch-2.py
\ No newline at end of file diff --git a/challenge-100/tyler-wardhaugh/python/requirements.txt b/challenge-100/tyler-wardhaugh/python/requirements.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/requirements.txt diff --git a/challenge-100/tyler-wardhaugh/python/test_ch1.py b/challenge-100/tyler-wardhaugh/python/test_ch1.py new file mode 100755 index 0000000000..66669ba9f6 --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/test_ch1.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +import unittest +from ch1 import fun_time + +class TestTask1(unittest.TestCase): + + + def test_example_cases(self): + self.assertEqual('17:15', fun_time('05:15 pm')) + self.assertEqual('17:15', fun_time('05:15pm')) + self.assertEqual('07:15PM', fun_time('19:15')) + + +if __name__ == '__main__': + unittest.main() diff --git a/challenge-100/tyler-wardhaugh/python/test_ch2.py b/challenge-100/tyler-wardhaugh/python/test_ch2.py new file mode 100755 index 0000000000..4b3b13553c --- /dev/null +++ b/challenge-100/tyler-wardhaugh/python/test_ch2.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import unittest +from ch2 import min_triangle_sum + +class TestTask2(unittest.TestCase): + + + def test_example_cases(self): + self.assertEqual(8, min_triangle_sum([ [1], [2,4], [6,4,9], [5,1,7,2] ])) + self.assertEqual(7, min_triangle_sum([ [3], [3,1], [5,2,3], [4,3,1,3] ])) + + +if __name__ == '__main__': + unittest.main() |
