From ea006adb9d66e2b866a61e37f35971a04f2714c6 Mon Sep 17 00:00:00 2001 From: Walt Mankowski Date: Fri, 15 Jul 2022 19:37:23 -0400 Subject: perl solution to challenge 1 --- challenge-173/walt-mankowski/perl/ch-1.pl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 challenge-173/walt-mankowski/perl/ch-1.pl diff --git a/challenge-173/walt-mankowski/perl/ch-1.pl b/challenge-173/walt-mankowski/perl/ch-1.pl new file mode 100644 index 0000000000..4f5a49952f --- /dev/null +++ b/challenge-173/walt-mankowski/perl/ch-1.pl @@ -0,0 +1,27 @@ +#!/usr/bin/env perl +use v5.36; + +# Task 1: Esthetic Number +# +# You are given a positive integer, $n. +# +# Write a script to find out if the given number is Esthetic Number. +# +# An esthetic number is a positive integer where every adjacent +# digit differs from its neighbour by 1. +# +# For example, +# +# 5456 is an esthetic number as |5 - 4| = |4 - 5| = |5 - 6| = 1 +# 120 is not an esthetic number as |1 - 2| != |2 - 0| != 1 + +sub is_esthetic($n) { + my @d = split //, $n; + for my $i (1..$#d) { + return 0 unless abs($d[$i-1] - $d[$i]) == 1; + } + return 1; +} + +my $n = @ARGV[0]; +printf "%d is%s an esthetic number\n", $n, is_esthetic($n) ? "" : " not"; -- cgit From af43b5a7055ee66b0fdc3589be8ba18134733a43 Mon Sep 17 00:00:00 2001 From: Walt Mankowski Date: Fri, 15 Jul 2022 19:57:28 -0400 Subject: perl solution to challenge 2 --- challenge-173/walt-mankowski/perl/ch-2.pl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 challenge-173/walt-mankowski/perl/ch-2.pl diff --git a/challenge-173/walt-mankowski/perl/ch-2.pl b/challenge-173/walt-mankowski/perl/ch-2.pl new file mode 100644 index 0000000000..20be9326f8 --- /dev/null +++ b/challenge-173/walt-mankowski/perl/ch-2.pl @@ -0,0 +1,17 @@ +#!/usr/bin/env perl +use v5.36; +use bigint; +use List::Util qw(product); + +# Task 2: Sylvester’s sequence +# Submitted by: Mohammad S Anwar +# +# Write a script to generate first 10 members of Sylvester's sequence. +# In number theory, Sylvester's sequence is an integer sequence in +# which each term of the sequence is the product of the previous +# terms, plus one. + +my @sylvester; +push @sylvester, 1 + product @sylvester while @sylvester < 10; +say for @sylvester; + -- cgit From c04831d7a245601dae441b8cd2993e1cc8c999cb Mon Sep 17 00:00:00 2001 From: Walt Mankowski Date: Fri, 15 Jul 2022 21:11:10 -0400 Subject: updated README for challenge 173 --- challenge-173/walt-mankowski/README.md | 112 ++++++--------------------------- 1 file changed, 20 insertions(+), 92 deletions(-) diff --git a/challenge-173/walt-mankowski/README.md b/challenge-173/walt-mankowski/README.md index ff4444732e..7a5af58509 100644 --- a/challenge-173/walt-mankowski/README.md +++ b/challenge-173/walt-mankowski/README.md @@ -1,106 +1,34 @@ Solutions by Walt Mankowski. -# Task #1: Prime Partition +# Perl Weekly Challenge #173: Esthetic Numbers and Sylvester's Sequence -For this task we're given 2 positive integers _m_ and _n_, and we need to find _n_ unique prime numbers that add up to _m_. +## Task #1: Esthetic Numbers -To solve this I made use of the `primes_to()` function I wrote for Challenge 169. I also used `Algorithm::Combinatorics` to find combinations of primes taking _n_ at time, and `sum()` from `List::Utils` to find the sum. Using those 3 functions this challenge was easy to solve: +For this task we're given a number _n_ and need to determine if it's an Esthetic Number. An **Esthetic Number** is a positive integer where every pair of adjacent digits differ in value by exactly 1. -```perl -$, = " "; -my ($m, $n) = @ARGV; -my $primes = primes_to($m); -my $iter = combinations($primes, $n); -while (my $p = $iter->next) { - say $p->@* if sum($p->@*) == $m; -} -``` - -I also wrote a version in Python. First I needed to port `primes_to()` to Python: - -```python -# find the primes up to n using the sieve of Eratosthenes and return -# them as a list -def primes_to(n): - is_prime = [True] * (n+1) - is_prime[0] = is_prime[1] = False - for i in range(2, int(sqrt(n))+1): - if is_prime[i]: - for j in range(i+i, n+1, i): - is_prime[j] = False - - return [i for i,val in enumerate(is_prime) if val] -``` - -Then the actual code to solve the challenge ended up looking very similar to the Perl version: - -```python -import sys -from itertools import combinations -from primes import primes_to - -m, n = [int(x) for x in sys.argv[1:]] -primes = primes_to(m) - -for comb in combinations(primes, n): - if sum(comb) == m: - print(comb) -``` - -# Task 2: Five-number Summary - -For this task we're given a list of numbers and need to compute their (Five-number Summary)[https://en.wikipedia.org/wiki/Five-number_summary], which consists of - -1. The minimum value -2. The lower quartile -3. The median -4. The upper quartile -5. The maximum value - -To solve this I first sorted the list. The minimum and maximum values are just the first and last element of the sorted list. Then I wrote a function to compute the median of a sorted list. - -```perl -sub median_sorted(@a) { - my $len2 = int(@a / 2); - return @a % 2 == 1 ? $a[$len2] : ($a[$len2-1] + $a[$len2]) / 2; -} -``` -Once we have that, then the lower quartile is the median of the values before the median in the sorted list, and the upper quartile is the median of the values after the median. +The only real trick to solve this in Perl is that we can turn a number `$n` into an array of digits `@d` with the statement `@d = split //, $n;`. Then we can wrap that in a function that checks the absolute value of each pair of points: ```perl -sub fivenum(@a) { - my @sorted = sort {$a <=> $b} @a; - my $min = $sorted[0]; - my $max = $sorted[-1]; - my $median = median_sorted(@sorted); - - my $len2 = int(@sorted / 2); - my $lower = median_sorted(@sorted[0..$len2-1]); - my $upper; - if (@sorted % 2 == 1) { # odd number of elements - $upper = median_sorted(@sorted[$len2+1..$#sorted]); - } else { - $upper = median_sorted(@sorted[$len2..$#sorted]); +sub is_esthetic($n) { + my @d = split //, $n; + for my $i (1..$#d) { + return 0 unless abs($d[$i-1] - $d[$i]) == 1; } - return ($min, $lower, $median, $upper, $max); + return 1; } ``` -`fivenum()` was a little tricky to port to Python. First, `sorted`, `min`, and `max` are all reserved words to Python, so I had to come up with different names for them. I decided to just prefix all the variable names with an underscore. I also had to be careful because the upper range of slices is inclusive in Perl but exclusive in Python. Here's my version: +## Task 2: Sylvester's Sequence -```python -def fivenum(a): - _sorted = sorted(a) - _min = _sorted[0] - _max = _sorted[-1] - _median = median_sorted(_sorted) +For this task we need to generate the first 10 terms of (Sylvester's Sequence)[https://en.wikipedia.org/wiki/Sylvester%27s_sequence]. **Sylvester's Sequence** is an integer sequence where every term is the product of all the previous terms, plus one. - len2 = len(a) // 2 - _lower = median_sorted(_sorted[0:len2]) - if len(a) % 2 == 1: # odd number of elements - _upper = median_sorted(_sorted[len2+1:]) - else: - _upper = median_sorted(_sorted[len2:]) +Terms in Sylvester's Sequence get very large very fast (the 10th term has 20 digits) so we need to use the `bigint` module. I also used the `prod` function from `List::Util` to do the multiplication. With those modules in hand, we can solve this challenge in just a few lines of code: - return _min, _lower, _median, _upper, _max -``` +```perl +use bigint; +use List::Util qw(product); + +my @sylvester; +push @sylvester, 1 + product @sylvester while @sylvester < 10; +say for @sylvester; +``` \ No newline at end of file -- cgit From 4e2d62b030546c9c04c8b9f355adff3cc0182d09 Mon Sep 17 00:00:00 2001 From: Walt Mankowski Date: Fri, 15 Jul 2022 21:17:16 -0400 Subject: fixed link syntax --- challenge-173/walt-mankowski/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/challenge-173/walt-mankowski/README.md b/challenge-173/walt-mankowski/README.md index 7a5af58509..b9e53c1a92 100644 --- a/challenge-173/walt-mankowski/README.md +++ b/challenge-173/walt-mankowski/README.md @@ -20,7 +20,7 @@ sub is_esthetic($n) { ## Task 2: Sylvester's Sequence -For this task we need to generate the first 10 terms of (Sylvester's Sequence)[https://en.wikipedia.org/wiki/Sylvester%27s_sequence]. **Sylvester's Sequence** is an integer sequence where every term is the product of all the previous terms, plus one. +For this task we need to generate the first 10 terms of [Sylvester's Sequence](https://en.wikipedia.org/wiki/Sylvester%27s_sequence). **Sylvester's Sequence** is an integer sequence where every term is the product of all the previous terms, plus one. Terms in Sylvester's Sequence get very large very fast (the 10th term has 20 digits) so we need to use the `bigint` module. I also used the `prod` function from `List::Util` to do the multiplication. With those modules in hand, we can solve this challenge in just a few lines of code: @@ -31,4 +31,4 @@ use List::Util qw(product); my @sylvester; push @sylvester, 1 + product @sylvester while @sylvester < 10; say for @sylvester; -``` \ No newline at end of file +``` -- cgit