From 2a8a2434896d98d8f59ff739fab15405a191f76b Mon Sep 17 00:00:00 2001 From: Jan Krňávek Date: Sat, 8 Jan 2022 19:24:31 +0100 Subject: solutions week 146 --- challenge-146/wambash/raku/ch-1.raku | 22 ++++++++++++++++++++++ challenge-146/wambash/raku/ch-2.raku | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 challenge-146/wambash/raku/ch-1.raku create mode 100644 challenge-146/wambash/raku/ch-2.raku (limited to 'challenge-146') diff --git a/challenge-146/wambash/raku/ch-1.raku b/challenge-146/wambash/raku/ch-1.raku new file mode 100644 index 0000000000..aa8c9f75ba --- /dev/null +++ b/challenge-146/wambash/raku/ch-1.raku @@ -0,0 +1,22 @@ +#!/usr/bin/env raku + +constant @prime = ^Inf .grep: *.is-prime; + +sub n-prime-number ($n=10001) { + @prime + andthen .skip: $n-1 + andthen .head +} + +multi MAIN (Bool :test($)!) { + use Test; + is n-prime-number(1),2; + is n-prime-number(2),3; + is n-prime-number(6),13; + is n-prime-number(), 104_743; + done-testing; +} + +multi MAIN ($n=10001) { + say n-prime-number $n +} diff --git a/challenge-146/wambash/raku/ch-2.raku b/challenge-146/wambash/raku/ch-2.raku new file mode 100644 index 0000000000..167ec464d6 --- /dev/null +++ b/challenge-146/wambash/raku/ch-2.raku @@ -0,0 +1,27 @@ +#!/usr/bin/env raku + +multi sub parent (Rat $r where * > 1) { + $r - 1 +} + +multi sub parent (Rat $r) { + $r / (1-$r) +} + +sub curious-fraction-tree (Rat $member) { + $member, *.&parent ... 1 +} + +multi MAIN (Bool :test($)!) { + use Test; + is curious-fraction-tree(3/5), (3/5, 3/2, 1/2, 1); + is curious-fraction-tree(4/3), (4/3, 1/3, 1/2, 1); + is curious-fraction-tree(121/155), (121/155, 121/34, 87/34, 53/34, 19/34, 19/15, 4/15, 4/11, 4/7, 4/3, 1/3, 1/2, 1); + done-testing; +} + +multi MAIN ($member) { + curious-fraction-tree $member + andthen .map: *.nude.join: '/' + andthen .put +} -- cgit From b2a17ffd1dc54aae0fb98681489af4604cf49cc2 Mon Sep 17 00:00:00 2001 From: dcw Date: Sat, 8 Jan 2022 21:51:29 +0000 Subject: imported my solutions to both tasks, liked both, and only took 30 minutes overall to solve both --- challenge-146/duncan-c-white/README | 74 ++++++------------- challenge-146/duncan-c-white/perl/MakePrimes.pm | 97 +++++++++++++++++++++++++ challenge-146/duncan-c-white/perl/ch-1.pl | 49 +++++++++++++ challenge-146/duncan-c-white/perl/ch-2.pl | 64 ++++++++++++++++ 4 files changed, 231 insertions(+), 53 deletions(-) create mode 100644 challenge-146/duncan-c-white/perl/MakePrimes.pm create mode 100755 challenge-146/duncan-c-white/perl/ch-1.pl create mode 100755 challenge-146/duncan-c-white/perl/ch-2.pl (limited to 'challenge-146') diff --git a/challenge-146/duncan-c-white/README b/challenge-146/duncan-c-white/README index bdbeb3c3a5..aae0f64482 100644 --- a/challenge-146/duncan-c-white/README +++ b/challenge-146/duncan-c-white/README @@ -1,71 +1,39 @@ -TASK #1 - Dot Product +TASK #1 - 10001st Prime Number -You are given 2 arrays of same size, @a and @b. +Write a script to generate the 10001st prime number. -Write a script to implement Dot Product. +(Remember that 2 is the 1st prime number). -Example: - @a = (1, 2, 3); - @b = (4, 5, 6); +MY NOTES: Very easy, especially (tada) if you happen to have a prime +generating module that you've already used several times in these +challenges.. - $dot_product = (1 * 4) + (2 * 5) + (3 * 6) => 4 + 10 + 18 => 32 -MY NOTES: Very easy. +TASK #2 - Curious Fraction Tree +Consider the following Curious Fraction Tree: -TASK #2 - Palindromic Tree +[diagram in which the root is 1/1, and for each element N/D +it's right child is N+D/D, and it's left child is N/N+D] -You are given a string $s. +You are given a N/D member of the tree created similar to the above sample. -Write a script to create a Palindromic Tree for the given string. - -I found this blog exaplaining Palindromic Tree in detail: - -https://medium.com/@alessiopiergiacomi/eertree-or-palindromic-tree-82453e75025b +Write a script to find out the parent and grandparent of the given member. Example 1: - Input: $s = 'redivider' - Output: r redivider e edivide d divid i ivi v + Input: $member = '3/5'; + Output: parent = '3/2' and grandparent = '1/2' Example 2: - Input: $s = 'deific' - Output: d e i ifi f c - -Example 3: - - Input: $s = 'rotors' - Output: r rotor o oto t s - -Example 4: - - Input: $s = 'challenge' - Output: c h a l ll e n g - -Example 5: - - Input: $s = 'champion' - Output: c h a m p i o n - -Example 6: - - Input: $s = 'christmas' - Output: c h r i s t m a - -MY NOTES: hmm.. I read the blog, but what on earth is it -talking about, it's not very clear? the underlying paper -https://arxiv.org/pdf/1506.04862.pdf is a lot clearer, but -still way too detailed for 10pm on a Sunday. + Input: $member = '4/3'; + Output: parent = '1/3' and grandparent = '1/2' -Looking at the examples given above, the output seems to be -a list of palindromic substrings not previously encountered, -in the natural order found by sequencing through every starting -position in the word and trying increasingly long substrings -for "Palindromic"-ness. +MY NOTES: hmm.. having determined the left and right child rules +above, I worked out that given a child N/D the parent rule is +"if D>N then (N, D-N) else (N-D, D)" -So, could we solve the "generate the output from the input" -problem, entirely ignoring the whole "build a weird tree" -part of it? Presumably a lot less efficient than their -clever eertree/Palindrome tree thingy, but who cares. +So very easy using that rule twice (and why not go all the way up to +the root while we're doing it). diff --git a/challenge-146/duncan-c-white/perl/MakePrimes.pm b/challenge-146/duncan-c-white/perl/MakePrimes.pm new file mode 100644 index 0000000000..6b5cd8e9fe --- /dev/null +++ b/challenge-146/duncan-c-white/perl/MakePrimes.pm @@ -0,0 +1,97 @@ +# +# mkprimes module (converted from mkprimes.c) +# + +use strict; +use warnings; +use Function::Parameters; + + +my $debug = 0; +my @foundprimes; # remember all primes we've found.. + + +fun prime_debug( $d ) +{ + $debug = $d; +} + + +# +# my @primes = primes_upto( $n ); +# Find all primes up to N; return a list of all such primes +# (note that 1 is not usually considered a prime) +# +fun primes_upto( $n ) +{ + my @isprime; + + for( my $i=1; $i<=$n; $i++ ) + { + $isprime[$i] = 1; # initially + } + + # now sieve the non-primes out.. + my $upper = int(sqrt($n)); + printf( "debug: n=%d, upper=%d\n", $n, $upper ) if $debug; + for( my $i=2; $i<=$upper; $i++ ) + { + if( $isprime[$i] ) + { + #printf( "debug: crossing out multiples of %d\n", $i ); + for( my $j=$i*$i; $j<=$n; $j+=$i ) + { + $isprime[$j] = 0; + } + } + } + + # after sieving, extract the primes + my @primes = grep { $isprime[$_] } 2..$n; + + # remember them + @foundprimes = @primes; + + return @primes; +} + + +# +# my @moreprimes = more_primes( $n, $m ); +# Need more primes! Have @foundprimes up to $n, but need +# to sieve primes from $n+1..$m, so re-sieve, return +# a list of all new primes (in the range $n+1..$m) that we find. +# +fun more_primes( $n, $m ) +{ + my %isprime; + + print "finding more primes from ", $n+1, "..$m\n" if $debug; + + for( my $i=$n+1; $i<=$m; $i++ ) + { + $isprime{$i} = 1; # pre-sieving + } + + # now sieve the non-primes out.. + foreach my $prime (@foundprimes) + { + # find first multiple of $prime > $n + my $mult = $prime * (int($n/$prime)+1); + + #print "debug: xo multiples of $prime from $mult to $m\n"; + + for( my $j=$mult; $j<=$m; $j+=$prime ) + { + delete $isprime{$j}; + } + } + + # after sieving, extract the primes + my @primes = grep { $isprime{$_} } $n+1..$m; + push @foundprimes, @primes; + return @primes; +} + + +1; diff --git a/challenge-146/duncan-c-white/perl/ch-1.pl b/challenge-146/duncan-c-white/perl/ch-1.pl new file mode 100755 index 0000000000..c90a9b20de --- /dev/null +++ b/challenge-146/duncan-c-white/perl/ch-1.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl +# +# TASK #1 - 10001st Prime Number +# +# Write a script to generate the 10001st prime number. +# +# (Remember that 2 is the 1st prime number). +# +# +# MY NOTES: Very easy, especially (tada) if you happen to have a prime +# generating module that you've already used several times in these +# challenges.. +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +use Data::Dumper; + +use lib qw(.); +use MakePrimes; + +my $debug=0; +die "Usage: nth-prime [--debug] [N, default 10001]\n" unless + GetOptions( "debug"=>\$debug ) && @ARGV<2; + +my $n = shift // 10001; + +prime_debug( $debug ); + +my $bandwidth = 10000; +my $upto = $bandwidth; +my @primes = primes_upto( $upto ); + +#die Dumper(\@primes); + +my $primesfound = @primes; + +while( $primesfound < $n ) +{ + my $from = $upto; + $upto += $bandwidth; + my @moreprimes = more_primes( $from, $upto ); + push @primes, @moreprimes; + $primesfound = @primes; +} + +say $primes[$n-1]; diff --git a/challenge-146/duncan-c-white/perl/ch-2.pl b/challenge-146/duncan-c-white/perl/ch-2.pl new file mode 100755 index 0000000000..c14d2ac179 --- /dev/null +++ b/challenge-146/duncan-c-white/perl/ch-2.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl +# +# TASK #2 - Curious Fraction Tree +# +# Consider the following Curious Fraction Tree: +# +# [diagram in which the root is 1/1, and for each element N/D +# it's right child is N+D/D, and it's left child is N/N+D] +# +# You are given a N/D member of the tree created similar to the above sample. +# +# Write a script to find out the parent and grandparent of the given member. +# +# Example 1: +# +# Input: $member = '3/5'; +# Output: parent = '3/2' and grandparent = '1/2' +# +# Example 2: +# +# Input: $member = '4/3'; +# Output: parent = '1/3' and grandparent = '1/2' +# +# MY NOTES: hmm.. having determined the left and right child rules +# above, I worked out that given a child N/D the parent rule is +# "if D>N then (N, D-N) else (N-D, D)" +# +# So very easy using that rule twice (and why not go all the way up to +# the root while we're doing it). +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +use Data::Dumper; +use Function::Parameters; + + +my $debug=0; + + +die "Usage: curious-fraction-tree-ancestors [--debug] N/D\n" unless + GetOptions( "debug"=>\$debug ) && @ARGV==1; +my $s = shift; + +die "cft: bad N/D string $s\n" unless $s =~ m|^(\d+)/(\d+)$|; +my( $n, $d ) = ( $1, $2 ); + +my $label = "parent"; + +while( $n>0 && $d>0 ) +{ + # change (n,d) to parent(n,d) + if( $d > $n ) + { + $d -= $n; + } else + { + $n -= $d; + } + say "$label: $n/$d" if $n>0 && $d>0; + $label = "grand$label"; +} -- cgit From 5d774188960c533ff59b4b9a42285b96f893f8c2 Mon Sep 17 00:00:00 2001 From: mohammad khalid anwar Date: Sun, 9 Jan 2022 03:34:07 +0530 Subject: 10001st Prime Number --- challenge-146/khalid-anwar/python/ch-1.py | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 challenge-146/khalid-anwar/python/ch-1.py (limited to 'challenge-146') diff --git a/challenge-146/khalid-anwar/python/ch-1.py b/challenge-146/khalid-anwar/python/ch-1.py new file mode 100644 index 0000000000..f5c05e61f5 --- /dev/null +++ b/challenge-146/khalid-anwar/python/ch-1.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" Returns the n-th prime number By Khalid Anwar +""" +def get_nth_prime_number(nth): + total_number_of_primes = 0 + factor = 2 + s = (nth * factor) + while total_number_of_primes < nth: + primes = make_prime(s) + total_number_of_primes = sum(primes[2:]) + factor += 1 + s = (nth * factor) + nth_prime_number = count_primes(primes, nth) + return nth_prime_number + +""" using the Sieve of Eratosthenes +""" +def make_prime(k): + prime = bytearray([1]*k) + for i in range(2, k): + if prime[i] == 1: + for j in range(i, k): + if i*j < k: + prime[i*j] = 0 + else: + break + return prime + +""" Returns the n-th prime +""" +def count_primes(primes, nth): + count = 0 + for k in range(2, len(primes)): + count += primes[k] + if count == nth: + return k + + +def main(): + NTH = 10001 + nth_prime_number = get_nth_prime_number(NTH) + print("The {}-th prime number is => {}".format(NTH, nth_prime_number)) + + +if __name__ == "__main__": + main() \ No newline at end of file -- cgit From fb0789c3ddec9b910e380206faf65c4510e2c39d Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Sat, 8 Jan 2022 12:45:20 -0800 Subject: prep for challenge New year, new template! --- challenge-146/tyler-wardhaugh/clojure/.gitignore | 22 +++++++++--- challenge-146/tyler-wardhaugh/clojure/LICENSE | 2 +- challenge-146/tyler-wardhaugh/clojure/README.md | 39 +++++++-------------- challenge-146/tyler-wardhaugh/clojure/bb.edn | 39 ++++++--------------- challenge-146/tyler-wardhaugh/clojure/build.clj | 19 ++++++++++ challenge-146/tyler-wardhaugh/clojure/deps.edn | 21 +++++------ challenge-146/tyler-wardhaugh/clojure/pom.xml | 44 ------------------------ 7 files changed, 71 insertions(+), 115 deletions(-) create mode 100644 challenge-146/tyler-wardhaugh/clojure/build.clj delete mode 100644 challenge-146/tyler-wardhaugh/clojure/pom.xml (limited to 'challenge-146') diff --git a/challenge-146/tyler-wardhaugh/clojure/.gitignore b/challenge-146/tyler-wardhaugh/clojure/.gitignore index 894239c8e8..ac8c2a1062 100644 --- a/challenge-146/tyler-wardhaugh/clojure/.gitignore +++ b/challenge-146/tyler-wardhaugh/clojure/.gitignore @@ -1,16 +1,28 @@ *.class *.jar +*.swp +*~ .*_history -.clj-kondo/ -.hg/ -.hgignore -.lsp/ -.projections.json +.sw* +.vscode +/.calva/output-window/ +/.classpath +/.clj-kondo/ /.cpcache/ +/.eastwood/ +/.factorypath +/.hg/ +/.hgignore +/.java-version /.lein-* /.lsp/ /.nrepl-history /.nrepl-port +/.project +/.projections.json +/.rebel_readline_history +/.settings +/.socket-repl-port /checkouts/ /classes/ /target/ diff --git a/challenge-146/tyler-wardhaugh/clojure/LICENSE b/challenge-146/tyler-wardhaugh/clojure/LICENSE index 7689f30efd..d921d3dffe 100644 --- a/challenge-146/tyler-wardhaugh/clojure/LICENSE +++ b/challenge-146/tyler-wardhaugh/clojure/LICENSE @@ -126,7 +126,7 @@ a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and -b) allow the Commercial Contributor tocontrol, and cooperate with the +b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. diff --git a/challenge-146/tyler-wardhaugh/clojure/README.md b/challenge-146/tyler-wardhaugh/clojure/README.md index 213f1884bc..4738867627 100644 --- a/challenge-146/tyler-wardhaugh/clojure/README.md +++ b/challenge-146/tyler-wardhaugh/clojure/README.md @@ -1,48 +1,35 @@ -# tw.weekly.c140 +# c146 - -The Weekly Challenge - #140 - Tyler Wardhaugh +The Weekly Challenge — #146 — Tyler Wardhaugh ## Usage Clojure ([installation instructions](https://clojure.org/guides/getting_started#_clojure_installer_and_cli_tools)) required for `clojure` commands; Babashka ([installation instructions](https://github.com/babashka/babashka#quickstart)) required for the `bb` commands. -Run the project directly (shows default output from both tasks): +Run Task #1: - $ clojure -M -m tw.weekly.c140.core + $ clojure -M:t1 # ... or ... - $ bb run both - -Run the project's tests (which are samples from the task descriptions): + $ bb run task-1 - $ clojure -X:test - # ... or ... - $ bb run test - -Run Task #1 with input +Run Task #2 with input: - $ clojure -M -m tw.weekly.c140.t1 A B + $ clojure -M:t2 M # ... or ... - $ bb run task-1 A B + $ bb run task-2 M -Run Task #2 with input: +Run the project's tests (which are samples from the task descriptions): - $ clojure -M -m tw.weekly.c140.t2 I J K + $ clojure -T:build test # ... or ... - $ bb run task-2 I J K + $ bb run test View available tasks Babashka can run: $ bb tasks -## Project Template - -I used Sean Corfield's clj-new to generate the project template - -See [seancorfield/clj-new: Generate new projects based on clj, Boot, or Leiningen Templates!](https://github.com/seancorfield/clj-new) for more information. - ## License -Copyright © 2021 Tyler Wardhaugh +Copyright © 2022 Tyler Wardhaugh -Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version. +Distributed under the Eclipse Public License version 1.0. diff --git a/challenge-146/tyler-wardhaugh/clojure/bb.edn b/challenge-146/tyler-wardhaugh/clojure/bb.edn index e053ec5de1..e21cd63a1e 100644 --- a/challenge-146/tyler-wardhaugh/clojure/bb.edn +++ b/challenge-146/tyler-wardhaugh/clojure/bb.edn @@ -16,15 +16,13 @@ (defn get-task-ns [task] - (let [glob-target (format "src/tw/weekly/*/%s.clj" (name task)) + (let [glob-target (format "src/*/%s.clj" (name task)) file (->> glob-target (fs/glob ".") first)] (-> file get-first-form second str))) - (defn run-task - ([task args] (run-task task args (get-task-ns task))) - ([task args task-ns] - (let [clj-options (format "-M -m %s " task-ns)] - (apply clojure clj-options args)))) + (defn run-task-clj + [task args] + (apply clojure (str "-M:" task) args)) (defn run-task-bb ([task args] (run-task-bb task args (get-task-ns task))) @@ -43,11 +41,9 @@ (System/exit 1))) clean {:doc "Clean out temporary files" - :task (run! fs/delete-tree - [".nrepl-port" ".cpcache" ".lsp" ".clj-kondo"])} - - generate-pom {:doc "Generate POM file" - :task (clojure "-X:deps mvn-pom")} + :task (do (clojure "-T:build" "clean") + (run! fs/delete-tree + [".nrepl-port" ".cpcache" ".lsp" ".clj-kondo"]))} generate-jar {:doc "Generate JAR file" :depends [generate-pom] @@ -68,35 +64,20 @@ p/check))} test {:doc "Run tests" - :task (clojure "-X:test")} + :task (clojure "-T:build test")} c**** {:doc "CHALLENGE TASKS"} task-1 {:doc "Run Task 1 (via clojure)" - :task (run-task :t1 *command-line-args*)} + :task (run-task-clj :t1 *command-line-args*)} task-1-bb {:doc "Run Task 1 (via Babashka)" :task (run-task-bb :t1 *command-line-args*)} task-2 {:doc "Run Task 2 (via clojure)" - :task (run-task :t2 *command-line-args*)} + :task (run-task-clj :t2 *command-line-args*)} task-2-bb {:doc "Run Task 2 (via Babashka)" :task (run-task-bb :t2 *command-line-args*)} - - both {:doc "Run both tasks (via clojure)" - :task (do - (println "Task 1:") - (run 'task-1) - (println "\nTask 2:") - (run 'task-2))} - - both-bb {:doc "Run both tasks (via Babashka)" - :task (do - (println "Task 1:") - (run 'task-1-bb) - (println "\nTask 2:") - (run 'task-2-bb))} - } } diff --git a/challenge-146/tyler-wardhaugh/clojure/build.clj b/challenge-146/tyler-wardhaugh/clojure/build.clj new file mode 100644 index 0000000000..8a78fbc09a --- /dev/null +++ b/challenge-146/tyler-wardhaugh/clojure/build.clj @@ -0,0 +1,19 @@ +(ns build + (:refer-clojure :exclude [test]) + (:require [org.corfield.build :as bb])) + +(def lib 'net.clojars.c146/c146) +(def version "0.1.0-SNAPSHOT") +(def main 'c146.c146) + +(defn test "Run the tests." [opts] + (bb/run-tests opts)) + +(def clean bb/clean) + +(defn ci "Run the CI pipeline of tests (and build the uberjar)." [opts] + (-> opts + (assoc :lib lib :version version :main main) + (bb/run-tests) + (bb/clean) + (bb/uber))) diff --git a/challenge-146/tyler-wardhaugh/clojure/deps.edn b/challenge-146/tyler-wardhaugh/clojure/deps.edn index 5b1400b27e..16a95bc2f6 100644 --- a/challenge-146/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-146/tyler-wardhaugh/clojure/deps.edn @@ -1,14 +1,15 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.10.3"}} :aliases - {:test {:extra-paths ["test"] - :extra-deps {org.clojure/test.check {:mvn/version "1.1.0"} + {:t1 {:main-opts ["-m" "c146.t1"]} + :t2 {:main-opts ["-m" "c146.t2"]} + :build {:deps {io.github.seancorfield/build-clj + {:git/tag "v0.6.3" :git/sha "9b8e09b" + ;; since we're building an app uberjar, we do not + ;; need deps-deploy for clojars.org deployment: + :deps/root "slim"}} + :ns-default build} + :test {:extra-paths ["test"] + :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"} 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}}}} + {:git/tag "v0.5.0" :git/sha "48c3c67"}}}}} diff --git a/challenge-146/tyler-wardhaugh/clojure/pom.xml b/challenge-146/tyler-wardhaugh/clojure/pom.xml deleted file mode 100644 index e51de32ab2..0000000000 --- a/challenge-146/tyler-wardhaugh/clojure/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - 4.0.0 - tw.weekly - tw.weekly.c140 - 0.1.0-SNAPSHOT - tw.weekly.c140 - Challenge #140 - https://github.com/tw.weekly/tw.weekly.c140 - - - Eclipse Public License - http://www.eclipse.org/legal/epl-v10.html - - - - - Tyler Wardhaugh - - - - - org.clojure - clojure - 1.10.3 - - - - src - - - - clojars - https://repo.clojars.org/ - - - - - clojars - Clojars repository - https://clojars.org/repo - - - -- cgit From fb357b920a95257266a0063ad44d0480b66fbff2 Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Sat, 8 Jan 2022 12:40:06 -0800 Subject: Ch146 (Clojure): Task 1 --- challenge-146/tyler-wardhaugh/clojure/src/c146/t1.clj | 17 +++++++++++++++++ challenge-146/tyler-wardhaugh/clojure/src/c146/t1b.clj | 11 +++++++++++ .../tyler-wardhaugh/clojure/test/c146/t1_test.clj | 8 ++++++++ 3 files changed, 36 insertions(+) create mode 100644 challenge-146/tyler-wardhaugh/clojure/src/c146/t1.clj create mode 100644 challenge-146/tyler-wardhaugh/clojure/src/c146/t1b.clj create mode 100644 challenge-146/tyler-wardhaugh/clojure/test/c146/t1_test.clj (limited to 'challenge-146') diff --git a/challenge-146/tyler-wardhaugh/clojure/src/c146/t1.clj b/challenge-146/tyler-wardhaugh/clojure/src/c146/t1.clj new file mode 100644 index 0000000000..f7e965c92b --- /dev/null +++ b/challenge-146/tyler-wardhaugh/clojure/src/c146/t1.clj @@ -0,0 +1,17 @@ +(ns c146.t1) + +(def TARGET 10001) + +(defn nth-prime + [n] + (let [p (promise) + sieve (fn [n] + (not-any? #(zero? (rem n %)) + (take-while #(<= (* % %) n) @p)))] + (->> @(deliver p (filter sieve (iterate inc 2))) + (drop (dec n)) + first))) + +(defn -main + [& _] + (println (nth-prime TARGET))) diff --git a/challenge-146/tyler-wardhaugh/clojure/src/c146/t1b.clj b/challenge-146/tyler-wardhaugh/clojure/src/c146/t1b.clj new file mode 100644 index 0000000000..0532597b87 --- /dev/null +++ b/challenge-146/tyler-wardhaugh/clojure/src/c146/t1b.clj @@ -0,0 +1,11 @@ +(ns c146.t1b) + +(def TARGET 10001) + +(defn nth-prime + [n] + (nth (iterate #(.nextProbablePrime %) BigInteger/ONE) n)) + +(defn -main + [& _] + (println (nth-prime TARGET))) diff --git a/challenge-146/tyler-wardhaugh/clojure/test/c146/t1_test.clj b/challenge-146/tyler-wardhaugh/clojure/test/c146/t1_test.clj new file mode 100644 index 0000000000..dcfbb9fb6c --- /dev/null +++ b/challenge-146/tyler-wardhaugh/clojure/test/c146/t1_test.clj @@ -0,0 +1,8 @@ +(ns c146.t1-test + (:require [clojure.test :refer [deftest is testing]] + [c146.t1 :as t1] + [c146.t1b :as t1b])) + +(deftest target + (testing "Target identified in task description" + (is (= 104743 (t1/nth-prime t1/TARGET) (t1b/nth-prime t1b/TARGET))))) -- cgit From b145e66a372043b350cee870df46b81034473b70 Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Sat, 8 Jan 2022 15:52:06 -0800 Subject: Ch146 (Clojure): Task 2 --- .../tyler-wardhaugh/clojure/src/c146/t2.clj | 22 ++++++++++++++++++++++ .../tyler-wardhaugh/clojure/test/c146/t2_test.clj | 11 +++++++++++ 2 files changed, 33 insertions(+) create mode 100644 challenge-146/tyler-wardhaugh/clojure/src/c146/t2.clj create mode 100644 challenge-146/tyler-wardhaugh/clojure/test/c146/t2_test.clj (limited to 'challenge-146') diff --git a/challenge-146/tyler-wardhaugh/clojure/src/c146/t2.clj b/challenge-146/tyler-wardhaugh/clojure/src/c146/t2.clj new file mode 100644 index 0000000000..b259c8edc8 --- /dev/null +++ b/challenge-146/tyler-wardhaugh/clojure/src/c146/t2.clj @@ -0,0 +1,22 @@ +(ns c146.t2 + (:require [clojure.edn :as edn] + [clojure.pprint :refer [cl-format]])) + +; Clojure supports Ratios (including as literals) +(def DEFAULT-INPUT [3/5]) + +(defn parent + [x] + (when (not= x 1) + (let [[n d] ((juxt numerator denominator) x)] + (if (< x 1) + (/ n (- d n)) ; left + (/ (- n d) d))))) ; right + +(defn -main + "Run Task 2 with a given input M, defaulting to the first example from the + task description." + [& args] + (let [[M] (or (some->> args (map edn/read-string)) DEFAULT-INPUT)] + (cl-format true "~{parent = '~a' and grandparent = '~a'~}~%" + (->> M (iterate parent) (drop 1) (take 2))))) diff --git a/challenge-146/tyler-wardhaugh/clojure/test/c146/t2_test.clj b/challenge-146/tyler-wardhaugh/clojure/test/c146/t2_test.clj new file mode 100644 index 0000000000..48dd9ca00a --- /dev/null +++ b/challenge-146/tyler-wardhaugh/clojure/test/c146/t2_test.clj @@ -0,0 +1,11 @@ +(ns c146.t2-test + (:refer-clojure :exclude [ancestors]) + (:require [clojure.test :refer [deftest is testing]] + [c146.t2 :refer [parent]])) + +(def ancestors (juxt parent (comp parent parent))) + +(deftest examples + (testing "Examples from task description" + (is (= [3/2 1/2] (ancestors 3/5))) + (is (= [1/3 1/2] (ancestors 4/3))))) -- cgit From c352307e0bc3f2777d0e2ccd64d5e77e3ce08cf6 Mon Sep 17 00:00:00 2001 From: Tyler Wardhaugh Date: Sat, 8 Jan 2022 17:02:41 -0800 Subject: flesh out README a bit more --- challenge-146/tyler-wardhaugh/clojure/README.md | 17 ++++++++++++++++- challenge-146/tyler-wardhaugh/clojure/bb.edn | 6 ++++++ challenge-146/tyler-wardhaugh/clojure/deps.edn | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'challenge-146') diff --git a/challenge-146/tyler-wardhaugh/clojure/README.md b/challenge-146/tyler-wardhaugh/clojure/README.md index 4738867627..ea5ea9467a 100644 --- a/challenge-146/tyler-wardhaugh/clojure/README.md +++ b/challenge-146/tyler-wardhaugh/clojure/README.md @@ -6,18 +6,33 @@ The Weekly Challenge — #146 — Tyler Wardhaugh Clojure ([installation instructions](https://clojure.org/guides/getting_started#_clojure_installer_and_cli_tools)) required for `clojure` commands; Babashka ([installation instructions](https://github.com/babashka/babashka#quickstart)) required for the `bb` commands. -Run Task #1: +Run Task #1 (implemented with a sieve): $ clojure -M:t1 # ... or ... $ bb run task-1 + # Alternatively, to run it via Babashka: + $ bb run task-1-bb + +Run Task #1b (implemented using JVM's BigInteger library): + + $ clojure -M:t1b + # ... or ... + $ bb run task-1b + + # Alternatively, to run it via Babashka: + $ bb run task-1b-bb + Run Task #2 with input: $ clojure -M:t2 M # ... or ... $ bb run task-2 M + # Alternatively, to run it via Babashka: + $ bb run task-2-bb + Run the project's tests (which are samples from the task descriptions): $ clojure -T:build test diff --git a/challenge-146/tyler-wardhaugh/clojure/bb.edn b/challenge-146/tyler-wardhaugh/clojure/bb.edn index e21cd63a1e..fdbac4a730 100644 --- a/challenge-146/tyler-wardhaugh/clojure/bb.edn +++ b/challenge-146/tyler-wardhaugh/clojure/bb.edn @@ -74,6 +74,12 @@ task-1-bb {:doc "Run Task 1 (via Babashka)" :task (run-task-bb :t1 *command-line-args*)} + task-1b {:doc "Run Task 1 (via clojure)" + :task (run-task-clj :t1b *command-line-args*)} + + task-1b-bb {:doc "Run Task 1 (via Babashka)" + :task (run-task-bb :t1b *command-line-args*)} + task-2 {:doc "Run Task 2 (via clojure)" :task (run-task-clj :t2 *command-line-args*)} diff --git a/challenge-146/tyler-wardhaugh/clojure/deps.edn b/challenge-146/tyler-wardhaugh/clojure/deps.edn index 16a95bc2f6..247ad7b44d 100644 --- a/challenge-146/tyler-wardhaugh/clojure/deps.edn +++ b/challenge-146/tyler-wardhaugh/clojure/deps.edn @@ -2,6 +2,7 @@ :deps {org.clojure/clojure {:mvn/version "1.10.3"}} :aliases {:t1 {:main-opts ["-m" "c146.t1"]} + :t1b {:main-opts ["-m" "c146.t1b"]} :t2 {:main-opts ["-m" "c146.t2"]} :build {:deps {io.github.seancorfield/build-clj {:git/tag "v0.6.3" :git/sha "9b8e09b" -- cgit From fb8d07bc2806e0dd6d40e1d22d2e1f3b4e66c992 Mon Sep 17 00:00:00 2001 From: Conor Hoekstra Date: Sun, 9 Jan 2022 00:20:06 -0500 Subject: Week 146 in APL --- challenge-146/conor-hoekstra/apl/ch-1.apl | 1 + 1 file changed, 1 insertion(+) create mode 100644 challenge-146/conor-hoekstra/apl/ch-1.apl (limited to 'challenge-146') diff --git a/challenge-146/conor-hoekstra/apl/ch-1.apl b/challenge-146/conor-hoekstra/apl/ch-1.apl new file mode 100644 index 0000000000..3e6b41a9d0 --- /dev/null +++ b/challenge-146/conor-hoekstra/apl/ch-1.apl @@ -0,0 +1 @@ +10001⊃1↓⍸((1=≢∘∪)∨∘(⍳∘⌊.5*⍨⊢)⍨)¨⍳110000 ⍝ 104743 -- cgit From 6c324d646e7831362edb09d1303b1a1d93ed848a Mon Sep 17 00:00:00 2001 From: Mohammad S Anwar Date: Sun, 9 Jan 2022 12:00:06 +0000 Subject: - Added solutions by Mark Senn. --- challenge-146/mark-senn/blog.txt | 1 + challenge-146/mark-senn/blog1.txt | 1 + challenge-146/mark-senn/raku/ch-1.raku | 1 + challenge-146/mark-senn/raku/ch-2.raku | 16 ++++++++++++++++ challenge-146/mark-senn/raku/ch-2a.raku | 17 +++++++++++++++++ 5 files changed, 36 insertions(+) create mode 100644 challenge-146/mark-senn/blog.txt create mode 100644 challenge-146/mark-senn/blog1.txt create mode 100644 challenge-146/mark-senn/raku/ch-1.raku create mode 100644 challenge-146/mark-senn/raku/ch-2.raku create mode 100644 challenge-146/mark-senn/raku/ch-2a.raku (limited to 'challenge-146') diff --git a/challenge-146/mark-senn/blog.txt b/challenge-146/mark-senn/blog.txt new file mode 100644 index 0000000000..03584819da --- /dev/null +++ b/challenge-146/mark-senn/blog.txt @@ -0,0 +1 @@ +https://engineering.purdue.edu/~mark/twc-146-1.pdf diff --git a/challenge-146/mark-senn/blog1.txt b/challenge-146/mark-senn/blog1.txt new file mode 100644 index 0000000000..80132e1bbe --- /dev/null +++ b/challenge-146/mark-senn/blog1.txt @@ -0,0 +1 @@ +https://engineering.purdue.edu/~mark/twc-146-2.pdf diff --git a/challenge-146/mark-senn/raku/ch-1.raku b/challenge-146/mark-senn/raku/ch-1.raku new file mode 100644 index 0000000000..26089ad900 --- /dev/null +++ b/challenge-146/mark-senn/raku/ch-1.raku @@ -0,0 +1 @@ +(1 .. Inf).grep({ .is-prime })[10_000].say; diff --git a/challenge-146/mark-senn/raku/ch-2.raku b/challenge-146/mark-senn/raku/ch-2.raku new file mode 100644 index 0000000000..57b71be1b2 --- /dev/null +++ b/challenge-146/mark-senn/raku/ch-2.raku @@ -0,0 +1,16 @@ +my $member = $*IN.get; + +# Split into numerator and denominator. +my ($n, $d) = $member.split('/'); + +say "Input: \$member = '$n/$d'"; + +for ('Output: parent =', ' and grandparent =') -> $label +{ + if ($n < $d) { $d = $d - $n; } + elsif ($n == $d) { say "no parent"; exit 1; } + else { $n = $n - $d; } + print "$lable '$n/$d'"; +} + +say ''; diff --git a/challenge-146/mark-senn/raku/ch-2a.raku b/challenge-146/mark-senn/raku/ch-2a.raku new file mode 100644 index 0000000000..6d832070c6 --- /dev/null +++ b/challenge-146/mark-senn/raku/ch-2a.raku @@ -0,0 +1,17 @@ +my $member = $*IN.get; + +# Split into numerator and denominator. +my ($n, $d) = $member.split('/'); + +say "Input: \$member = '$n/$d'"; + +for ('Output: parent =', ' and grandparent =') -> $label { + given ($n <=> $d) { + when -1 { $d = $d - $n; } # n < d + when 0 { say "no parent"; exit 1; } # n = d + when 1 { $n = $n - $d; } # n > d + } + print "$_ '$n/$d'"; +} + +say ''; -- cgit From bf0e37317122de0322d69b1c68bd07ccfc5b36a8 Mon Sep 17 00:00:00 2001 From: Mohammad S Anwar Date: Sun, 9 Jan 2022 19:38:28 +0000 Subject: - Added solutions by Pete Houston. --- challenge-146/pete-houston/perl/ch-1.pl | 22 ++++++++ challenge-146/pete-houston/perl/ch-2.pl | 96 +++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100755 challenge-146/pete-houston/perl/ch-1.pl create mode 100755 challenge-146/pete-houston/perl/ch-2.pl (limited to 'challenge-146') diff --git a/challenge-146/pete-houston/perl/ch-1.pl b/challenge-146/pete-houston/perl/ch-1.pl new file mode 100755 index 0000000000..78477cbaa7 --- /dev/null +++ b/challenge-146/pete-houston/perl/ch-1.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +#=============================================================================== +# +# FILE: 14601.pl +# +# USAGE: ./14601.pl [ N ] +# +# DESCRIPTION: Output the Nth prime (defaults to 10001) +# +# OPTIONS: N defaults to 10_001 if unspecified +# REQUIREMENTS: Math::Prime::Util, what else? +# AUTHOR: Pete Houston (pete), cpan@openstrike.co.uk +# ORGANIZATION: Openstrike +# VERSION: 1.0 +# CREATED: 05/01/22 +#=============================================================================== + +use strict; +use warnings; +use Math::Prime::Util 'nth_prime'; + +print nth_prime (shift // 10_001) . "\n"; diff --git a/challenge-146/pete-houston/perl/ch-2.pl b/challenge-146/pete-houston/perl/ch-2.pl new file mode 100755 index 0000000000..eafd0a7e2c --- /dev/null +++ b/challenge-146/pete-houston/perl/ch-2.pl @@ -0,0 +1,96 @@ +#!/usr/bin/env perl +#=============================================================================== +# +# FILE: 14602.pl +# +# USAGE: ./14602.pl N/M +# +# DESCRIPTION: Print out 2 ancestors of the tree value matching the +# argument. +# +# REQUIREMENTS: Class::Tiny +# NOTES: The tree is really unnecessary here. See 14602b.pl for +# alternative approach without one. +# AUTHOR: Pete Houston (pete), cpan@openstrike.co.uk +# ORGANIZATION: Openstrike +# VERSION: 1.0 +# CREATED: 03/01/22 +#=============================================================================== + +use strict; +use warnings; + +# Each pair of children have values which are: +# Left: parent numerator over sum of parent numerator and denominator +# Right: sum of parent numerator and denominator over parent denominator + +package Node; + +use Class::Tiny qw/lchild rchild parent value/; + +sub BUILD { + + #my ($class, $value, $r, $maxdepth, $parent) = @_; + my ($self, $args) = @_; + my $r = $args->{row}; + my $maxdepth = $args->{maxdepth}; + + # Build tree from 1/1 + unless ($args->{row}) { + $r //= 0; + $self->value ('1/1') unless defined $self->value; + } + + # Add children if we are not the bottom row + if ($r < $maxdepth) { + my ($num, $dom) = split /\//, $self->value; + my $sum = $num + $dom; + my %childargs = ( + row => $r + 1, + maxdepth => $maxdepth, + parent => $self + ); + $self->lchild (Node->new (value => "$num/$sum", %childargs)); + $self->rchild (Node->new (value => "$sum/$dom", %childargs)); + } + +} + +# Retrieve or calculate the minimum path downwards from here. +sub find_by_value { + my ($self, $value) = @_; + return $self if $self->value eq $value; + for my $child ($self->lchild, $self->rchild) { + next unless defined $child; + my $res = $child->find_by_value ($value); + return $res if defined $res; + } + return; +} + +package main; + +my $root = Node->new (value => '1/1', row => 0, maxdepth => 4); + +my $v = shift; +my $one = $root->find_by_value ($v); + +unless (defined $one) { + print "No match for value '$v' found\n"; + exit; +} + +my $parent = $one->parent; +unless (defined $parent) { + print "No parent found\n"; + exit; +} +print "parent = '" . $parent->value . "' and "; + +my $gparent = $parent->parent; +unless (defined $gparent) { + print "no grandparent found\n"; + exit; +} +print "grandparent = '" . $gparent->value . "'\n"; + -- cgit From 48b7a6a3696f0557c667adce9b0b03d845213ac9 Mon Sep 17 00:00:00 2001 From: mohammad khalid anwar Date: Mon, 10 Jan 2022 01:46:30 +0530 Subject: Fraction Tree solution in PHP by Khalid Anwar challenge 146 --- challenge-146/khalid-anwar/php/ch-2.php | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 challenge-146/khalid-anwar/php/ch-2.php (limited to 'challenge-146') diff --git a/challenge-146/khalid-anwar/php/ch-2.php b/challenge-146/khalid-anwar/php/ch-2.php new file mode 100644 index 0000000000..9e2daaa05e --- /dev/null +++ b/challenge-146/khalid-anwar/php/ch-2.php @@ -0,0 +1,55 @@ +\d+)?\s?((?P\d+)\/(?P\d+))?$/', $fraction, $components); + // Extract numerator, and denominator components + $numerator = $components['numerator'] ?: 0; + $denominator = $components['denominator'] ?: 0; + return $components; +} + +function getParent($c, $d){ + $parent = Array(); + if ($c > $d){ + $parent['p_nominator'] = $c-$d; + $parent['p_denominator'] = $d; + }else{ + $parent['p_nominator'] = $c; + $parent['p_denominator'] = $d-$c; + } + return $parent; +} + +// Testing of member input, first input is set as default in this code. Others can be tested by uncommenting it accordingly +// online php editor reference : https://paiza.io/en/projects/new + +$member = '3/5'; //input 1 +//$member = '4/3'; //input 2 +//$member = '3/4'; //input 3 + +$var = getNumeratorDenominator($member); + +echo "For member =".$member."\n"; +$parent = getParent($var['numerator'],$var['denominator']); +echo "Parent = ".$parent['p_nominator']."/".$parent['p_denominator']; +echo " and "; +$grandParent = getParent($parent['p_nominator'],$parent['p_denominator']); +echo "GrandParent = ".$grandParent['p_nominator']."/".$grandParent['p_denominator']; + +?> -- cgit From 48378db6c5177d3119d06fe99c687bbcf2c96a41 Mon Sep 17 00:00:00 2001 From: mohammad khalid anwar Date: Mon, 10 Jan 2022 02:00:18 +0530 Subject: update file --- challenge-146/khalid-anwar/php/ch-2.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'challenge-146') diff --git a/challenge-146/khalid-anwar/php/ch-2.php b/challenge-146/khalid-anwar/php/ch-2.php index 9e2daaa05e..a63a3a5046 100644 --- a/challenge-146/khalid-anwar/php/ch-2.php +++ b/challenge-146/khalid-anwar/php/ch-2.php @@ -1,11 +1,11 @@ Date: Mon, 10 Jan 2022 02:28:29 +0530 Subject: Update ch-1.py --- challenge-146/khalid-anwar/python/ch-1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'challenge-146') diff --git a/challenge-146/khalid-anwar/python/ch-1.py b/challenge-146/khalid-anwar/python/ch-1.py index f5c05e61f5..62e628bbdd 100644 --- a/challenge-146/khalid-anwar/python/ch-1.py +++ b/challenge-146/khalid-anwar/python/ch-1.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -""" Returns the n-th prime number By Khalid Anwar +""" Returns the nth prime number By Khalid Anwar """ def get_nth_prime_number(nth): total_number_of_primes = 0 @@ -43,4 +43,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() -- cgit From 329ea0e601d67c6eb37e8677aba54922a4680603 Mon Sep 17 00:00:00 2001 From: Ian Goodnight Date: Sun, 9 Jan 2022 16:34:53 -0500 Subject: challenge 146 --- challenge-146/iangoodnight/javascript/ch-1.js | 73 ++++++++ challenge-146/iangoodnight/javascript/ch-2.js | 257 ++++++++++++++++++++++++++ challenge-146/iangoodnight/perl/ch-1.pl | 96 ++++++++++ challenge-146/iangoodnight/perl/ch-2.pl | 242 ++++++++++++++++++++++++ challenge-146/iangoodnight/python/ch-1.py | 77 ++++++++ challenge-146/iangoodnight/ruby/ch-1.rb | 65 +++++++ challenge-146/iangoodnight/ruby/ch-2.rb | 158 ++++++++++++++++ 7 files changed, 968 insertions(+) create mode 100755 challenge-146/iangoodnight/javascript/ch-1.js create mode 100755 challenge-146/iangoodnight/javascript/ch-2.js create mode 100755 challenge-146/iangoodnight/perl/ch-1.pl create mode 100755 challenge-146/iangoodnight/perl/ch-2.pl create mode 100755 challenge-146/iangoodnight/python/ch-1.py create mode 100755 challenge-146/iangoodnight/ruby/ch-1.rb create mode 100755 challenge-146/iangoodnight/ruby/ch-2.rb (limited to 'challenge-146') diff --git a/challenge-146/iangoodnight/javascript/ch-1.js b/challenge-146/iangoodnight/javascript/ch-1.js new file mode 100755 index 0000000000..dd9b97965f --- /dev/null +++ b/challenge-146/iangoodnight/javascript/ch-1.js @@ -0,0 +1,73 @@ +#!/usr/bin/env node +// ch-1.js + +/******************************************************************************* + * https://theweeklychallenge.org/blog/perl-weekly-challenge-146/ + * + * ## Task 1 > 10001st Prime Number + * ================================ + * + * Write a script to generate the 10001st prime number. + ******************************************************************************/ + +'use strict'; + +/******************************************************************************* + * PWC Solution **************************************************************** + ******************************************************************************/ + +function getPrime(numPrime = 10001) { + const primes = [2, 3]; + + const limit = parseInt(numPrime, 10); + + const isPrime = (n) => + !primes.some( + (prime) => prime <= Math.floor(Math.sqrt(n)) && n % prime === 0, + ); + + let num = 5; + + while (primes.length < limit) { + if (isPrime(num)) primes.push(num); + num += 2; + } + + return primes.slice(-1)[0]; +} + +/******************************************************************************* + * Utilities ******************************************************************* + ******************************************************************************/ + +function getSuffix(num) { + const lastDigit = parseInt([...num.toString()].pop(), 10); + + if (lastDigit === 0 || lastDigit >= 4) return 'th'; + if (lastDigit === 1) return 'st'; + if (lastDigit === 2) return 'nd'; + if (lastDigit === 3) return 'rd'; + return ''; +} + +const colors = { + yellow: '\x1b[33m', + green: '\x1b[32m', + reset: '\x1b[0m', +}; + +/******************************************************************************* + * Main ************************************************************************ + ******************************************************************************/ + +(function main() { + const nth = process.argv[2] || 10001; + + const prime = getPrime(nth); + + const suffix = getSuffix(nth); + + const { yellow: y, green: g, reset: r } = colors; + + console.log(`The ${y + nth + suffix + r} prime number is: ${g + prime + r}`); +})(); diff --git a/challenge-146/iangoodnight/javascript/ch-2.js b/challenge-146/iangoodnight/javascript/ch-2.js new file mode 100755 index 0000000000..a71c81fa85 --- /dev/null +++ b/challenge-146/iangoodnight/javascript/ch-2.js @@ -0,0 +1,257 @@ +#!/usr/bin/env node +// ch-2.js + +/******************************************************************************* + * https://theweeklychallenge.org/blog/perl-weekly-challenge-146/ + * + * ## Task 2 > Curious Fraction Tree + * ================================= + * + * Consider the following `Curious Fraction Tree`: + * + * ``` + * __________1/1__________ + * / \ + * ___1/2___ ___2/1___ + * / \ / \ + * 1/3 3/2 2/3 3/1 + * / \ / \ / \ / \ + * 1/4 4/3 3/5 5/2 2/5 5/3 3/4 4/1 + * ``` + * + * You are given a fraction, member of the tree created similar to the above + * sample. + * + * Write a script to find out the parent and grandparent of the given member. + * + * **Example 1:** + * + * ``` + * Input: $member = '3/5'; + * Output: parent = '3/2' and grandparent = '1/2' + * ``` + * + * **Example 2:** + * + * ``` + * Input: $member = '4/3'; + * Output: parent = '1/3' and grandparent = '1/2' + * ``` + * + ******************************************************************************/ + +'use strict'; + +/******************************************************************************* + * Dependencies **************************************************************** + ******************************************************************************/ + +const readline = require('readline'); + +/******************************************************************************* + * PWC Solution **************************************************************** + ******************************************************************************/ + +// Input guard +function isFractionString(string) { + const re = /^\d+\/\d+$/; + + return typeof string === 'string' && re.test(string.trim()); +} + +// Find immediate parent +function getCuriousParent(member = '1/1') { + if (!isFractionString(member)) { + const badArg = '`getCuriousParent` expects a string (i.e.: "3/4")'; + + throw new Error(badArg); + } + + const [num, den] = member.split('/').map((elem) => parseInt(elem, 10)); + + const value = num / den; + + if (value > 1) return `${num - den}/${den}`; + if (value < 1) return `${num}/${den - num}`; + return null; +} + +// Returns whole chain from member to root +function getCuriousTree(member = '1/1') { + if (!isFractionString(member)) { + throw new Error('`getCuriousTree` expects a string (i.e.: "3/2")'); + } + + const parents = []; + + let child = member; + + while (child !== null) { + parents.push(child); + child = getCuriousParent(child); + } + + return parents; +} + +// Not really necessarily to abstract this step, but it makes it easier to do +// other things with the whole chain, like figure out if it is rooted at 1/1 or +// not +function getCuriousGenerations(tree = [], generations = 2) { + return tree.slice(1, generations + 1); +} + +/******************************************************************************* + * Utilities ******************************************************************* + ******************************************************************************/ + +const colors = { + green: '\x1b[32m', + red: '\x1b[31m', + reset: '\x1b[0m', + yellow: '\x1b[33m', +}; + +function formatOutput(tree = [], termColors = {}) { + const { yellow: y = '', green: g = '', reset: rst = '' } = termColors; + + return tree + .map((member, idx, array) => { + const { length } = array; + + const conjunction = idx === length - 1 && length !== 1 ? 'and ' : ''; + + const last = idx === length - 1; + + let ordinal = idx === 0 ? 'parent' : 'grandparent'; + + if (idx > 1) ordinal = 'great-'.repeat(idx - 1) + ordinal; + + let separator = last ? '' : ', '; + + if (length === 2) separator = ' '; + + return `${conjunction}${y + ordinal + rst} = ${ + g + member + rst + }${separator}`; + }) + .join(''); +} + +function assertRoot(tree = [], termColors = {}) { + const last = [...tree].pop(); + + const { + green: g = '', + red: r = '', + reset: rst = '', + yellow: y = '', + } = termColors; + + if (last !== '1/1') { + return `${y}Curious fraction tree rooted at ${ + r + last + y + } and not at ${`${g}1/1${rst}`}`; + } + return null; +} + +function repl(termColors = {}) { + const { green: g = '', yellow: y = '', reset: rst = '' } = termColors; + + return new Promise((resolve) => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + /* eslint-disable prefer-template */ + const mainPrompt = + 'Enter a fraction (i.e.: "' + + g + + '3/5' + + rst + + '") or type "' + + y + + 'exit' + + rst + + '" to quit /> '; + + const morePrompt = + 'Enter "' + + y + + 'more' + + rst + + '" to see more details, or enter a fraction (i.e.: "' + + g + + '3/5' + + rst + + '") to continue /> '; + /* eslint-enable prefer-template */ + + let currentTree; + let generations; + let assertedRoot; + + rl.setPrompt(mainPrompt); + + rl.prompt(); + + rl.on('line', (line) => { + const input = line.trim().toLowerCase(); + + if (input === 'exit' || input === 'quit' || input === 'q') { + return rl.close(); + } + + if (isFractionString(input)) { + currentTree = getCuriousTree(input); + generations = getCuriousGenerations(currentTree, 2); + assertedRoot = assertRoot(currentTree, termColors); + console.log(formatOutput(generations, termColors)); + rl.setPrompt(morePrompt); + return rl.prompt(); + } + + if (input === 'more') { + console.log(formatOutput(currentTree.slice(1), termColors)); + if (assertedRoot) console.log(assertedRoot); + currentTree = null; + generations = null; + assertedRoot = null; + rl.setPrompt(mainPrompt); + return rl.prompt(); + } + console.log(`Sorry, I don't understand ${input}.`); + return rl.prompt(); + }).on('close', () => { + console.log(`${y}Goodbye.${rst}`); + resolve(); + }); + }); +} + +function printBanner(termColors = {}) { + const { yellow: y = '', reset: rst = '' } = termColors; + + const message = 'A Curious Fraction Tree'; + + const underline = '='.repeat(message.length); + + console.log(`${y}${message}`); + console.log(`${underline}${rst}`); +} + +/******************************************************************************* + * Main ************************************************************************ + ******************************************************************************/ + +(async function main() { + try { + printBanner(colors); + await repl(colors); + } catch (error) { + console.log(error); + process.exit(1); + } +})(); diff --git a/challenge-146/iangoodnight/perl/ch-1.pl b/challenge-146/iangoodnight/perl/ch-1.pl new file mode 100755 index 0000000000..34d5b75eff --- /dev/null +++ b/challenge-146/iangoodnight/perl/ch-1.pl @@ -0,0 +1,96 @@ +#!/usr/bin/perl +# ch-1.pl + +=begin comment + + https://theweeklychallenge.org/blog/perl-weekly-challenge-146/ + + ## Task 1 > 10001st Prime Number + ================================ + + Write a script to generate the 10001st prime number. + +=end comment +=cut + +use strict; +use warnings; + +################################################################################ +# PWC Solution ################################################################# +################################################################################ + +sub get_prime { + my $nth = shift; + my @primes = ( 2, 3 ); + my $num = 5; + + if ( $nth <= 2 ) { + return $primes[ $nth - 1 ]; + } + + while ( scalar @primes < $nth ) { + my $is_prime = 1; + for my $prime (@primes) { + if ( int( sqrt($num) ) < $prime ) { + last; + } + if ( $num % $prime == 0 ) { + $is_prime = 0; + last; + } + } + if ($is_prime) { + push @primes, $num; + } + + $num += 2; + } + return $primes[-1]; +} + +################################################################################ +# Utilities #################################################################### +################################################################################ + +sub get_suffix { + my $last_digit = substr shift, -1; + + if ( $last_digit == 0 || $last_digit >= 4 ) { + return 'th'; + } + if ( $last_digit == 1 ) { + return 'st'; + } + if ( $last_digit == 2 ) { + return 'nd'; + } + if ( $last_digit == 3 ) { + return 'rd'; + } + return q{ }; +} + +sub color_string { + my $str = shift; + my $color = shift; + my %colors = ( + yellow => "\e[33m", + green => "\e[32m", + ); + my $reset = "\e[0m"; + + return $colors{$color} . $str . $reset; +} + +################################################################################ +# Main ######################################################################### +################################################################################ + +my $nth = shift @ARGV // '10001'; +my $prime = get_prime $nth; +my $suffix = get_suffix $nth; +my $num_string = color_string( $nth . $suffix, 'yellow' ); +my $prime_string = color_string( $prime, 'green' ); + +print "The $num_string prime number is $prime_string\n"; diff --git a/challenge-146/iangoodnight/perl/ch-2.pl b/challenge-146/iangoodnight/perl/ch-2.pl new file mode 100755 index 0000000000..a8bc926997 --- /dev/null +++ b/challenge-146/iangoodnight/perl/ch-2.pl @@ -0,0 +1,242 @@ +#!/usr/bin/perl +# ch-2.pl + +=begin comment + + https://theweeklychallenge.org/blog/perl-weekly-challenge-146/ + + ## Task 2 > Curious Fraction Tree + ================================= + + Consider the following `Curious Fraction Tree`: + + ``` + __________1/1__________ + / \ + ___1/2___ ___2/1___ + / \ / \ + 1/3 3/2 2/3 3/1 + / \ / \ / \ / \ + 1/4 4/3 3/5 5/2 2/5 5/3 3/4 4/1 + ``` + + You are given a fraction, member of the tree created similar to the above + sample. + + Write a script to find out the parent and grandparent of the given member. + + **Example 1:** + + ``` + Input: $member = '3/5'; + Output: parent = '3/2' and grandparent = '1/2' + ``` + + **Example 2:** + + ``` + Input: $member = '4/3'; + Output: parent = '1/3' and grandparent = '1/2' + ``` + +=end comment +=cut + +use strict; +use warnings; + +################################################################################ +# PWC Solution ################################################################# +################################################################################ + +sub is_fraction_string { + my $string = shift; + + if ( $string =~ m{ \A \s* \d+ / \d+ \s* \z }x ) { + $string =~ s/ \A \s+ | \s+ \z//gx; + return $string; + } + return 0; +} + +sub get_curious_parent { + my $member = shift; + my $fraction = is_fraction_string $member; + + die qq{`get_curious_parent` expects a string (i.e.: "3/5"), got $member\n} + unless $fraction; + + my ( $num, $den ) = split qr{ / }x, $fraction; + my $quotient = $num / $den; + + if ( $quotient > 1 ) { + return ( $num - $den ) . q{/} . $den; + } + if ( $quotient < 1 ) { + return $num . q{/} . ( $den - $num ); + } + return 0; +} + +sub get_curious_tree { + my $member = shift; + my $fraction = is_fraction_string $member; + + die qq{`get_curious_tree` expects a string (i.e.: "3/5"), got $member\n} + unless $fraction; + + my @parents; + my $child = $fraction; + + while ($child) { + push @parents, $child; + $child = get_curious_parent $child; + } + + return \@parents; +} + +sub get_curious_generations { + my @tree = @{ +shift }; + my $generations = shift // 2; + + if ( scalar @tree == 2 ) { + return [ $tree[1] ]; + } + + my @slice = @tree[ 1 .. $generations ]; + + return \@slice; +} + +################################################################################ +# Utilities #################################################################### +################################################################################ + +sub color { + my $color = shift; + my $str = shift // q{}; + my $reset = "\e[0m"; + my %colors = ( + green => "\e[32m", + none => q{}, + red => "\e[31m", + yellow => "\e[33m", + ); + return $colors{$color} . $str . $reset; +} + +sub format_results { + my @tree = @{ +shift }; + my $length = @tree; + my $results = q{}; + + for my $idx ( 0 .. $#tree ) { + my $relation = $idx == 0 ? 'parent' : 'grandparent'; + my $great = $idx > 1 ? 'great-' x ( $idx - 1 ) : q{}; + my $ordinal = color 'yellow', qq{$great$relation}; + my $member = color 'green', $tree[$idx]; + my $separator = + $idx == 0 ? q{} : $length <= 2 || $idx == $length - 2 ? ' and ' : ', '; + $results = $results . $separator . "$ordinal = $member"; + } + return $results; +} + +sub assert_root { + my @tree = @{ +shift }; + my $last_elem = $tree[-1]; + + if ( $last_elem ne '1/1' ) { + my $beginning = color 'yellow', 'Curious fraction tree rooted at '; + my $root = color 'red', $last_elem; + my $middle = color 'yellow', ' and not at '; + my $end = color 'green', '1/1'; + return $beginning . $root . $middle . $end; + } + return 0; +} + +sub repl { + my $prompt = + 'Enter a fraction (i.e.: "' + . color( 'green', '3/5' ) + . '") or type "' + . color( 'yellow', 'exit' ) + . '" to quit /> '; + my $continue_prompt = + 'Enter "' + . color( 'yellow', 'more' ) + . '" to see more details, or enter a fraction (i.e.: "' + . color( 'green', '3/5' ) + . '") to continue /> '; + my $current_tree; + my $generations; + my $assert_root; + + print $prompt; + + while ( my $line = <> ) { + chomp $line; + + $line =~ s/ \A \s+ | \s+ \z //gx; + + if ( $line eq 'exit' || $line eq 'quit' || $line eq 'q' ) { + print color( 'yellow', 'Goodbye.' ), "\n"; + return 0; + } + + if ( $current_tree && $line eq 'more' ) { + my @tree = @{$current_tree}; + my $slice = [ @tree[ 1 .. $#tree ] ]; + print format_results($slice), "\n"; + + if ($assert_root) { + print $assert_root, "\n"; + } + + $current_tree = undef; + $generations = undef; + $assert_root = undef; + + print $prompt; + next; + } + + my $fraction = is_fraction_string $line; + + if ($fraction) { + if ( $fraction eq '1/1' ) { + my $message = color( 'green', '1/1' ) . " is root.\n"; + print $message; + print $prompt; + next; + } + + $current_tree = get_curious_tree $fraction; + $generations = get_curious_generations $current_tree; + $assert_root = assert_root $current_tree; + print format_results($generations), "\n"; + print $continue_prompt; + next; + } + + print "Sorry, I don't understand $line\n"; + print $prompt; + } + return 0; +} + +sub print_banner { + my $message = 'A Curious Fracion Tree'; + my $underline = q{=} x length $message; + + return print color( 'yellow', $message . "\n" . $underline . "\n" ); +} + +################################################################################ +# Main ######################################################################### +################################################################################ + +print_banner(); +repl(); diff --git a/challenge-146/iangoodnight/python/ch-1.py b/challenge-146/iangoodnight/python/ch-1.py new file mode 100755 index 0000000000..840d58770f --- /dev/null +++ b/challenge-146/iangoodnight/python/ch-1.py @@ -0,0 +1,77 @@ +#!/usr/bin/python3 +# ch-1.py + +# > https://theweeklychallenge.org/blog/perl-weekly-challenge-146/ +# +# ## Task 1 > 10001st Prime Number +# ================================ +# +# Write a script to generate the 10001st prime number. + +import math +import sys + +############################################################################### +# PWC Solution ################################################################ +############################################################################### + + +def get_prime(nth): + primes = [2, 3] + cursor = 5 + while (len(primes) < nth): + is_prime = True + for prime in primes: + if prime > math.sqrt(cursor): + break + if cursor % prime == 0: + is_prime = False + break + if is_prime: + primes.append(cursor) + cursor += 2 + return primes.pop() + + +############################################################################### +# Utilities ################################################################### +############################################################################### + + +def get_suffix(num): + last_d = num % 10 + if last_d == 0 or last_d >= 4: + return 'th' + if last_d == 1: + return 'st'