diff options
| author | Packy Anderson <packy@cpan.org> | 2024-08-05 23:00:40 -0400 |
|---|---|---|
| committer | Packy Anderson <packy@cpan.org> | 2024-08-05 23:00:40 -0400 |
| commit | 4b08f96f7df8de14e0c77b7fabbde2ade95718d2 (patch) | |
| tree | 1b6d14e8e1b4c4a1fa6f4935c99c4da66249ba9b | |
| parent | d4691a9d293de4cf2f42e44cdefabb0b455045fb (diff) | |
| download | perlweeklychallenge-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.md | 2 | ||||
| -rw-r--r-- | challenge-281/packy-anderson/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-281/packy-anderson/blog/graphviz.dot | 59 | ||||
| -rw-r--r-- | challenge-281/packy-anderson/blog/graphviz.png | bin | 0 -> 468918 bytes | |||
| -rwxr-xr-x | challenge-281/packy-anderson/elixir/ch-1.exs | 31 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/elixir/ch-2.exs | 20 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/perl/ch-1.pl | 25 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/perl/ch-2.pl | 81 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/python/ch-1.py | 23 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/python/ch-2.py | 77 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/raku/ch-1.raku | 25 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/raku/ch-2.raku | 81 |
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 Binary files differnew file mode 100644 index 0000000000..a0ec8a2060 --- /dev/null +++ b/challenge-281/packy-anderson/blog/graphviz.png 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'); |
