aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Ransan <lucas@ransan.tk>2021-06-21 19:16:11 +0200
committerLucas Ransan <lucas@ransan.tk>2021-06-21 19:32:29 +0200
commit4c176e6c719a1fe5b734a9a795886a27ac08c7a2 (patch)
tree6a92891436d48754e2d64db0780a09253c1f6e74
parent398d0ae9fe0fa178774f23a6d901dfb6cbd3bb7c (diff)
downloadperlweeklychallenge-club-4c176e6c719a1fe5b734a9a795886a27ac08c7a2.tar.gz
perlweeklychallenge-club-4c176e6c719a1fe5b734a9a795886a27ac08c7a2.tar.bz2
perlweeklychallenge-club-4c176e6c719a1fe5b734a9a795886a27ac08c7a2.zip
Raku week 118 task 2
-rw-r--r--challenge-118/luc65r/input.txt10
-rwxr-xr-xchallenge-118/luc65r/raku/ch-2.raku91
2 files changed, 101 insertions, 0 deletions
diff --git a/challenge-118/luc65r/input.txt b/challenge-118/luc65r/input.txt
new file mode 100644
index 0000000000..625172b696
--- /dev/null
+++ b/challenge-118/luc65r/input.txt
@@ -0,0 +1,10 @@
+ a b c d e f g h
+ 8 N * * * * * * * 8
+ 7 * * * * * * * * 7
+ 6 * * * * x * * * 6
+ 5 * * * * * * * * 5
+ 4 * * x * * * * * 4
+ 3 * x * * * * * * 3
+ 2 x x * * * * * * 2
+ 1 * x * * * * * * 1
+ a b c d e f g h
diff --git a/challenge-118/luc65r/raku/ch-2.raku b/challenge-118/luc65r/raku/ch-2.raku
new file mode 100755
index 0000000000..d05941ef5a
--- /dev/null
+++ b/challenge-118/luc65r/raku/ch-2.raku
@@ -0,0 +1,91 @@
+#!/usr/bin/env raku
+
+#`{
+Brute force implementation.
+Provides the shortest path, but takes about 15 to 20 minutes.
+}
+
+subset Coordinate of UInt where 1 ≤ * ≤ 8;
+
+class Square {
+ has Coordinate $.y is required;
+ has Coordinate $.x is required;
+
+ method new(Coordinate:D $y, Coordinate:D $x --> Square:D) {
+ self.bless: :$y, :$x
+ }
+ method Str(Square:D: --> Str:D) {
+ self.gist
+ }
+ method gist(Square:D: --> Str:D) {
+ ('a' .. 'h')[$!x - 1] ~ $!y
+ }
+ method WHICH(Square:D: --> ValueObjAt) {
+ ValueObjAt.new: "Square|$!y|$!x"
+ }
+
+ method knight-moves(Square:D: --> Seq) {
+ gather {
+ for -1, 1 -> $i {
+ for -2, 2 -> $j {
+ try take Square.new: $!y + $i, $!x + $j;
+ try take Square.new: $!y + $j, $!x + $i;
+ }
+ }
+ }
+ }
+
+ method search(
+ Square:D:
+ Set[Square:D] $treasures,
+ UInt $depth,
+ Square:_ $last = Square,
+ --> Str:_
+ ) {
+ return if $depth == 0;
+
+ for self.knight-moves -> $square {
+ next if $last && $last === $square;
+
+ my Set[Square:D] $remaining = $treasures ∖ $square;
+ return ~$square if $remaining == ∅;
+ return "$square $_" with $square.search: $remaining, $depth - 1, self;
+ }
+ }
+}
+
+grammar Chessboard {
+ regex TOP { <.letters>? <line> ** 8 <.letters>? }
+
+ rule letters { \s* <.alpha> ** 8 }
+ rule line { \s* \d? <square> ** 8 \d? }
+
+ proto token square { * }
+ token square:sym('*') { <sym> }
+ token square:sym<x> { <sym> }
+ token square:sym<N> { <sym> }
+}
+
+class Board {
+ has UInt $!y = 8;
+ has UInt $!x = 1;
+ has Square $!start;
+ has Square @!treasures;
+
+ method TOP($/) { make self }
+ method line($/) { $!y--; $!x = 1 }
+ method square:sym('*')($/) { $!x++ }
+ method square:sym<x>($/) { @!treasures.push: Square.new: $!y, $!x++ }
+ method square:sym<N>($/) { $!start = Square.new: $!y, $!x++ }
+
+ method search(Board:D: --> Str:D) {
+ my $treasures = Set[Square:D].new: @!treasures;
+ for 0..∞ -> $i {
+ return $_ with Square.new(8, 1).search: $treasures, $i;
+ }
+ }
+}
+
+sub MAIN(Str:D $file = '-') {
+ say Chessboard.parsefile($file, actions => Board.new).made.search;
+}