aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPacky Anderson <packy@cpan.org>2024-08-05 23:00:40 -0400
committerPacky Anderson <packy@cpan.org>2024-08-05 23:00:40 -0400
commit4b08f96f7df8de14e0c77b7fabbde2ade95718d2 (patch)
tree1b6d14e8e1b4c4a1fa6f4935c99c4da66249ba9b
parentd4691a9d293de4cf2f42e44cdefabb0b455045fb (diff)
downloadperlweeklychallenge-club-4b08f96f7df8de14e0c77b7fabbde2ade95718d2.tar.gz
perlweeklychallenge-club-4b08f96f7df8de14e0c77b7fabbde2ade95718d2.tar.bz2
perlweeklychallenge-club-4b08f96f7df8de14e0c77b7fabbde2ade95718d2.zip
Challenge 281 solutions by Packy Anderson
* Raku that maybe looks like Raku, but mostly like Perl * Perl * Python that definitely looks like Perl * Elixir (Task 1 only so far) 1 Blog post
-rw-r--r--challenge-281/packy-anderson/README.md2
-rw-r--r--challenge-281/packy-anderson/blog.txt1
-rw-r--r--challenge-281/packy-anderson/blog/graphviz.dot59
-rw-r--r--challenge-281/packy-anderson/blog/graphviz.pngbin0 -> 468918 bytes
-rwxr-xr-xchallenge-281/packy-anderson/elixir/ch-1.exs31
-rwxr-xr-xchallenge-281/packy-anderson/elixir/ch-2.exs20
-rwxr-xr-xchallenge-281/packy-anderson/perl/ch-1.pl25
-rwxr-xr-xchallenge-281/packy-anderson/perl/ch-2.pl81
-rwxr-xr-xchallenge-281/packy-anderson/python/ch-1.py23
-rwxr-xr-xchallenge-281/packy-anderson/python/ch-2.py77
-rwxr-xr-xchallenge-281/packy-anderson/raku/ch-1.raku25
-rwxr-xr-xchallenge-281/packy-anderson/raku/ch-2.raku81
12 files changed, 424 insertions, 1 deletions
diff --git a/challenge-281/packy-anderson/README.md b/challenge-281/packy-anderson/README.md
index 7974906632..69be440f4b 100644
--- a/challenge-281/packy-anderson/README.md
+++ b/challenge-281/packy-anderson/README.md
@@ -22,4 +22,4 @@
## Blog Post
-[Perl Weekly Challenge: Appear Twice, Count Once](https://packy.dardan.com/b/P_)
+[Perl Weekly Challenge: The Ultimate Test of Cerebral Fitness](https://packy.dardan.com/b/Pd)
diff --git a/challenge-281/packy-anderson/blog.txt b/challenge-281/packy-anderson/blog.txt
new file mode 100644
index 0000000000..84c5dd54ff
--- /dev/null
+++ b/challenge-281/packy-anderson/blog.txt
@@ -0,0 +1 @@
+https://packy.dardan.com/b/Pd \ No newline at end of file
diff --git a/challenge-281/packy-anderson/blog/graphviz.dot b/challenge-281/packy-anderson/blog/graphviz.dot
new file mode 100644
index 0000000000..5651258a6a
--- /dev/null
+++ b/challenge-281/packy-anderson/blog/graphviz.dot
@@ -0,0 +1,59 @@
+digraph G {
+ node [style=filled]
+ edge [style=dashed]
+ g2 -> e3 -> c4 -> b6 -> a8 [style=solid, color=red];
+ g2 -> e1
+ g2 -> f4
+ g2 -> h4
+ e1 -> c2
+ e1 -> d3
+ e1 -> f3
+ e3 -> d1
+ e3 -> d5
+ e3 -> g4
+ e3 -> f1
+ e3 -> f5
+ f4 -> e2
+ f4 -> e6
+ f4 -> h3
+ f4 -> h5
+ f4 -> g6
+ c2 -> a1
+ c2 -> a3
+ c2 -> b4
+ c2 -> d4
+ d3 -> b2
+ d3 -> c1
+ d3 -> c5
+ d3 -> f2
+ d3 -> e5
+ f3 -> d2
+ f3 -> h2
+ f3 -> g1
+ f3 -> g5
+ c4 -> a5
+ c4 -> d6
+ d1 -> c3
+ d5 -> c7
+ d5 -> f6
+ d5 -> e7
+ g4 -> h6
+ f1 -> g3
+ f5 -> g7
+ e6 -> d8
+ e6 -> f8
+ g6 -> h8
+ a1 -> b3
+ a3 -> b1
+ a3 -> b5
+ b4 -> a2
+ b4 -> a6
+ b4 -> c6
+ b2 -> a4
+ c5 -> b7
+ c5 -> e4
+ c5 -> d7
+ f2 -> h1
+ e5 -> f7
+ g5 -> h7
+} \ No newline at end of file
diff --git a/challenge-281/packy-anderson/blog/graphviz.png b/challenge-281/packy-anderson/blog/graphviz.png
new file mode 100644
index 0000000000..a0ec8a2060
--- /dev/null
+++ b/challenge-281/packy-anderson/blog/graphviz.png
Binary files differ
diff --git a/challenge-281/packy-anderson/elixir/ch-1.exs b/challenge-281/packy-anderson/elixir/ch-1.exs
new file mode 100755
index 0000000000..ebf52874c3
--- /dev/null
+++ b/challenge-281/packy-anderson/elixir/ch-1.exs
@@ -0,0 +1,31 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ require Integer
+
+ def isLight(coordinates) do
+ letter = String.first(coordinates)
+ {num, _} = Integer.parse(String.last(coordinates))
+ cond do
+ String.contains?("aceg", letter)
+ and Integer.is_even(num) -> "true"
+ String.contains?("bdfh", letter)
+ and Integer.is_odd(num) -> "true"
+ true -> "false"
+ end
+ end
+
+ def solution(coordinates) do
+ IO.puts("Input: $coordinates = \"#{coordinates}\"")
+ IO.puts("Output: " <> isLight(coordinates) )
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution("d3")
+
+IO.puts("\nExample 2:")
+PWC.solution("g5")
+
+IO.puts("\nExample 3:")
+PWC.solution("e6")
diff --git a/challenge-281/packy-anderson/elixir/ch-2.exs b/challenge-281/packy-anderson/elixir/ch-2.exs
new file mode 100755
index 0000000000..04b5c8529b
--- /dev/null
+++ b/challenge-281/packy-anderson/elixir/ch-2.exs
@@ -0,0 +1,20 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+
+ def solution(ints) do
+ IO.puts("Input: @ints = (" <> Enum.join(ints, ", ") <> ")")
+ {sign, explain} = PWC.productSign(ints)
+ IO.puts("Output: " <> to_string(sign) )
+ IO.puts("\n" <> explain)
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution()
+
+IO.puts("\nExample 2:")
+PWC.solution()
+
+IO.puts("\nExample 3:")
+PWC.solution()
diff --git a/challenge-281/packy-anderson/perl/ch-1.pl b/challenge-281/packy-anderson/perl/ch-1.pl
new file mode 100755
index 0000000000..ff595d7c57
--- /dev/null
+++ b/challenge-281/packy-anderson/perl/ch-1.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/env perl
+use v5.40;
+
+sub isLight($coordinates) {
+ my ($letter, $num) = split //, $coordinates;
+ return (
+ ( ($letter =~ /[aceg]/) && ($num % 2 == 0) )
+ ||
+ ( ($letter =~ /[bdfh]/) && ($num % 2 == 1) )
+ ) ? 'true' : 'false';
+}
+
+sub solution($coordinates) {
+ say qq/Input: \$coordinates = "$coordinates"/;
+ say 'Output: ' . isLight($coordinates);
+}
+
+say "Example 1:";
+solution("d3");
+
+say "\nExample 2:";
+solution("g5");
+
+say "\nExample 3:";
+solution("e6");
diff --git a/challenge-281/packy-anderson/perl/ch-2.pl b/challenge-281/packy-anderson/perl/ch-2.pl
new file mode 100755
index 0000000000..92eeb1cbd4
--- /dev/null
+++ b/challenge-281/packy-anderson/perl/ch-2.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/env perl
+use v5.40;
+
+my @knightMoveList = (
+ [-2, -1], [-2, +1], [-1, -2], [-1, +2],
+ [+2, -1], [+2, +1], [+1, -2], [+1, +2],
+);
+
+sub knightMoves($coordinates) {
+ my ($letter, $num) = split //, $coordinates;
+ my @endpoints;
+ foreach my $colRow ( @knightMoveList ) {
+ my ($col, $row) = @$colRow;
+ my $newcol = chr(ord($letter) + $col);
+ next unless $newcol ge "a" && $newcol le "h";
+ my $newrow = $num + $row;
+ next unless 1 <= $newrow <= 8;
+ push @endpoints, ($newcol . $newrow);
+ }
+ return @endpoints;
+}
+
+sub leastMoves($start, $end) {
+ # trivial case: we're already at the end point
+ return ( 0, $end ) if $start eq $end;
+
+ # Ok, we're going to need to search for a solution.
+
+ # Keep track of how many moves it takes to get to
+ # a particular position, starting at $start
+ my %moves = ( $start => 0 );
+
+ # also keep track of the path to get there
+ my %path_to = ( $start => $start );
+
+ # make a queue of starting points
+ my @queue = ( $start );
+
+ while ( @queue ) {
+ $start = shift @queue;
+
+ # figure out the valid moves that we haven't been to yet
+ my @endpoints = grep {
+ ! exists $path_to{$_}
+ } knightMoves($start);
+
+ foreach my $next ( @endpoints ) {
+ # build the path to the next endpoint
+ $path_to{$next} = $path_to{$start} . " -> $next";
+
+ # increment the number of moves it takes to get there
+ $moves{$next} = $moves{$start} + 1;
+
+ # have we arrived at our destination
+ return ( $moves{$next}, $path_to{$next} ) if $next eq $end;
+
+ # no? then push this space onto our processing queue
+ push @queue, $next;
+ }
+ }
+
+ # we can't get there from here!
+ # (only possible when the chessboard is an odd size)
+ return ( -1, "no path found" );
+}
+
+sub solution($start, $end) {
+ say qq/Input: \$start = '$start', \$end = '$end'/;
+ my ($count, $moves) = leastMoves($start, $end);
+ say 'Output: ' . $count;
+ say "\n$moves\n";
+}
+
+say "Example 1:";
+solution('g2', 'a8');
+
+say "\nExample 2:";
+solution('g2', 'h2');
+
+say "\nExample 3:";
+solution('a1', 'h8');
diff --git a/challenge-281/packy-anderson/python/ch-1.py b/challenge-281/packy-anderson/python/ch-1.py
new file mode 100755
index 0000000000..a327de57b8
--- /dev/null
+++ b/challenge-281/packy-anderson/python/ch-1.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+def isLight(coordinates):
+ letter = coordinates[0:1]
+ num = int(coordinates[1:])
+ return (
+ ( (letter in "aceg") and (num % 2 == 0) )
+ or
+ ( (letter in "bdfh") and (num % 2 == 1) )
+ )
+
+def solution(coordinates):
+ print(f'Input: $coordinates = "{coordinates}"')
+ print(f'Output: {isLight(coordinates)}')
+
+print('Example 1:')
+solution("d3")
+
+print('\nExample 2:')
+solution("g5")
+
+print('\nExample 3:')
+solution("e6")
diff --git a/challenge-281/packy-anderson/python/ch-2.py b/challenge-281/packy-anderson/python/ch-2.py
new file mode 100755
index 0000000000..f1b8803a71
--- /dev/null
+++ b/challenge-281/packy-anderson/python/ch-2.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+knightMoveList = [
+ [-2, -1], [-2, +1], [-1, -2], [-1, +2],
+ [+2, -1], [+2, +1], [+1, -2], [+1, +2],
+]
+
+def knightMoves(coordinates):
+ letter = coordinates[0:1]
+ num = int(coordinates[1:])
+ endpoints = []
+ for colRow in knightMoveList:
+ col, row = colRow
+ newcol = chr(ord(letter) + col)
+ if "a" <= newcol <= "h":
+ newrow = num + row
+ if 1 <= newrow <= 8:
+ endpoints.append(newcol + str(newrow))
+ return endpoints
+
+
+def leastMoves(start, end):
+ # trivial case: we're already at the end point
+ if start == end:
+ return ( 0, end )
+
+ # Ok, we're going to need to search for a solution.
+
+ # Keep track of how many moves it takes to get to
+ # a particular position, starting at $start
+ moves = { start: 0 }
+
+ # also keep track of the path to get there
+ path_to = { start: start }
+
+ # make a queue of starting points
+ queue = [ start ]
+
+ while ( queue ):
+ start = queue.pop(0)
+
+ # figure out the valid moves that we haven't been to yet
+ endpoints = [
+ m for m in knightMoves(start) if m not in path_to
+ ]
+
+ for next in endpoints:
+ # build the path to the next endpoint
+ path_to[next] = f'{path_to[start]} -> {next}'
+
+ # increment the number of moves it takes to get there
+ moves[next] = moves[start] + 1
+
+ # have we arrived at our destination
+ if next == end:
+ return ( moves[next], path_to[next] )
+
+ # no? then push this space onto our processing queue
+ queue.append(next)
+
+ # we can't get there from here!
+ # (only possible when the chessboard is an odd size)
+ return ( -1, "no path found" )
+
+def solution(start, end):
+ print(f'Input: $start = \'{start}\', $end = \'{end}\'')
+ count, moves = leastMoves(start, end)
+ print(f'Output: {count}\n\n{moves}\n')
+
+print('Example 1:')
+solution('g2', 'a8')
+
+print('\nExample 2:')
+solution('g2', 'h2')
+
+print('\nExample 3:')
+solution('a1', 'h8')
diff --git a/challenge-281/packy-anderson/raku/ch-1.raku b/challenge-281/packy-anderson/raku/ch-1.raku
new file mode 100755
index 0000000000..44ea131900
--- /dev/null
+++ b/challenge-281/packy-anderson/raku/ch-1.raku
@@ -0,0 +1,25 @@
+#!/usr/bin/env raku
+use v6;
+
+sub isLight($coordinates) {
+ my ($letter, $num) = $coordinates.comb;
+ return (
+ $letter.match(/<[aceg]>/) && ($num %% 2)
+ ||
+ $letter.match(/<[bdfh]>/) && !($num %% 2)
+ ) ?? 'true' !! 'false';
+}
+
+sub solution($coordinates) {
+ say qq/Input: \$coordinates = "$coordinates"/;
+ say 'Output: ' ~ isLight($coordinates);
+}
+
+say "Example 1:";
+solution("d3");
+
+say "\nExample 2:";
+solution("g5");
+
+say "\nExample 3:";
+solution("e6");
diff --git a/challenge-281/packy-anderson/raku/ch-2.raku b/challenge-281/packy-anderson/raku/ch-2.raku
new file mode 100755
index 0000000000..4ab5b7f4b1
--- /dev/null
+++ b/challenge-281/packy-anderson/raku/ch-2.raku
@@ -0,0 +1,81 @@
+#!/usr/bin/env raku
+use v6;
+
+my @knightMoveList = (
+ (-2, -1), (-2, +1), (-1, -2), (-1, +2),
+ (+2, -1), (+2, +1), (+1, -2), (+1, +2),
+);
+
+sub knightMoves($coordinates) {
+ my ($letter, $num) = $coordinates.comb;
+ my @endpoints;
+ for @knightMoveList -> @colRow {
+ my ($col, $row) = @colRow;
+ my $newcol = ($letter.ord + $col).chr;
+ next unless $newcol ge "a" && $newcol le "h";
+ my $newrow = $num + $row;
+ next unless 1 <= $newrow <= 8;
+ @endpoints.push($newcol ~ $newrow);
+ }
+ return @endpoints;
+}
+
+sub leastMoves($start is copy, $end) {
+ # trivial case: we're already at the end point
+ return ( 0, $end ) if $start eq $end;
+
+ # Ok, we're going to need to search for a solution.
+
+ # Keep track of how many moves it takes to get to
+ # a particular position, starting at $start
+ my %moves = ( $start => 0 );
+
+ # also keep track of the path to get there
+ my %path_to = ( $start => $start );
+
+ # make a queue of starting points
+ my @queue = ( $start );
+
+ while ( @queue ) {
+ $start = @queue.shift;
+
+ # figure out the valid moves that we haven't been to yet
+ my @endpoints = knightMoves($start).grep({
+ %path_to{$_}:!exists
+ });
+
+ for @endpoints -> $next {
+ # build the path to the next endpoint
+ %path_to{$next} = %path_to{$start} ~ " -> $next";
+
+ # increment the number of moves it takes to get there
+ %moves{$next} = %moves{$start} + 1;
+
+ # have we arrived at our destination
+ return ( %moves{$next}, %path_to{$next} ) if $next eq $end;
+
+ # no? then push this space onto our processing queue
+ @queue.push: $next;
+ }
+ }
+
+ # we can't get there from here!
+ # (only possible when the chessboard is an odd size)
+ return ( -1, "no path found" );
+}
+
+sub solution($start, $end) {
+ say qq/Input: \$start = '$start', \$end = '$end'/;
+ my ($count, $moves) = leastMoves($start, $end);
+ say 'Output: ' ~ $count;
+ say "\n$moves\n";
+}
+
+say "Example 1:";
+solution('g2', 'a8');
+
+say "\nExample 2:";
+solution('g2', 'h2');
+
+say "\nExample 3:";
+solution('a1', 'h8');