diff options
| author | Lucas Ransan <lucas@ransan.tk> | 2021-06-21 19:16:11 +0200 |
|---|---|---|
| committer | Lucas Ransan <lucas@ransan.tk> | 2021-06-21 19:32:29 +0200 |
| commit | 4c176e6c719a1fe5b734a9a795886a27ac08c7a2 (patch) | |
| tree | 6a92891436d48754e2d64db0780a09253c1f6e74 | |
| parent | 398d0ae9fe0fa178774f23a6d901dfb6cbd3bb7c (diff) | |
| download | perlweeklychallenge-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.txt | 10 | ||||
| -rwxr-xr-x | challenge-118/luc65r/raku/ch-2.raku | 91 |
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; +} |
