aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2020-02-24 00:10:31 +0000
committerGitHub <noreply@github.com>2020-02-24 00:10:31 +0000
commit7d8194326dfab06b99a5394e78b653485b6c09b9 (patch)
tree778d443427e049ae7e48caf262ebbbb69a88be53
parent65db9b76aeb3299ae12f2ba7a8fd4bdd8e235e72 (diff)
parent34e0375e897876fbcbb850b24ae5c29dbf429350 (diff)
downloadperlweeklychallenge-club-7d8194326dfab06b99a5394e78b653485b6c09b9.tar.gz
perlweeklychallenge-club-7d8194326dfab06b99a5394e78b653485b6c09b9.tar.bz2
perlweeklychallenge-club-7d8194326dfab06b99a5394e78b653485b6c09b9.zip
Merge pull request #1300 from dcw803/master
imported my solutions
-rw-r--r--challenge-048/duncan-c-white/README34
-rwxr-xr-xchallenge-048/duncan-c-white/perl/ch-1.pl74
-rwxr-xr-xchallenge-048/duncan-c-white/perl/ch-2.pl83
3 files changed, 170 insertions, 21 deletions
diff --git a/challenge-048/duncan-c-white/README b/challenge-048/duncan-c-white/README
index bc2b8ce427..fd02558cf3 100644
--- a/challenge-048/duncan-c-white/README
+++ b/challenge-048/duncan-c-white/README
@@ -1,29 +1,21 @@
-Task 1: "Roman Calculator
+Task 1: "Survivor
-Write a script that accepts two roman numbers and operation. It should
-then perform the operation on the give roman numbers and print the result.
+There are 50 people standing in a circle in position 1 to 50. The person
+standing at position 1 has a sword. He kills the next person i.e. standing
+at position 2 and pass on the sword to the immediate next i.e. person
+standing at position 3. Now the person at position 3 does the same and
+it goes on until only one survives.
-For example,
-
-perl ch-1.pl V + VI
-
-should print
-
-XI
+Write a script to find out the survivor.
"
-My notes: cute, especially given that we did Roman->Int and Int->Roman in
-challenge 10:-). So convert Roman->Int, Do Op, Int->Roman for the result.
-Added the ability for the user to specify the operands in EITHER Roman
-or Arabic.
+My notes: cute, sounds easy. Let's investigate this for N=1..max
-Task #2: "Gapful Numbers
+Task #2: "Palindrome Dates
-Write a script to print first 20 Gapful Numbers greater than or equal
-to 100. See https://oeis.org/A108343 for details.
-In summary, Gapful Numbers are those numbers >= 100 that are divisible
-by the number formed by their first and last digit. Numbers up to 100
-trivially have this property and are excluded. eg. 100 is, because 100%10==0
+Write a script to print all Palindrome Dates between 2000 and 2999. The
+format of date is mmddyyyy. For example, the first one was on October 2,
+2001 as it is represented as 10022001.
"
-My notes: cute. Easy. Was so easy that I did it in Postscript as well.
+My notes: cute, but why American date format? Let's let the user choose..
diff --git a/challenge-048/duncan-c-white/perl/ch-1.pl b/challenge-048/duncan-c-white/perl/ch-1.pl
new file mode 100755
index 0000000000..8062215bb0
--- /dev/null
+++ b/challenge-048/duncan-c-white/perl/ch-1.pl
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+#
+# Task 1: "Survivor
+#
+# There are 50 people standing in a circle in position 1 to 50. The person
+# standing at position 1 has a sword. He kills the next person i.e. standing
+# at position 2 and pass on the sword to the immediate next i.e. person
+# standing at position 3. Now the person at position 3 does the same and
+# it goes on until only one survives.
+#
+# Write a script to find out the survivor.
+# "
+#
+# My notes: cute, sounds easy. Let's investigate this for N=1..max
+#
+
+use feature 'say';
+use strict;
+use warnings;
+use Function::Parameters;
+use Getopt::Long;
+#use Data::Dumper;
+
+my $debug = 0;
+my $tabulate = 0;
+my $result = GetOptions( "tabulate" => \$tabulate, "debug" => \$debug );
+die "Usage: survivor [--debug] [--tabulate] [MAX]\n" if $result && @ARGV>1;
+my $max = shift // 50;
+
+if( $tabulate )
+{
+ foreach my $n (1..$max)
+ {
+ my $survivor = survivor( $n );
+ say "$n people survivor: person $survivor";
+ }
+}
+else
+{
+ my $survivor = survivor( $max );
+ say "$max people survivor: person $survivor";
+}
+
+
+#
+# my $survivor = survivor( $n );
+# Do the above survivor algorithm for $n people.
+# Return the person number of the sole survivor.
+#
+fun survivor( $n )
+{
+ my @alive = ( 1..$n ); # @alive list of person numbers still alive
+ my $pos = 0; # position in @alive
+ my $nalive = $n; # number of people still alive
+ while( $nalive>1 )
+ {
+ # person at pos $pos kills person next to him
+ my $i = $alive[$pos];
+ my $nextpos = $pos+1;
+ $nextpos = 0 if $nextpos>$#alive;
+ my $j = $alive[$nextpos];
+ say "person $i at pos $pos kills next person $j" if $debug;
+ splice( @alive, $nextpos, 1 );
+ $nalive--;
+ # hand sword on
+ $pos++;
+ $pos = 0 if $pos>$#alive;
+ my $k = $alive[$pos];
+ say "hands sword onto person $k at pos $pos" if $debug;
+ say "$nalive people alive: ", join(',',@alive) if $debug;
+ }
+ say "" if $debug;
+ return $alive[0];
+}
diff --git a/challenge-048/duncan-c-white/perl/ch-2.pl b/challenge-048/duncan-c-white/perl/ch-2.pl
new file mode 100755
index 0000000000..dde1ef7f22
--- /dev/null
+++ b/challenge-048/duncan-c-white/perl/ch-2.pl
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+#
+# Task #2: "Palindrome Dates
+#
+# Write a script to print all Palindrome Dates between 2000 and 2999. The
+# format of date is mmddyyyy. For example, the first one was on October 2,
+# 2001 as it is represented as 10022001.
+# "
+#
+# My notes: cute, but why American date format? Let's let the user choose..
+#
+
+use feature 'say';
+use strict;
+use warnings;
+use Getopt::Long;
+use Date::Manip;
+use Function::Parameters;
+
+my $format = "US";
+my %valid = map { $_ => 1 } qw(UK ISO US);
+my $result = GetOptions( "format=s" => \$format );
+die "Usage: palindromicdates [--format=UK|ISO|US] [STARYEAR [ENDYEAR]]\n"
+ if $result && @ARGV>2;
+my $startyear = shift // 2000;
+my $endyear = shift // 2999;
+$format = uc($format);
+die "bad format $format (should be UK|ISO|US)\n" unless $valid{$format};
+
+my @palindromes = palindromicdates( $startyear, $endyear, $format );
+say join("\n",@palindromes);
+
+#
+# my $ispal = palindromic( $s );
+# Returns 1 iff the string $s is palindromic.
+#
+fun palindromic( $s )
+{
+ return $s eq reverse($s) ? 1 : 0;
+}
+
+
+#
+# my $datestr = formdate( $day, $month, $year, $format );
+# Form the date string for day no $day (1..ndaysinmonth),
+# month $month (1..12) and year $year, in the given format $format,
+# which is either UK (ddmmyyyy) or US (mmddyyyy) or ISO (yyymmdd).
+#
+fun formdate( $day, $month, $year, $format )
+{
+ my $y = sprintf( "%04d", $year );
+ my $m = sprintf( "%02d", $month );
+ my $d = sprintf( "%02d", $day );
+ return "$d$m$y" if $format eq "UK";
+ return "$m$d$y" if $format eq "US";
+ return "$y$m$d" if $format eq "ISO";
+ die "formdate: bad format $format, should be UK|US|ISO";
+}
+
+
+#
+# my @p = palindromicdates( $startyear, $endyear, $format );
+# Find and return all palindromic dates in any year between $startyear
+# and $endyear in date format $format (UK or US or ISO).
+#
+fun palindromicdates( $startyear, $endyear, $format )
+{
+ my @palindrome;
+ foreach my $year ($startyear..$endyear)
+ {
+ foreach my $month (1..12)
+ {
+ my $ndays = Date_DaysInMonth($month,$year);
+ foreach my $day (1..$ndays)
+ {
+ my $date = formdate(
+ $day, $month, $year, $format );
+ push @palindrome, $date if palindromic($date);
+ }
+ }
+ }
+ return @palindrome;
+}