aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordcw <d.white@imperial.ac.uk>2021-05-16 23:19:25 +0100
committerdcw <d.white@imperial.ac.uk>2021-05-16 23:19:25 +0100
commit67186f7e0c0533fc5e529481223ec4339bd4bd0b (patch)
treece3894508f2bef77c7644b91df70cee736b7c68b
parent06834eb68e5143e7cfae8cf6626b66a74191394f (diff)
downloadperlweeklychallenge-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/README72
-rwxr-xr-xchallenge-112/duncan-c-white/perl/ch-1.pl80
-rwxr-xr-xchallenge-112/duncan-c-white/perl/ch-2.pl79
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++;
+}