diff options
| author | dcw <d.white@imperial.ac.uk> | 2021-05-16 23:19:25 +0100 |
|---|---|---|
| committer | dcw <d.white@imperial.ac.uk> | 2021-05-16 23:19:25 +0100 |
| commit | 67186f7e0c0533fc5e529481223ec4339bd4bd0b (patch) | |
| tree | ce3894508f2bef77c7644b91df70cee736b7c68b | |
| parent | 06834eb68e5143e7cfae8cf6626b66a74191394f (diff) | |
| download | perlweeklychallenge-club-67186f7e0c0533fc5e529481223ec4339bd4bd0b.tar.gz perlweeklychallenge-club-67186f7e0c0533fc5e529481223ec4339bd4bd0b.tar.bz2 perlweeklychallenge-club-67186f7e0c0533fc5e529481223ec4339bd4bd0b.zip | |
imported my solutions to this week's tasks
| -rw-r--r-- | challenge-112/duncan-c-white/README | 72 | ||||
| -rwxr-xr-x | challenge-112/duncan-c-white/perl/ch-1.pl | 80 | ||||
| -rwxr-xr-x | challenge-112/duncan-c-white/perl/ch-2.pl | 79 |
3 files changed, 207 insertions, 24 deletions
diff --git a/challenge-112/duncan-c-white/README b/challenge-112/duncan-c-white/README index 65a6d1e549..0efdd3eeaa 100644 --- a/challenge-112/duncan-c-white/README +++ b/challenge-112/duncan-c-white/README @@ -1,39 +1,63 @@ -Task 1: "Search Matrix +Task 1: "Canonical Path -You are given 5x5 matrix filled with integers such that each row is -sorted from left to right and the first integer of each row is greater -than the last integer of the previous row. +You are given a string path, starting with a slash '/'. -Write a script to find a given integer in the matrix using an efficient search algorithm. +Write a script to convert the given absolute path to the simplified canonical path. + +In a Unix-style file system: + +- A period '.' refers to the current directory +- A double period '..' refers to the directory up a level +- Multiple consecutive slashes ('//') are treated as a single slash '/' + +The canonical path format: + +- The path starts with a single slash '/'. +- Any two directories are separated by a single slash '/'. +- The path does not end with a trailing '/'. +- The path only contains the directories on the path from the root + directory to the target file or directory Example - Matrix: [ 1, 2, 3, 5, 7 ] - [ 9, 11, 15, 19, 20 ] - [ 23, 24, 25, 29, 31 ] - [ 32, 33, 39, 40, 42 ] - [ 45, 47, 48, 49, 50 ] +Input: "/a/" +Output: "/a" - Input: 35 - Output: 0 since it is missing in the matrix +Input: "/a/b//c/" +Output: "/a/b/c" - Input: 39 - Output: 1 as it exists in the matrix +Input: "/a/b/c/../.." +Output: "/a" " -My notes: could flatten onto a 1D array and binary search. Other -methods? Find which row it's in (if any) and then grep? Did that. -Not a very nice method (not even sure it works:-)) +My notes: ok, I like this. Pretty straightforward, but a nice practical problem. + + +Task 2: "Climb Stairs + +You are given $n steps to climb + +Write a script to find out the distinct ways to climb to the top. You +are allowed to climb either 1 or 2 steps at a time. + +Example +Input: $n = 3 +Output: 3 -Task 2: "Ordered Letters + Option 1: 1 step + 1 step + 1 step + Option 2: 1 step + 2 steps + Option 3: 2 steps + 1 step -Given a word, you can sort its letters alphabetically (case -insensitive). For example, "beekeeper" becomes "beeeeekpr" and -"dictionary" becomes "acdiinorty". +Input: $n = 4 +Output: 5 -Write a script to find the longest English words that don't change when -their letters are sorted. + Option 1: 1 step + 1 step + 1 step + 1 step + Option 2: 1 step + 1 step + 2 steps + Option 3: 2 steps + 1 step + 1 step + Option 4: 1 step + 2 steps + 1 step + Option 5: 2 steps + 2 steps " -My notes: nice! +My notes: looks pretty straightforward, although may not generate the options +in the same order. diff --git a/challenge-112/duncan-c-white/perl/ch-1.pl b/challenge-112/duncan-c-white/perl/ch-1.pl new file mode 100755 index 0000000000..e1158faac4 --- /dev/null +++ b/challenge-112/duncan-c-white/perl/ch-1.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl +# +# Task 1: "Canonical Path +# +# You are given a string path, starting with a slash '/'. +# +# Write a script to convert the given absolute path to the simplified canonical path. +# +# In a Unix-style file system: +# +# - A period '.' refers to the current directory +# - A double period '..' refers to the directory up a level +# - Multiple consecutive slashes ('//') are treated as a single slash '/' +# +# The canonical path format: +# +# - The path starts with a single slash '/'. +# - Any two directories are separated by a single slash '/'. +# - The path does not end with a trailing '/'. +# - The path only contains the directories on the path from the root +# directory to the target file or directory +# +# Example +# +# Input: "/a/" +# Output: "/a" +# +# Input: "/a/b//c/" +# Output: "/a/b/c" +# +# Input: "/a/b/c/../.." +# Output: "/a" +# " +# +# My notes: ok, I like this. Pretty straightforward, but a nice practical problem. +# + +use strict; +use warnings; +use feature 'say'; +use Function::Parameters; +#use Data::Dumper; + +# +# my $canon = canonical_path( $path ); +# Find the canonical version of $path, according +# to the rules above. +# +fun canonical_path( $path ) +{ + $path =~ s|//+|/|g; # turn //+ -> / + $path =~ s|^/||; # remove initial / + $path =~ s|/$||; # remove trailing / + + #die $path; + + my @p; + foreach my $x (split( m|/|, $path )) + { + if( $x eq '..' ) + { + pop @p; + } + elsif( $x ne '.' ) + { + push @p, $x; + } + } + + return '/'. join('/',@p); +} + + +die "Usage: canonical-path PATH\n" unless @ARGV==1; +my $path = shift; + +my $canon = canonical_path( $path ); + +say "Input: $path"; +say "Output: $canon"; diff --git a/challenge-112/duncan-c-white/perl/ch-2.pl b/challenge-112/duncan-c-white/perl/ch-2.pl new file mode 100755 index 0000000000..8e0719879d --- /dev/null +++ b/challenge-112/duncan-c-white/perl/ch-2.pl @@ -0,0 +1,79 @@ +#!/usr/bin/perl +# +# Task 2: "Climb Stairs +# +# You are given $n steps to climb +# +# Write a script to find out the distinct ways to climb to the top. You +# are allowed to climb either 1 or 2 steps at a time. +# +# Example +# +# Input: $n = 3 +# Output: 3 +# +# Option 1: 1 step + 1 step + 1 step +# Option 2: 1 step + 2 steps +# Option 3: 2 steps + 1 step +# +# Input: $n = 4 +# Output: 5 +# +# Option 1: 1 step + 1 step + 1 step + 1 step +# Option 2: 1 step + 1 step + 2 steps +# Option 3: 2 steps + 1 step + 1 step +# Option 4: 1 step + 2 steps + 1 step +# Option 5: 2 steps + 2 steps +# " +# +# My notes: looks pretty straightforward, although may not generate the options +# in the same order. +# + +use strict; +use warnings; +use feature 'say'; +use Function::Parameters; +use Text::CSV; +#use Data::Dumper; + +# +# my @ways = climb( $n ); +# Find and return all ways [each any array of 1|2] of climbing $n +# stairs, given that we can only climb 1 or 2 stairs per go. +# +fun climb( $n ) +{ + if( $n==1 ) + { + return ( [1] ); + } + if( $n==2 ) + { + return ( [1,1], [2] ); + } + my @ways; + foreach my $try (1..2) + { + my $left = $n-$try; + my @w = map { [ @$_, $try ] } climb( $left ); + push @ways, @w; + } + return @ways; +} + + + +die "Usage: climb-stairs N\n" unless @ARGV==1; +my $n = shift; + +my $x = my @ways = climb( $n ); +say "Input: $n"; +say "Output: $x"; +say ""; +my $opt = 1; +foreach my $way (@ways) +{ + say " Option $opt: ", join( ' + ', map { "$_ step".($_==1?"":"s") } @$way ); + $opt++; +} |
