diff options
| author | dcw <d.white@imperial.ac.uk> | 2021-10-17 22:57:12 +0100 |
|---|---|---|
| committer | dcw <d.white@imperial.ac.uk> | 2021-10-17 22:57:12 +0100 |
| commit | e66cf656367950f8484bd2a1545d09917c9b4b96 (patch) | |
| tree | 14c61c1da02458318c35ea2bca317e60ee5674a2 | |
| parent | 78cc5db60b6a54cd365b67b17013b72db7ed4268 (diff) | |
| download | perlweeklychallenge-club-e66cf656367950f8484bd2a1545d09917c9b4b96.tar.gz perlweeklychallenge-club-e66cf656367950f8484bd2a1545d09917c9b4b96.tar.bz2 perlweeklychallenge-club-e66cf656367950f8484bd2a1545d09917c9b4b96.zip | |
imported my solutions to this week's tasks
| -rw-r--r-- | challenge-134/duncan-c-white/README | 62 | ||||
| -rwxr-xr-x | challenge-134/duncan-c-white/perl/ch-1.pl | 69 | ||||
| -rwxr-xr-x | challenge-134/duncan-c-white/perl/ch-2.pl | 102 |
3 files changed, 206 insertions, 27 deletions
diff --git a/challenge-134/duncan-c-white/README b/challenge-134/duncan-c-white/README index 7c8d08653f..83854546f8 100644 --- a/challenge-134/duncan-c-white/README +++ b/challenge-134/duncan-c-white/README @@ -1,44 +1,52 @@ -TASK #1 - Integer Square Root +TASK #1 - Pandigital Numbers -You are given a positive integer $N. +Write a script to generate first 5 Pandigital Numbers in base 10. -Write a script to calculate the integer square root of the given number. +As per the wikipedia, it says: -Please avoid using a built-in function. Find out more about it: +A pandigital number is an integer that in a given base has among its +significant digits each digit used in the base at least once. +The smallest base 10 pandigital number is 1023456789, and subsequent +ones are lexicographic permutations, ie. 1023456798, 1023456879... -https://en.wikipedia.org/wiki/Integer_square_root +MY NOTES: Basically just needs a standard lexicographic permutation algorithm, +with the initial value to permute being 1023456789. -Examples +TASK #2 - Distinct Terms Count - Input: $N = 10 - Output: 3 +You are given 2 positive numbers, $m and $n. - Input: $N = 27 - Output: 5 +Write a script to generate multiplication table and display count of distinct terms. - Input: $N = 85 - Output: 9 +Example 1 - Input: $N = 101 - Output: 10 +Input: $m = 3, $n = 3 +Output: -MY NOTES: Pretty easy as the Wikipedia page shows a C implementation + x | 1 2 3 + --+------ + 1 | 1 2 3 + 2 | 2 4 6 + 3 | 3 6 9 +Distinct Terms: 1, 2, 3, 4, 6, 9 +Count: 6 -TASK #2 - Smith Numbers +Example 2 -Write a script to generate first 10 Smith Numbers in base 10. +Input: $m = 3, $n = 5 +Output: -According to Wikipedia: + x | 1 2 3 4 5 + --+-------------- + 1 | 1 2 3 4 5 + 2 | 2 4 6 8 10 + 3 | 3 6 9 12 15 -"In number theory, a Smith number is a composite number for which, in -a given number base, the sum of its digits is equal to the sum of the -digits in its prime factorization in the given number base." +Distinct Terms: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15 +Count: 11 -MY NOTES: Ok, an example in the Wikipedia clarifies this: - 4937775 = 3**1 5**2 658371 (prime factors) - 4 + 9 + 3 + 7 + 7 + 7 + 5 = 42 - 3 x· 1 + 5x 2 + (6 + 5 + 8 + 3 + 7) x 1 = 42 too - -Should be quite straightforward. +MY NOTES: Pretty easy, the distinct terms just need a set (hash) as usual. +The tricky bit is the pretty layout of the multiplication table, especially +getting the correct column widths.. diff --git a/challenge-134/duncan-c-white/perl/ch-1.pl b/challenge-134/duncan-c-white/perl/ch-1.pl new file mode 100755 index 0000000000..30f2d76e2d --- /dev/null +++ b/challenge-134/duncan-c-white/perl/ch-1.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl +# +# TASK #1 - Pandigital Numbers +# +# Write a script to generate first 5 Pandigital Numbers in base 10. +# +# As per the wikipedia, it says: +# +# A pandigital number is an integer that in a given base has among its +# significant digits each digit used in the base at least once. +# The smallest base 10 pandigital number is 1023456789, and subsequent +# ones are lexicographic permutations, ie. 1023456798, 1023456879... +# +# MY NOTES: Basically just needs a standard lexicographic permutation algorithm, +# with the initial value to permute being 1023456789. +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +use Function::Parameters; +#use Data::Dumper; + +# +# my $next = next_perm( $val ); +# Find and return the next permutation in lexicographic order +# of $val. Return undef is $val is the last permutation (in order). +# Algorithm treats $val as an array of digits a[n]: +# 1. Find the largest index k such that a[k] < a[k + 1]. If no such index exists, +# the permutation is the last permutation. +# 2. Find the largest index l greater than k such that a[k] < a[l]. +# 3. Swap the value of a[k] with that of a[l]. +# 4. Reverse the sequence from a[k + 1] up to and including the final element a[n]. +# +fun next_perm( $val ) +{ + my @a = split( //, $val ); + my( $k, $l ); + my $n = @a-1; + for( $k=$n-1; $k>=0 && $a[$k]>=$a[$k+1]; $k-- ) + { + } + return undef if $k<0; + for( $l=$n; $l>$k && $a[$k]>=$a[$l]; $l-- ) + { + } + ( $a[$k], $a[$l] ) = ( $a[$l], $a[$k] ); + + # reverse a[k+1]..a[n] + @a[$k+1..$n] = reverse @a[$k+1..$n]; + + return join( '', @a ); +} + + +my $debug=0; +die "Usage: first-N-base-10-pandigital-numbers [N, default 5]\n" unless + GetOptions( "debug"=>\$debug ) && @ARGV<2; +my $firstn = @ARGV == 1 ? shift @ARGV : 5; + +my $pandigital = "1023456789"; + +for( my $i=1; $i<=$firstn; $i++ ) +{ + die "fallen off last perm\n" unless defined $pandigital; + say $pandigital; + $pandigital = next_perm( $pandigital ); +} diff --git a/challenge-134/duncan-c-white/perl/ch-2.pl b/challenge-134/duncan-c-white/perl/ch-2.pl new file mode 100755 index 0000000000..db5613df26 --- /dev/null +++ b/challenge-134/duncan-c-white/perl/ch-2.pl @@ -0,0 +1,102 @@ +#!/usr/bin/perl +# +# TASK #2 - Distinct Terms Count +# +# You are given 2 positive numbers, $m and $n. +# +# Write a script to generate multiplication table and display count of distinct terms. +# +# Example 1 +# +# Input: $m = 3, $n = 3 +# Output: +# +# x | 1 2 3 +# --+------ +# 1 | 1 2 3 +# 2 | 2 4 6 +# 3 | 3 6 9 +# +# Distinct Terms: 1, 2, 3, 4, 6, 9 +# Count: 6 +# +# Example 2 +# +# Input: $m = 3, $n = 5 +# Output: +# +# x | 1 2 3 4 5 +# --+-------------- +# 1 | 1 2 3 4 5 +# 2 | 2 4 6 8 10 +# 3 | 3 6 9 12 15 +# +# Distinct Terms: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15 +# Count: 11 +# +# MY NOTES: Pretty easy, the distinct terms just need a set (hash) as usual. +# The tricky bit is the pretty layout of the multiplication table, especially +# getting the correct column widths.. +# + +use strict; +use warnings; +use feature 'say'; +use Function::Parameters; +use Getopt::Long; +use Data::Dumper; + +my $debug = 0; + +die "Usage: distinct-terms-count [-d|--debug] M N\n" + unless GetOptions( "debug"=>\$debug ) && @ARGV==2; +my( $m, $n ) = @ARGV; +my $table = form_table( $m, $n ); +say $table; + +# Build the distinct values.. messy to do this while formatting the table.. +my %distinct; +for( my $i=1; $i<=$m; $i++ ) +{ + for( my $j=1; $j<=$n; $j++ ) + { + $distinct{$i*$j}++; + } +} +my @distinct = sort { $a <=> $b } keys %distinct; +my $count = @distinct; + +say "Distinct Terms: ". join(', ', @distinct); +say "Count: $count"; + + +# +# my $table = form_table( $m, $n ); +# Form a neatly formatted times table for $m rows x $n columns, +# and return the single $m+2 line string. +# +fun form_table( $m, $n ) +{ + my $width = 1 + int( log($n*$m)/log(10) ); + my $firstw = 1 + int(log($m)/log(10)); + + my @result; + + my $row = sprintf("%${firstw}s", "x") . " | "; + $row .= sprintf("%${firstw}d ", 1 ); + $row .= sprintf("%${width}d ", $_ ) for 2..$n; + push @result, $row; + + $row = '-'x($firstw+1)."+".('-'x($firstw+$width*($n-1)+$n)); + push @result, $row; + + for( my $i=1; $i<=$m; $i++ ) + { + $row = sprintf("%${firstw}d", $i). " | "; + $row .= sprintf("%${firstw}d ", $i ); + $row .= sprintf("%${width}d ", $i*$_ ) for 2..$n; + push @result, $row; + } + + return join("\n", @result); +} |
