## DEV Community is a community of 731,460 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Simon Proctor

Posted on

# Perl Weekly Challenge : Week 48

I've decided I'm going to try blogging about my attempts at the Perl Weekly Challenge which I've been doing since it started. Generally I do my challenge in Raku the language formally known as Perl6.

This weeks challenge has a couple of fun parts. If you've not tried it yet you might want to come back after you have.

## Challenge 1

So I'd seen a video on this before it's called the Josephus Problem so I knew there was a mathematical solution to it.... but I couldn't remember it.

As is often the way I went a bit above and beyond and worked out a function to give the survivor number for any number of swordsmen. My thinking about it was simple. Get a list of number from 1 to 50, take the first two from the front. The first survives the second is dead. Put the survivor at the end of the list. Repeat until you have 1 survivor :

``````#| Calculate the survivor of the swordsmen suicide pact
multi sub MAIN(
UInt \$swords = 50, #= Number of swordsmen (default 50)
) {
my @men = [1..\$swords];
while ( @men.elems > 1 ) {
my ( \$alive, \$dead ) = @men.splice(0,2);
@men.push(\$alive);
}

say "Survivor of \$swords is number {@men}";
}
``````

With that I was able to run the test for lots of different value and worked out the mathematical solution. Given a number of swordsmen (s) we find p where p < s and p is a power of 2. Then the number of the survivor is the nth odd number where n = s - p.

For example for s = 50, p = 32 and n is the 18th odd number (indexed on 0) which is 37.

The code for this :

``````#| Calculate mathematically
multi sub MAIN(
"math",
UInt \$swords = 50, #= Number of swordsmen
) {
my \$low-power = (1,* * 2...*).first(* > \$swords) div 2;
say "Survivor of \$swords is number {(1,3,5...*)[\$swords - \$low-power]}";
}
``````

Couple of fun uses of Raku sequences one to generate the powers of 2 and the second to generate the list of odd numbers.

## Challenge 2

For challenge 2 I initially worked on the theory I'll look at every date between 2020-01-01 and 2999-12-31 and look for palindromes. Turns out... that's a lot of days (357937 to be exact) and it take a while. Even when you use `.hyper` to thread the tests over multiple cores. But then I had a thought.

If I went through every month and day combination that's 12 x 31 (we'll worry about out of range values in a second) and that's only 372 to check. If we take the month and day and flip it to get a year if we can check it's valid and it's between our start and end dates.

``````#| Find the palendromic numbers (writen mmddyyy) between 2000-01-01 and 2999-01-01
sub MAIN() {
my sub df( Date \$d) {
# Bleh American dates
sprintf "%02d%02d%04d", .month, .day, .year given \$d;
}

constant START = Date.new(2000,1,1,formatter => &df);
constant END = Date.new(2999,12,31, formatter => &df);

my @out;

for (1..12) -> \$month {
for (1..31) -> \$day {
my \$date;
my \$year = sprintf( "%02d%02d", \$month, \$day ).flip;
try {
\$date = Date.new(\$year,\$month,\$day,formatter => &df);
}
next unless \$date;
next unless START <= \$date <= END;
@out.push(\$date);
}
}

.say for @out.sort;
}
``````

I hope that all makes sense. Feel free to drop a comment if you've got questions or thoughts.