aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsaiftynet <saiftynet@gmail.com>2020-05-31 23:00:17 +0100
committersaiftynet <saiftynet@gmail.com>2020-05-31 23:00:17 +0100
commitbceb7f7f17cf67f04b3b60c202f226a9d05750a9 (patch)
treec99d0cac0c94d2ccdf3005311b5780feb2ade7e3
parent2ea63cdf5aa1fd7b2062998a71a75a56711ef5f3 (diff)
downloadperlweeklychallenge-club-bceb7f7f17cf67f04b3b60c202f226a9d05750a9.tar.gz
perlweeklychallenge-club-bceb7f7f17cf67f04b3b60c202f226a9d05750a9.tar.bz2
perlweeklychallenge-club-bceb7f7f17cf67f04b3b60c202f226a9d05750a9.zip
Challenge-062 solutions by saiftynet
-rw-r--r--challenge-062/saiftynet/perl/ch-1.pl100
-rw-r--r--challenge-062/saiftynet/perl/ch-2.pl114
2 files changed, 214 insertions, 0 deletions
diff --git a/challenge-062/saiftynet/perl/ch-1.pl b/challenge-062/saiftynet/perl/ch-1.pl
new file mode 100644
index 0000000000..6c43b59202
--- /dev/null
+++ b/challenge-062/saiftynet/perl/ch-1.pl
@@ -0,0 +1,100 @@
+#!/usr/env/perl
+# Task 1 Challenge 062 Solution by saiftynet
+# › Sort Email AddressesSubmitted by: Neil BowersReviewed by: Ryan
+# ThompsonWrite 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&rsquo;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.
+# BonusAdd a -u option which only includes unique email addresses
+# in the output, just like sort -u.
+
+
+# this iextended to provide a couple of other options
+# including saving output to file and chhoding another separator and
+# also allowing for case insensitive user portion of the email
+
+use strict;use warnings;
+use 5.10.0;
+my @list=();
+my %option=(
+ unique=>0,
+ separator=>"\n",
+ caseInsensitive=>0,
+);
+
+# example input to demo if no input supplied
+my @plist=("name\@example.org","rjt\@cpan.org","Name\@example.org",
+ "rjt\@CPAN.org","user\@alpha.example.org","data","-U");
+# or use provided input
+@plist=@ARGV if @ARGV;
+
+while (@plist){
+ my $next=shift @plist;
+ if ($next=~/^(.+@[^@]+)$/){ # collect email-looking arguments
+ push @list, $next
+ }
+ # options -u unique as defined in task,
+ # -U username case insensitive
+ # -o output to file (follwed by filename
+ # -s choose a different separator
+ elsif ($next=~/^-[Uuos]$/){
+ if ($next=~/^-u$/) {$option{unique}=1}
+ elsif ($next=~/^-o$/) {$option{outputFile}=shift @plist}
+ elsif ($next=~/^-U$/) {$option{caseInsensitive}=1;$option{unique}=1}
+ elsif ($next=~/^-s$/) {$option{separator}=shift @plist}
+
+ }
+ # uses the __DATA__ segment for demo purposes if "data" is one of the parameters
+ elsif ($next=~/^data$/i){
+ while(<DATA>){
+ my @found=(m/([^\s"']+@[\w\.]+)/g);
+ push @list, @found;
+ }
+ }
+ elsif (-f $next){
+ open my $fh, "$next" or next;
+ while(<$fh>){
+ my @found=(m/([^\s"']+@[^\w\b]+)/g);
+ push @list, @found;
+ }
+ close $fh;
+ }
+}
+
+sortEmail();
+
+sub sortEmail{
+ my @splitList=map {m/^(.+)@([^@]+)$/;[$1,$2]} map{$option{caseInsensitive}?lc $_:$_} @list;
+ my @sorted=sort { lc ($$a[1]) cmp lc($$b[1])? lc $$a[1] cmp lc $$b[1]:$$a[0] cmp $$b[0] } @splitList;
+ my @filtered=();
+ if ($option{unique}){
+ foreach (0..$#sorted){
+ push @filtered,$sorted[$_] unless (${$sorted[$_]}[0] eq ${$sorted[$_-1]}[0]) and (lc ${$sorted[$_]}[1] eq lc ${$sorted[$_-1]}[1])
+ }
+ }
+ else {
+ @filtered=@sorted;
+ }
+
+ if ($option{outputFile}){
+ open (my $fh,">",$option{outputFile}) or die "unable to create outputFile $option{outputFile}:$!";
+ print $fh "$$_[0]\@$$_[1]$option{separator}" foreach @filtered;
+ close $fh;
+
+ }
+ else{
+ print "$$_[0]\@$$_[1]$option{separator}" foreach @filtered;
+ }
+}
+
+
+__DATA__
+fred@flintstone.com, wilma@flintstone.com lorem ipsum etc rubbish barney@rubble.org
+more rubbish BETTY@rubble.com
+;
diff --git a/challenge-062/saiftynet/perl/ch-2.pl b/challenge-062/saiftynet/perl/ch-2.pl
new file mode 100644
index 0000000000..eb8682ff1d
--- /dev/null
+++ b/challenge-062/saiftynet/perl/ch-2.pl
@@ -0,0 +1,114 @@
+#!/usr/env/perl
+# Task 2 Challenge 062 Solution by saiftynet
+# › N QueensSubmitted by: Ryan ThompsonA standard 8×8 chessboard
+# has 64 squares. The Queen is a chesspiece that can attack in 8
+# directions, as shown by the green shaded squares below:
+#
+# It is possible to place 8 queens on to a single chessboard such
+# that none of the queens can attack each other (i.e., their shaded
+# squares would not overlap). In fact, there are multiple ways to
+# do so, and this is a favourite undergraduate assignment in computer
+# science.
+# But here at PWC, we&rsquo;re going to take it into the next dimension!
+# Your job is to write a script to work with a three dimensional
+# chess cube, M×M×M in size, and find a solution that maximizes
+# the number of queens that can be placed in that cube without attacking
+# each other. Output one possible solution.
+
+
+# This was a Bugger.
+# Calculating all possibilities and then establishing the highest possible
+# number of queens was taking me too long and I gave up. Instead here
+# is a solution that produces a possible answer, without verifying that
+# it is indeed the highest possible number of queens in the 3D grid.
+
+
+use strict;use warnings;
+my $side=6; # number of squares per side
+my @grid;
+$grid[$side-1][$side-1][$side-1]=undef; # initialise 3d grid
+
+print "\n";
+
+tryAll();
+
+sub tryAll{
+ my $numberOfQueens=0;
+ foreach my $x (0..$side-1){
+ foreach my $y (0..$side-1){
+ foreach my $z (0..$side-1){
+ $numberOfQueens+= placeQueen($x,$y,$z);;
+ }
+ }
+ }
+ print "Number of queens in a $side x $side x $side grid is $numberOfQueens\n";
+ printGrid();
+
+}
+
+# places a queen aa given 3d position if not occupied
+# puts a "." in all places that the queen may strike at
+sub placeQueen{
+ my ($x,$y,$z)=@_;
+ ($x,$y,$z) = @$x if (ref $x eq "ARRAY");
+ return 0 if $grid[$x][$y][$z]; # if occupied or targetted return fail
+ $grid[$x][$y][$z]="Q";
+
+ # in each of the possible directions
+ foreach my $deltaX(-1..1){
+ foreach my $deltaY(-1..1){
+ foreach my $deltaZ(-1..1){
+ next unless $deltaX or $deltaY or $deltaZ; # ignore "all zero" direction.
+ foreach my $distance (1..$side-1){ # for distances in that direction
+ my ($testX,$testY,$testZ)=($x+$distance*$deltaX,
+ $y+$distance*$deltaY,
+ $z+$distance*$deltaZ);
+ last if outOfBounds($testX,$testY,$testZ); # ignore if out of bounds
+ # place a dot at targetted squares
+ $grid[$testX][$testY][$testZ]="." unless $grid[$testX][$testY][$testZ];
+ }
+ }
+ }
+ }
+ return 1; # successfuly placed a queen
+
+ sub outOfBounds{ # test for bounds
+ my ($x,$y,$z)=@_;
+ return 1 if $x < 0 or $y < 0 or $z < 0 or
+ $x >= $side or $y >= $side or $z >= $side;
+ return 0;
+ }
+}
+
+# prints a 3d ish grid;
+# for sides larger than 5 the grid is printed vwith vertical pages
+# for less than 5 the pages are displayed horizontally
+sub printGrid{
+ if ($side<=5){
+ print "",(("_"x($side*2)).(" "x4))x$side,"\n";
+ foreach my $x (0..$side-1){
+ print " "x$x;
+ foreach my $y (0..$side-1){
+ foreach my $z (0..$side-1){
+ print "\\",($grid[$x][$y][$z]//".");
+ }
+ print "\\"," "x3;
+ }
+ print "\n";
+ }
+ print " "x$side,(("-"x($side*2)).(" "x4))x$side,"\n";
+ }
+ else{
+ foreach my $x (0..$side-1){
+ foreach my $y (0..$side-1){
+ print " "x$y;
+ foreach my $z (0..$side-1){
+ print "\\",($grid[$x][$y][$z]//".");
+ }
+ print "\\\n";
+ }
+ print "\n";
+ }
+ }
+}
+