aboutsummaryrefslogtreecommitdiff
path: root/challenge-138/colin-crain
diff options
context:
space:
mode:
authorMohammad S Anwar <mohammad.anwar@yahoo.com>2021-11-15 03:07:56 +0000
committerMohammad S Anwar <mohammad.anwar@yahoo.com>2021-11-15 03:07:56 +0000
commit814dadd73434d2f7fa6db52a424d6b059913be64 (patch)
tree68dcec0169fa7158160fcd5b2681631719219f8c /challenge-138/colin-crain
parent24cd30b39971a866bd7f318d1d670e877f3061bf (diff)
downloadperlweeklychallenge-club-814dadd73434d2f7fa6db52a424d6b059913be64.tar.gz
perlweeklychallenge-club-814dadd73434d2f7fa6db52a424d6b059913be64.tar.bz2
perlweeklychallenge-club-814dadd73434d2f7fa6db52a424d6b059913be64.zip
- Added solutions by Colin Crain.
Diffstat (limited to 'challenge-138/colin-crain')
-rwxr-xr-xchallenge-138/colin-crain/perl/ch-1.pl98
-rwxr-xr-xchallenge-138/colin-crain/perl/ch-2.pl156
2 files changed, 254 insertions, 0 deletions
diff --git a/challenge-138/colin-crain/perl/ch-1.pl b/challenge-138/colin-crain/perl/ch-1.pl
new file mode 100755
index 0000000000..2e7e7f574e
--- /dev/null
+++ b/challenge-138/colin-crain/perl/ch-1.pl
@@ -0,0 +1,98 @@
+#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# .pl
+#
+#
+# Workdays
+# Submitted by: Mohammad S Anwar
+# You are given a year, $year in 4-digits form.
+#
+# Write a script to calculate the total number of workdays in the given year.
+#
+# For the task, we consider, Monday - Friday as workdays.
+#
+# Example 1
+# Input: $year = 2021
+# Output: 261
+# Example 2
+# Input: $year = 2020
+# Output: 262
+
+# method:
+#
+# Ahh, another DateTime problem, as far as I'm concerned.
+# Excellent. This is good for me, actually, as I could use more
+# immediate familiiarity with that module. I did previusly use
+# Date::Manip on a project, but I think I'm going to move on
+# over on this one. Let's take 'er out for a spin, as they say.
+#
+# The way we'll do this is to count them. We have January 1st,
+# and a set duration of one day. We assess a day, chalk it up
+# if its a workday, count down the days remaining to be
+# counted, and move to the next day.
+#
+# Some people would solve this by determining whether its a
+# leap year and responding 261 or 262 appropriately, but I
+# consider this unsporting. I will pretend I don't know the
+# answer and recalculate it.
+#
+# I think it's the scientist thing. There's no shame in
+# repeating an experiment. I suppose I am relying on DateTime
+# to give me the correct days of the week, but recreating that
+# calculation breaks the covenant to not mess with doing your
+# own calender calculations. The calender we use is a twisted
+# artifact wedged and shimmed into fitting just right,
+# requiring constant maintenance to properly reflect the
+# physical world we live in. Leap years are child's play, a
+# hack from centuries ago. Leap century years are geeting
+# there, but leap seconds are where its at, baby, and don't you
+# forget. We must properly account for Earth's perturbations on
+# its axis. I do pity the poor spacecraft designers, who need
+# to toss reletivity into the mix. I don't know how they do it.
+#
+# Seriously, I don't know how they do it. Probably a lot of
+# little post-corrections whenever things get out of line. But
+# that's just a guess. Try and avoid making it matter and fix
+# it in editing.
+#
+# In any case we're going to play around with durations a bit
+# and count the days. Come on, it'll be fun.
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use utf8;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+
+use DateTime;
+
+my $year = shift @ARGV || 2020;
+
+my $dt = DateTime
+ ->new( year => $year ,
+ month => 1 ,
+ day => 1 );
+
+my $dur = DateTime::Duration
+ ->new ( days => 1 );
+
+my $num_days = 365;
+$dt->is_leap_year && $num_days++;
+my $workdays;
+
+
+while ( $num_days-- ) {
+ $dt->dow < 6 && $workdays++;
+ $dt->add( $dur );
+}
+
+say $workdays;
+
+
diff --git a/challenge-138/colin-crain/perl/ch-2.pl b/challenge-138/colin-crain/perl/ch-2.pl
new file mode 100755
index 0000000000..d94ef038d6
--- /dev/null
+++ b/challenge-138/colin-crain/perl/ch-2.pl
@@ -0,0 +1,156 @@
+#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# .pl
+#
+# Split Number
+# Submitted by: Mohammad S Anwar
+# You are given a perfect square.
+#
+# Write a script to figure out if the square root the given number
+# is same as sum of 2 or more splits of the given number.
+#
+# Example 1
+# Input: $n = 81
+# Output: 1
+#
+# Since, sqrt(81) = 8 + 1
+#
+# Example 2
+# Input: $n = 9801
+# Output: 1
+#
+# Since, sqrt(9801) = 98 + 0 + 1
+#
+# Example 3
+# Input: $n = 36
+# Output: 0
+#
+# Since, sqrt(36) != 3 + 6
+#
+#
+# method:
+#
+# "2 or more splits of the given number"
+#
+# The what of the what? Splits? What is that? I mean, I see what it
+# is. You might call it a sort of "digital partioning", with
+# sequential digits grouped in various arrangements. It's
+# mathematically curious because the positional values change for a
+# given digit depending on the segmentation. Mathematically it's
+# all very weird.
+#
+# SOmehow I doubt there's any other name for it: "splits" is as
+# good as any, but "digital partition" at least sounds like a
+# specific process, like the digital root with 50% less Voodoo. Or
+# maybe Kabbalah would be more accurate.
+#
+# In any case it all soounds very complex if we look at the groups
+# of numbers generated when multiple splitting variations are
+# available. One thing is noteworthy, however, and that is that we
+# are taking ordered sets; if different partitionings generate the
+# same set of values, and hence the same sum, from different
+# groupings of the digits, then that's just coincidence. The
+# different groupings are different partitions and that is that.
+#
+# For example take the number 361361. There are many partitions
+# available, but two of these are (36) + (1) + (3) + (6) + (1) and
+# (3) + (6) + (1) + (36) + (1) As the divisions lie in different
+# places, they would be different partitions, or slices. As they
+# sum to the same value this makes no difference for this task. The
+# task asks only whether such a matching digital partition exists,
+# not what it is.
+#
+# Of ocurse we're going to ignore that and find them all. That,
+# after all, is how we roll.
+#
+# Focusing on the numbers produced is daunting, as the values a
+# given digit may have changes drastically as it changes
+# positionally, so I think it best to not solve the problem
+# mathematically at all. We're looking at an ordered collection of
+# items and wish to divide it into groups, maintaining local
+# postional order. We can do that by focusing not on the items, but
+# rather on the division points.
+#
+# There are n-1 division points between items, in this case the
+# individual digits. Each point can either hold a division or not,
+# or occupy one of two states. Another way of saying this is we are
+# looking for a set of subsets of a set of n-1 elements, which has
+# 2^n-1 elements. The states, whether we have a division between
+# two chaaracters or not, can be mapped to a bit in a binary number
+# matching that position: a three digit binary number can map to
+# the three divisions between four characters. If the bit is set,
+# we make a slice, or if it is not we leave the characters
+# connected. If we do this over the range from 0 to (2^n-1)-1 we
+# will create a template for every combination of splits and joins
+# possible between n characters, and hence every substring
+# combination.
+#
+# We are given a perfect square, so we know that the square root
+# will be an integer. Just to be sure we could validate our inpout
+# at this point to make sure we're all on the same page, so to
+# speak.
+
+
+
+
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use utf8;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+use List::Util qw( sum );
+
+for my $num (1..100000) {
+
+ $num *= $num;
+ my @output = digipart( $num );
+ next unless scalar @output;
+
+ say "INPUT: ", $num;
+ say "OUTPUT: found ", scalar @output, " solutions";
+
+ for (1..scalar @output) {
+ say join ' + ', (shift @output)->@*;
+ }
+
+ say '';
+
+}
+
+sub perfect_root ( $num ) {
+## checks to see whether $num is a perfect square. If so, returns the
+## square root, if not, returns 0
+ my $root = int(sqrt $num);
+ return $root**2 == $num
+ ? $root
+ : 0 ;
+}
+
+sub digipart ( $num ) {
+ my $root = perfect_root( $num );
+ my $div = length($num) - 1;
+ my $bfmt = "%0${div}b";
+ my @output;
+
+ for (0..2**$div-1) {
+ my $bin = sprintf $bfmt, $_;
+ my @sliced = substr $num, 0, 1;
+ for my $pos (0..$div-1) {
+ substr ($bin, $pos, 1) == 1
+ ? $sliced[-1] .= substr $num, $pos+1, 1
+ : push @sliced, substr $num, $pos+1, 1 ;
+ }
+ if ( sum(@sliced) == $root ) {
+ push @output, \@sliced;
+ }
+ }
+ return @output;
+}
+