diff options
| author | dcw <d.white@imperial.ac.uk> | 2020-05-31 23:37:25 +0100 |
|---|---|---|
| committer | dcw <d.white@imperial.ac.uk> | 2020-05-31 23:37:25 +0100 |
| commit | 0eb6027c2a76f991bef17d58d5476455ad4c50f5 (patch) | |
| tree | a4d6bb6266eb750cc25fa8dd6dd38795102c8a3b | |
| parent | 385eea00ce8b1f68c2f7c0d3e9cd3b39a76f50f5 (diff) | |
| download | perlweeklychallenge-club-0eb6027c2a76f991bef17d58d5476455ad4c50f5.tar.gz perlweeklychallenge-club-0eb6027c2a76f991bef17d58d5476455ad4c50f5.tar.bz2 perlweeklychallenge-club-0eb6027c2a76f991bef17d58d5476455ad4c50f5.zip | |
imported solution to first task, sorry no time to do second (and didn't much like the question anyway:-))
| -rw-r--r-- | challenge-062/duncan-c-white/README | 54 | ||||
| -rwxr-xr-x | challenge-062/duncan-c-white/perl/ch-1.pl | 118 |
2 files changed, 146 insertions, 26 deletions
diff --git a/challenge-062/duncan-c-white/README b/challenge-062/duncan-c-white/README index 0551c0a85d..736cbb1087 100644 --- a/challenge-062/duncan-c-white/README +++ b/challenge-062/duncan-c-white/README @@ -1,41 +1,43 @@ -Task 1: "Product SubArray +Task 1: "Sort Email Addresses -Given a list of 4 or more numbers, write a script to find the contiguous -sublist that has the maximum product. The length of the sublist is -irrelevant; your job is to maximize the product. +Write a script that takes a list of email addresses (one per line) and sorts them first by the domain part of the email address, and then by the part to the left of the @ (known as the mailbox). -Example - -Input: [ 2, 5, -1, 3 ] - -Output: [ 2, 5 ] which gives maximum product 10. -" +Note that the domain is case-insensitive, while the mailbox part is case sensitive. (Some email providers choose to ignore case, but that’s another matter entirely.) -My notes: very straightforward. +If your script is invoked with arguments, it should treat them as file names and read them in order, otherwise your script should read email addresses from standard input. +Bonus +Add a -u option which only includes unique email addresses in the output, just like sort -u. +Example -Task 2: "IPv4 Partition +If given the following list: -You are given a string containing only digits (0..9). The string should -have between 4 and 12 digits. +name@example.org +rjt@cpan.org +Name@example.org +rjt@CPAN.org +user@alpha.example.org -Write a script to print every possible valid IPv4 address that can be -made by partitioning the input string. +Your script (without -u) would return: -For the purpose of this challenge, a valid IPv4 address consists of four -'octets' i.e. A, B, C and D, separated by dots (.). +user@alpha.example.org +rjt@cpan.org +rjt@CPAN.org +Name@example.org +name@example.org -Each octet must be between 0 and 255, and must not have any leading -zeroes. (e.g., 0 is OK, but 01 is not.) +With -u, the script would return: -Example +user@alpha.example.org +rjt@CPAN.org +Name@example.org +name@example.org +" -Input: 25525511135, +My notes: cool question. Will have a go! -Output: -255.255.11.135 -255.255.111.35 +Task 2: "N Queens - in 3D.. " -My notes: sounds quite straightforward, nice problem. +My notes: sorry, I'm rather busy, sounds like a horrible problem, not doing it. diff --git a/challenge-062/duncan-c-white/perl/ch-1.pl b/challenge-062/duncan-c-white/perl/ch-1.pl new file mode 100755 index 0000000000..031d7a9386 --- /dev/null +++ b/challenge-062/duncan-c-white/perl/ch-1.pl @@ -0,0 +1,118 @@ +#!/usr/bin/perl +# +# Task 1: "Sort Email Addresses +# +# Write a script that takes a list of email addresses (one per line) +# and sorts them first by the domain part of the email address, and then +# by the part to the left of the @ (known as the mailbox). +# +# Note that the domain is case-insensitive, while the mailbox part is case +# sensitive. (Some email providers choose to ignore case, but that's +# another matter entirely.) +# +# If your script is invoked with arguments, it should treat them as file +# names and read them in order, otherwise your script should read email +# addresses from standard input. +# +# Bonus +# +# Add a -u option which only includes unique email addresses in the output, +# just like sort -u. +# +# Example +# +# If given the following list: +# +# name@example.org +# rjt@cpan.org +# Name@example.org +# rjt@CPAN.org +# user@alpha.example.org +# +# Your script (without -u) would return: +# +# user@alpha.example.org +# rjt@cpan.org +# rjt@CPAN.org +# Name@example.org +# name@example.org +# +# With -u, the script would return: +# +# user@alpha.example.org +# rjt@CPAN.org +# Name@example.org +# name@example.org +# " +# +# My notes: cool question. Will have a go! I also added '-i' meaning: +# treat the mailname part as case-insensitive as well. Running this +# script on the above input with -i and -u outputs only: +# +# user@alpha.example.org +# rjt@CPAN.org +# name@example.org +# + +use strict; +use warnings; +use feature 'say'; +use Function::Parameters; +use Getopt::Long; + +my $unique = 0; +my $caseinsensitive = 0; +my $result = GetOptions( "u" => \$unique, "i" => \$caseinsensitive ); + +die "Usage: sort-email-addresses [-u] [-i] (addresses on input)\n" + unless $result; + +my @addr; +while( <> ) +{ + chomp; + s/\s+//g; + die "bad input $_\n" unless /@/; + push @addr, $_; +} + +sub compare +{ + my( $aname, $adom ) = split( /@/, $a, 2 ); + my( $bname, $bdom ) = split( /@/, $b, 2 ); + + # compare domains first, case insensitively + $adom = lc($adom); + $bdom = lc($bdom); + return $adom cmp $bdom if $adom ne $bdom; + + # now compare names, case insensitively if $caseinsensitive + if( $caseinsensitive ) + { + $aname = lc($aname); + $bname = lc($bname); + } + return $aname cmp $bname; +} + +# +# my $out = sanitize( $in ); +# Sanitize the email address $in, giving $out. +# Sanitizing means: +# - lowercasing every domain, because domains are case insensitive +# - lowercasing every name IF $caseinsensitive +# +fun sanitize( $in ) +{ + my( $name, $dom ) = split( /@/, $in, 2 ); + $dom = lc($dom); + $name = lc($name) if $caseinsensitive; + return $name.'@'.$dom; +} + + +my %seen; +@addr = grep { ! $seen{sanitize($_)}++ } @addr if $unique; +@addr = sort compare @addr; + +say for @addr; |
