aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-023/duane-powell/perl5/ch-1.pl56
-rwxr-xr-xchallenge-023/duane-powell/perl5/ch-2.pl86
2 files changed, 142 insertions, 0 deletions
diff --git a/challenge-023/duane-powell/perl5/ch-1.pl b/challenge-023/duane-powell/perl5/ch-1.pl
new file mode 100755
index 0000000000..d17b0b95b9
--- /dev/null
+++ b/challenge-023/duane-powell/perl5/ch-1.pl
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+use Modern::Perl;
+
+# Create a script that prints nth order forward difference series. You should be a able to pass
+# the list of numbers and order number as command line parameters. Let me show you with an example.
+
+# Suppose we have list (X) of numbers: 5, 9, 2, 8, 1, 6 and we would like to create 1st order
+# forward difference series (Y). So using the formula Y(i) = X(i+1) - X(i), we get the following
+# numbers: (9-5), (2-9), (8-2), (1-8), (6-1). In short, the final series would be: 4, -7, 6, -7, 5.
+# If you noticed, it has one less number than the original series. Similary you can carry on 2nd
+# order forward difference series like: (-7-4), (6+7), (-7-6), (5+7) => -11, 13, -13, 12.
+#
+my ($order, @series) = @ARGV;
+($order and @series > 1) || die "Usage:\n$0 order list-of-space-separated-ints\n";
+
+# No point in order being larger than series size - 1
+$order = scalar(@series)-1 if ($order >= @series);
+
+say "order:\tseries:";
+for (1 .. $order) {
+ my @num;
+ # we need two numbers to continue
+ if (@series > 1) {
+ my $x = shift @series;
+ foreach my $n (@series) {
+ push @num, $n-$x;
+ $x = $n;
+ }
+ say "$_:\t" . join(",",@num);
+ }
+ @series = @num;
+}
+
+__END__
+
+./ch-1.pl 5 5 9 2 8 1 6
+order: series:
+1: 4,-7,6,-7,5
+2: -11,13,-13,12
+3: 24,-26,25
+4: -50,51
+5: 101
+
+./ch-1.pl 10 1 2 3 4 5 6 7 8 9 10 10000
+order: series:
+1: 1,1,1,1,1,1,1,1,1,9990
+2: 0,0,0,0,0,0,0,0,9989
+3: 0,0,0,0,0,0,0,9989
+4: 0,0,0,0,0,0,9989
+5: 0,0,0,0,0,9989
+6: 0,0,0,0,9989
+7: 0,0,0,9989
+8: 0,0,9989
+9: 0,9989
+10: 9989
+
diff --git a/challenge-023/duane-powell/perl5/ch-2.pl b/challenge-023/duane-powell/perl5/ch-2.pl
new file mode 100755
index 0000000000..72abe7aacc
--- /dev/null
+++ b/challenge-023/duane-powell/perl5/ch-2.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+use Modern::Perl;
+use Math::Prime::Util qw(is_prime);
+use bigint;
+
+# Create a script that prints Prime Decomposition of a given number.
+# The prime decomposition of a number is defined as a list of prime
+# numbers which when all multiplied together, are equal to that number.
+# For example, the Prime decomposition of 228 is 2,2,3,19 as 228 = 2 x 2 x 3 x 19.
+
+my @num = @ARGV;
+(@num) || die "Usage:\n$0 list-of-space-separted-ints;\n$0 test\n";
+@num = (228,864,1008,1024,130321,823543,3894380348208432032,7102345678999999999) if ($ARGV[0] eq 'test');
+prime_fact($_) foreach (@num);
+exit;
+
+sub prime_fact {
+ my $p = shift;
+ if ($p < 2 or $p =~ m/\D/) {
+ say "$p? Input must be an integer greater than 1";
+ return;
+ }
+
+ my %out;
+ my $fac = 2;
+ my $n = $p;
+ while ($n >=2) {
+ if (is_prime($n)) {
+ $out{$n}++;
+ last;
+ } else {
+ if ($n % $fac) {
+ # Remainder exists, try next factor.
+ $fac++;
+ } else {
+ # No remainder, $fac is a factor.
+ # Continue with smaller $n
+ $out{$fac}++;
+ $n = $n/$fac;
+ }
+ }
+ }
+
+ # We got all factors and their counts, make the output human
+ # readable with commify() and powers, eg 2 x 2 x 2 = (2^3)
+ my @out;
+ foreach (sort {$a <=> $b} (keys %out)) {
+ if ($out{$_} > 1) {
+ push @out, "($_^" . commify($out{$_}) . ")";
+ } else {
+ push @out, commify($_);
+ }
+ }
+ # If input $p was a prime then display output as p=1xp by unshifting 1 into front of @out
+ unshift @out, 1 if (@out == 1 and $out[0] !~ m/\(/);
+ $p = commify($p);
+ say "$p = ", join(" x ", @out);
+}
+
+# From the Perl Cookbook
+sub commify {
+ my $n = reverse shift;
+ $n =~ s/(\d\d\d)(?=\d)(?!\dx\.)/$1,/g;
+ return scalar reverse $n;
+}
+
+__END__
+
+./ch-2.pl 999999999
+999,999,999 = (3^4) x 37 x 333,667
+
+./ch-2.pl 256 500 1001
+256 = (2^8)
+500 = (2^2) x (5^3)
+1,001 = 7 x 11 x 13
+
+./ch-2.pl test
+228 = (2^2) x 3 x 19
+864 = (2^5) x (3^3)
+1,008 = (2^4) x (3^2) x 7
+1,024 = (2^10)
+130,321 = (19^4)
+823,543 = (7^7)
+3,894,380,348,208,432,032 = (2^5) x 47 x 136,373 x 18,987,252,871
+7,102,345,678,999,999,999 = 661 x 45,600,991 x 235,627,549
+