aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-118/paulo-custodio/perl/ch-1.pl24
-rw-r--r--challenge-118/paulo-custodio/perl/ch-2.pl200
-rw-r--r--challenge-118/paulo-custodio/t/test-1.yaml10
-rw-r--r--challenge-118/paulo-custodio/t/test-2.yaml15
-rw-r--r--challenge-118/paulo-custodio/test.pl4
5 files changed, 253 insertions, 0 deletions
diff --git a/challenge-118/paulo-custodio/perl/ch-1.pl b/challenge-118/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..678ccbc4d9
--- /dev/null
+++ b/challenge-118/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,24 @@
+#!/usr/bin/env perl
+
+# Challenge 118
+#
+# TASK #1 - Binary Palindrome
+# Submitted by: Mohammad S Anwar
+# You are given a positive integer $N.
+#
+# Write a script to find out if the binary representation of the given integer
+# is Palindrome. Print 1 if it is otherwise 0.
+#
+# Example
+# Input: $N = 5
+# Output: 1 as binary representation of 5 is 101 which is Palindrome.
+#
+# Input: $N = 4
+# Output: 0 as binary representation of 4 is 100 which is NOT Palindrome.
+
+use Modern::Perl;
+
+my $N = shift // 0;
+my $bits = sprintf("%b", $N);
+my $rbits = reverse($bits);
+say $bits eq $rbits ? 1 : 0;
diff --git a/challenge-118/paulo-custodio/perl/ch-2.pl b/challenge-118/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..2463830515
--- /dev/null
+++ b/challenge-118/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,200 @@
+#!/usr/bin/env perl
+
+# Challenge 118
+#
+# TASK #2 - Adventure of Knight
+# Submitted by: Cheok-Yin Fung
+# A knight is restricted to move on an 8×8 chessboard. The knight is denoted by
+# N and its way of movement is the same as what it is defined in Chess.
+# * represents an empty square. x represents a square with treasure.
+#
+# The Knight’s movement is unique. It may move two squares vertically and one
+# square horizontally, or two squares horizontally and one square vertically
+# (with both forming the shape of an L).
+#
+# There are 6 squares with treasures.
+#
+# Write a script to find the path such that Knight can capture all treasures.
+# The Knight can start from the top-left square.
+#
+# 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
+#
+
+# https://en.m.wikipedia.org/wiki/Knight%27s_tour
+
+use Modern::Perl;
+use Clone 'clone';
+
+{
+ package Board;
+ use Object::Tiny::RW qw( board treasures path );
+
+ sub new {
+ my($class) = @_;
+ my $self = bless {
+ board => [[],[],[],[],[],[],[],[]],
+ treasures => {},
+ path => [],
+ }, $class;
+ return $self;
+ }
+
+ sub parse {
+ my($self) = @_;
+ $self->board([[],[],[],[],[],[],[],[]]);
+ $self->treasures({});
+ $self->path([]);
+
+ local $_;
+ $_ = <>;
+ /a b c d e f g h/i or die "expected header";
+ for my $row (0..7) {
+ my $y = 8 - $row;
+ $_ = <>;
+ s/^ \s* $y \s*//x or die "expected row $y";
+ for my $col (0..7) {
+ my $x = chr(ord('a') + $col);
+ s/^ (\S) \s* //x or die "expected cell $x$y";
+ my $cell = $1;
+ if ($cell eq 'N') {
+ push @{$self->path}, [$row, $col];
+ $self->board->[$row][$col] = 1;
+ }
+ elsif ($cell eq 'x') {
+ $self->treasures->{"$row$col"} = 1;
+ }
+ }
+ }
+ $_ = <>;
+ /a b c d e f g h/i or die "expected footer";
+ }
+
+ sub next_moves {
+ my($self, $row, $col) = @_;
+ my @next;
+ for ([-2, -1], [-2, +1], [+2, -1], [+2, +1],
+ [+1, -2], [-1, -2], [+1, +2], [-1, +2]) {
+ my($drow, $dcol) = @$_;
+ my $nrow = $row + $drow;
+ my $ncol = $col + $dcol;
+ if ($nrow >= 0 && $nrow < 8) {
+ if ($ncol >= 0 && $ncol < 8) {
+ if (!$self->board->[$nrow][$ncol]) {
+ push @next, [$nrow, $ncol];
+ }
+ }
+ }
+ }
+ return @next;
+ }
+
+ sub next_possible_moves {
+ my($self) = @_;
+
+ # get current position
+ my($row, $col) = @{$self->path->[-1]};
+
+ # get possible moves from here
+ my @next = $self->next_moves($row, $col);
+
+ # count possible moves from each destination
+ my $min_count = 1e10;
+ for (@next) {
+ my($nrow, $ncol) = @$_;
+ my $count = $self->next_moves($nrow, $ncol);
+ push @$_, $count;
+ $min_count = $count if $min_count > $count;
+ }
+
+ # select move(s) with less count
+ @next = grep {$_->[2] == $min_count} @next;
+
+ return @next;
+ }
+
+ sub path_str {
+ my($self) = @_;
+ my @moves;
+ for (@{$self->path}) {
+ my($row, $col) = @$_;
+ my $x = chr(ord('a') + $col);
+ my $y = 8 - $row;
+ push @moves, "$x$y";
+ }
+ return "@moves";
+ }
+
+ sub str {
+ my($self) = @_;
+ my $ret = " a b c d e f g h\n";
+ for my $row (0..7) {
+ my $y = 8 - $row;
+ $ret .= "$y ";
+ for my $col (0..7) {
+ if (exists $self->treasures->{"$row$col"}) {
+ $ret .= "x ";
+ }
+ elsif ($self->board->[$row][$col]) {
+ $ret .= "N ";
+ }
+ else {
+ $ret .= "* ";
+ }
+ }
+ $ret .= "$y\n";
+ }
+ $ret .= " a b c d e f g h\n";
+ $ret .= $self->path_str . "\n";
+
+ return $ret;
+ }
+
+}
+
+sub solve {
+ my($board) = @_;
+
+ my @queue = clone($board);
+ while (@queue) {
+ $board = shift @queue;
+ if (%{$board->treasures} == 0) { # all treasures found
+ return $board;
+ }
+ else {
+ my @next = $board->next_possible_moves;
+ # if any matches a treasure, move it forward
+ for (0..$#next) {
+ my($row, $col) = @{$next[$_]};
+ if (exists $board->treasures->{"$row$col"}) {
+ @next = ($next[$_], @next[0..$_-1], @next[$_+1..$#next]);
+ last;
+ }
+ }
+
+ for (@next) {
+ my($row, $col) = @$_;
+ my $new_board = clone($board);
+ $new_board->board->[$row][$col] = 1;
+ push @{$new_board->path}, [$row, $col];
+ delete $new_board->treasures->{"$row$col"};
+
+ push @queue, $new_board;
+ }
+ }
+ }
+ die "no solution found\n";
+}
+
+my $board = Board->new;
+$board->parse;
+$board = solve($board);
+say $board->path_str;
diff --git a/challenge-118/paulo-custodio/t/test-1.yaml b/challenge-118/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..bdb0c9139c
--- /dev/null
+++ b/challenge-118/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,10 @@
+- setup:
+ cleanup:
+ args: 5
+ input:
+ output: 1
+- setup:
+ cleanup:
+ args: 4
+ input:
+ output: 0
diff --git a/challenge-118/paulo-custodio/t/test-2.yaml b/challenge-118/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..d3149a283f
--- /dev/null
+++ b/challenge-118/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,15 @@
+- setup:
+ cleanup:
+ args:
+ input: |
+ | 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
+ output: a8 c7 a6 b8 d7 f8 h7 g5 h3 g1 e2 c1 a2 b4 c2 a1 b3 a5 b7 d8 e6 c5 a4 b2 d1 c3 b1 a3 b5 a7 c8 b6 c4
diff --git a/challenge-118/paulo-custodio/test.pl b/challenge-118/paulo-custodio/test.pl
new file mode 100644
index 0000000000..ba6c37260b
--- /dev/null
+++ b/challenge-118/paulo-custodio/test.pl
@@ -0,0 +1,4 @@
+#!/usr/bin/env perl
+use Modern::Perl;
+use Test::More;
+require '../../challenge-001/paulo-custodio/test.pl';