From bceb7f7f17cf67f04b3b60c202f226a9d05750a9 Mon Sep 17 00:00:00 2001 From: saiftynet Date: Sun, 31 May 2020 23:00:17 +0100 Subject: Challenge-062 solutions by saiftynet --- challenge-062/saiftynet/perl/ch-1.pl | 100 ++++++++++++++++++++++++++++++ challenge-062/saiftynet/perl/ch-2.pl | 114 +++++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 challenge-062/saiftynet/perl/ch-1.pl create mode 100644 challenge-062/saiftynet/perl/ch-2.pl 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’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(){ + 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’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"; + } + } +} + -- cgit