aboutsummaryrefslogtreecommitdiff
path: root/challenge-052/saiftynet
diff options
context:
space:
mode:
authorsaiftynet <saiftynet@gmail.com>2020-03-20 19:05:19 +0000
committersaiftynet <saiftynet@gmail.com>2020-03-20 19:05:19 +0000
commitfd9405d9763d3c54caea94ab37ca2bed211b1956 (patch)
tree2d1252e39aaef01df6d88af6f406efc8a36da1cf /challenge-052/saiftynet
parent77a796b73be1dcbba5543bbbc6acad2c923b06ff (diff)
downloadperlweeklychallenge-club-fd9405d9763d3c54caea94ab37ca2bed211b1956.tar.gz
perlweeklychallenge-club-fd9405d9763d3c54caea94ab37ca2bed211b1956.tar.bz2
perlweeklychallenge-club-fd9405d9763d3c54caea94ab37ca2bed211b1956.zip
Challenge-052 solutions by saiftynet
Diffstat (limited to 'challenge-052/saiftynet')
-rw-r--r--challenge-052/saiftynet/perl/ch-1.pl44
-rw-r--r--challenge-052/saiftynet/perl/ch-2.pl93
2 files changed, 137 insertions, 0 deletions
diff --git a/challenge-052/saiftynet/perl/ch-1.pl b/challenge-052/saiftynet/perl/ch-1.pl
new file mode 100644
index 0000000000..cf31e620ff
--- /dev/null
+++ b/challenge-052/saiftynet/perl/ch-1.pl
@@ -0,0 +1,44 @@
+#!/usr/env/perl
+# Task 1 Challenge 052 Solution by saiftynet
+# Stepping Numbers
+# Write a script to accept two numbers between 100 and 999. It should
+# then print all Stepping Numbers between them.
+# A number is called a stepping number if the adjacent digits have
+# a difference of 1. For example, 456 is a stepping number but 129
+# is not.
+
+# The challenge is relatively restricted that it only expects one
+# to provide 3 digit stepping numbers. This following solution extends
+# the task to be able to provide every stepping number from 0-9,999,999
+# So while the script will ask for two numbers, and will work perfectly
+# well from numbers 100-999 as specified in the task, it will work for
+# any inputs from 1 to 7 digits long
+
+# assembles an array of stepping numbers arranged by the number of digits
+my @steppingNumbers;
+
+# single digit numbers are just 1-9;
+$steppingNumbers[1]=[(1..9)];
+
+# subsequent arrays are assembled from the previous array
+foreach my $digitCount (2..7){
+ foreach my $no (@{$steppingNumbers[$digitCount-1]}){
+ # get the last digit
+ my $lastDigit=(split //,$no)[-1];
+ # now continue adding digits one more or one less than the last digit
+ # unless it will cause over or underflow
+ push @{$steppingNumbers[$digitCount]},$no.($lastDigit-1) if $lastDigit ne "0";
+ push @{$steppingNumbers[$digitCount]},$no.($lastDigit+1) if $lastDigit ne "9";
+ }
+}
+
+# main program loop
+print "Enter starting number >>" and chomp (my $in1=<>);
+print "Enter ending number >>" and chomp (my $in2=<>);
+# swaps numbers if entered in wrong order
+($in1,$in2)=($in2,$in1) if $in1>$in2;
+foreach my $digits (length $in1..length $in2){
+ foreach my $no (@{$steppingNumbers[$digits]}){
+ print $no," " if $no>$in1 and $no < $in2;
+ }
+}
diff --git a/challenge-052/saiftynet/perl/ch-2.pl b/challenge-052/saiftynet/perl/ch-2.pl
new file mode 100644
index 0000000000..a297b9a636
--- /dev/null
+++ b/challenge-052/saiftynet/perl/ch-2.pl
@@ -0,0 +1,93 @@
+#!/usr/env perl
+# Task 2 Challenge 052 Solution by saiftynet
+# Lucky Winner
+# Suppose there are following coins arranged on a table in a line
+# in random order.
+# £1, 50p, 1p, 10p, 5p, 20p, £2, 2p
+# Suppose you are playing against the computer. Player can only
+# pick one coin at a time from either ends. Find out the lucky winner,
+# who has the larger amounts in total?
+
+# A game in which the user or the computer can pick from either
+# end of an array...doing so implies either a pop or a shift.
+# This game offers player vs player, computer vs player or
+# computer vs computer options, and best of multiple games
+
+binmode STDOUT, 'utf8'; # required to allow £ symbol
+
+# initialise variables
+my (@coins, @p1,@p2,$p1Total,$p2Total);
+my $p1wins=$p2Wins=0;
+
+# Select players human or computers, choose which goes first and number of
+#ganmes to play
+print "Enter name of player1, or blank for Computer :- " and chomp( my $player1=<>);
+$player1="Computer" if $player1 eq "";
+print "Enter name of player2, or blank for Computer :- " and chomp( my $player2=<>);
+$player2="Computer" if $player2 eq "";
+
+# if both players have same name (e.g if both are computers
+if ($player1 eq $player2){$player1.=" 1"; $player2.=" 2"; };
+print "Enter number of games (1-9)" and chomp( my $games=<>);
+$games=1 if $games !~/^[1-9]$/;
+
+# game loop
+foreach (1..$games){
+ print "\n\n### Starting game $_ ###\n";
+ @p1=@p2=();$p1Total=$p2Total=0;
+ @coins=fisheryates(qw{1p 2p 5p 10p 20p 50p £1 £2}); # shuffle coins
+ while (@coins>0){ # make moves until no more coins
+ unshift @p1, move($player1)?shift @coins:pop @coins; # move coin from pile to player
+ print "---$player1 finds a $p1[0]\n"; # report coin found
+ $p1Total+=coinValue($p1[0]); # add the value of the coin to player1s total
+ unshift @p2, move($player2)?shift @coins:pop @coins; # move coin from pile to player
+ print "---$player2 finds a $p2[0]\n"; # report coin found
+ $p2Total+=coinValue($p2[0]); # add the value of the coin to player2s total
+ }
+
+ # game has ended, display reults
+ print "\n$player1 has: ", (join ", ",reverse @p1), " total= ",$p1Total;
+ print "\n$player2 has: ", (join ", ",reverse @p2), " total= ",$p2Total;
+ if ($p1Total>$p2Total){
+ $p1wins++;
+ print "\n* $player1 wins!!";
+ next
+ }
+ $p2wins++;
+ print "\n* $player2 wins!!";
+
+}
+
+# tot up overall results
+print "\n* $player1 has won $p1wins games, $player2 has won $p2wins games";
+sub move{
+ my $mover=shift;
+ my $choice="";
+ if ($mover !~/Computer/){
+ print "\n$mover pick end Left or Right (L or R)" and chomp($choice=<>) while $choice !~/[lr]/i;
+ }
+ else {
+ ($choice=(rand()>.5)?"Left":"Right") and print "\n$mover picks $choice\n";
+ }
+ return $choice =~/l/i;
+}
+
+# a classic shuffling routine slightly modified from version in Perl Cookbook
+# by Nathan Torkington, Tom Christiansen
+sub fisheryates{
+ my @list=@_;
+ for ($i = @list; --$i; ){
+ $j=rand($i+1);
+ next if $i == $j;
+ @list[$i,$j] = @list[$j,$i];
+ }
+return @list
+}
+
+# converts the coins to their penny values
+sub coinValue{
+ my $coin=shift;
+ $coin=~s/p$//; # if ends with p, just remove it
+ $coin=~s/\£(\d)/$1*100/e; # if starts with £, multiply by 100
+ return $coin;
+}