aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2021-08-23 01:52:14 +1000
committerPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2021-08-23 01:52:14 +1000
commitba85d6ddb9fd62909f68ff8d22558b1a0b741024 (patch)
treefe87bd1f3abf4095185eccefca74a525630e97da
parente7c5bbc5e9ae19d558b0b000958e19eb6c47416b (diff)
downloadperlweeklychallenge-club-ba85d6ddb9fd62909f68ff8d22558b1a0b741024.tar.gz
perlweeklychallenge-club-ba85d6ddb9fd62909f68ff8d22558b1a0b741024.tar.bz2
perlweeklychallenge-club-ba85d6ddb9fd62909f68ff8d22558b1a0b741024.zip
Perl & Raku solutions to Task 2 of the Perl Weekly Challenge #126
-rw-r--r--challenge-126/athanasius/perl/Example.txt5
-rw-r--r--challenge-126/athanasius/perl/ch-2.pl201
-rw-r--r--challenge-126/athanasius/raku/Example.txt5
-rw-r--r--challenge-126/athanasius/raku/ch-2.raku187
4 files changed, 398 insertions, 0 deletions
diff --git a/challenge-126/athanasius/perl/Example.txt b/challenge-126/athanasius/perl/Example.txt
new file mode 100644
index 0000000000..e211219443
--- /dev/null
+++ b/challenge-126/athanasius/perl/Example.txt
@@ -0,0 +1,5 @@
+x * * * x * x x x x
+* * * * * * * * * x
+* * * * x * x * x *
+* * * x x * * * * *
+x * * * x * * * * x
diff --git a/challenge-126/athanasius/perl/ch-2.pl b/challenge-126/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..3bb5a5317d
--- /dev/null
+++ b/challenge-126/athanasius/perl/ch-2.pl
@@ -0,0 +1,201 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 126
+=========================
+
+TASK #2
+-------
+*Minesweeper Game*
+
+Submitted by: Cheok-Yin Fung
+
+You are given a rectangle with points marked with either x or *. Please
+consider the x as a land mine.
+
+Write a script to print a rectangle with numbers and x as in the Minesweeper
+game.
+
+A number in a square of the minesweeper game indicates the number of mines
+within the neighbouring squares (usually 8), also implies that there are no
+bombs on that square.
+
+Example
+
+ Input:
+ x * * * x * x x x x
+ * * * * * * * * * x
+ * * * * x * x * x *
+ * * * x x * * * * *
+ x * * * x * * * * x
+
+ Output:
+ x 1 0 1 x 2 x x x x
+ 1 1 0 2 2 4 3 5 5 x
+ 0 0 1 3 x 3 x 2 x 2
+ 1 1 1 x x 4 1 2 2 2
+ x 1 1 3 x 2 0 0 1 x
+
+=cut
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2021 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast;
+
+const my $FILE => 'Example.txt';
+const my $MINE => 'x';
+const my $EMPTY => '*';
+const my $USAGE =>
+"Usage:
+ perl $0 [<file>]
+
+ [<file>] The name of a file containing a Minesweeper starting grid\n";
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 126, Task #2: Minesweeper Game (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ my $file = parse_command_line();
+ my @in_grid = read_in_the_grid( $file );
+
+ print "Input from $file:\n";
+ printf " %s\n", join ' ', @$_ for @in_grid;
+
+ my @out_grid = number_the_grid( @in_grid );
+
+ print "\nOutput:\n";
+ printf " %s\n", join ' ', @$_ for @out_grid;
+}
+
+#------------------------------------------------------------------------------
+sub read_in_the_grid
+#------------------------------------------------------------------------------
+{
+ my ($file) = @_;
+ my @grid;
+
+ open( my $fh, '<', $file )
+ or die qq[Cannot open file "$file" for reading, stopped];
+
+ while (my $line = <$fh>)
+ {
+ $line =~ s/ \s+ //gx;
+
+ push @grid, [ split '', $line ];
+ }
+
+ close $fh
+ or die qq[Cannot close file "$file", stopped];
+
+ scalar @grid > 0
+ or error( 'Empty grid' );
+
+ my $width = scalar @{ $grid[ 0 ] };
+
+ $width > 0
+ or error( 'Empty first row' );
+
+ for my $row (0 .. $#grid)
+ {
+ scalar @{ $grid[ $row ] } == $width
+ or error( 'The grid is not a rectangle' );
+
+ for my $col (0 .. $#{ $grid[ $row ] })
+ {
+ my $point = $grid[ $row ][ $col ];
+
+ $point eq $MINE || $point eq $EMPTY
+ or error( qq["$point" is not a valid input character] );
+ }
+ }
+
+ return @grid;
+}
+
+#------------------------------------------------------------------------------
+sub number_the_grid
+#------------------------------------------------------------------------------
+{
+ my @in_grid = @_;
+
+ my $max_row = $#in_grid;
+ my $max_col = $#{ $in_grid[ 0 ] };
+ my @out_grid;
+
+ push @out_grid, [ (0) x ($max_col + 1) ] for 0 .. $max_row;
+
+ for my $row (0 .. $max_row)
+ {
+ for my $col (0 .. $max_col)
+ {
+ if ($in_grid[ $row ][ $col ] eq $MINE)
+ {
+ $out_grid[ $row ][ $col ] = $MINE;
+ }
+ else
+ {
+ my $count = 0;
+
+ for my $r ($row - 1 .. $row + 1)
+ {
+ next if $r < 0 || $r > $max_row;
+
+ for my $c ($col - 1 .. $col + 1)
+ {
+ next if $r == $row && $c == $col ||
+ $c < 0 || $c > $max_col;
+
+ ++$count if $in_grid[ $r ][ $c ] eq $MINE;
+ }
+ }
+
+ $out_grid[ $row ][ $col ] = $count if $count;
+ }
+ }
+ }
+
+ return @out_grid;
+}
+
+#------------------------------------------------------------------------------
+sub parse_command_line
+#------------------------------------------------------------------------------
+{
+ my $args = scalar @ARGV;
+ $args == 0 || $args == 1
+ or error( "Expected 0 or 1 command line arguments, found $args" );
+
+ my $file = $args ? $ARGV[ 0 ] : $FILE;
+
+ -e $file or error( qq[File "$file" does not exist] );
+ -s $file or error( qq[File "$file" is empty] );
+ -f $file or error( qq[File "$file" is not a plain file] );
+
+ return $file;
+}
+
+#------------------------------------------------------------------------------
+sub error
+#------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+###############################################################################
diff --git a/challenge-126/athanasius/raku/Example.txt b/challenge-126/athanasius/raku/Example.txt
new file mode 100644
index 0000000000..e211219443
--- /dev/null
+++ b/challenge-126/athanasius/raku/Example.txt
@@ -0,0 +1,5 @@
+x * * * x * x x x x
+* * * * * * * * * x
+* * * * x * x * x *
+* * * x x * * * * *
+x * * * x * * * * x
diff --git a/challenge-126/athanasius/raku/ch-2.raku b/challenge-126/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..e74fd5e1cc
--- /dev/null
+++ b/challenge-126/athanasius/raku/ch-2.raku
@@ -0,0 +1,187 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 126
+=========================
+
+TASK #2
+-------
+*Minesweeper Game*
+
+Submitted by: Cheok-Yin Fung
+
+You are given a rectangle with points marked with either x or *. Please
+consider the x as a land mine.
+
+Write a script to print a rectangle with numbers and x as in the Minesweeper
+game.
+
+A number in a square of the minesweeper game indicates the number of mines
+within the neighbouring squares (usually 8), also implies that there are no
+bombs on that square.
+
+Example
+
+ Input:
+ x * * * x * x x x x
+ * * * * * * * * * x
+ * * * * x * x * x *
+ * * * x x * * * * *
+ x * * * x * * * * x
+
+ Output:
+ x 1 0 1 x 2 x x x x
+ 1 1 0 2 2 4 3 5 5 x
+ 0 0 1 3 x 3 x 2 x 2
+ 1 1 1 x x 4 1 2 2 2
+ x 1 1 3 x 2 0 0 1 x
+
+=end comment
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2021 PerlMonk Athanasius #
+#--------------------------------------#
+
+my Str constant $FILE = 'Example.txt';
+my Str constant $MINE = 'x';
+my Str constant $EMPTY = '*';
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ "\nChallenge 126, Task #2: Minesweeper Game (Raku)\n".put;
+}
+
+#==============================================================================
+sub MAIN
+(
+ #| The name of a file containing a Minesweeper starting grid
+
+ Str:D $file where *.IO.f = $FILE
+)
+#==============================================================================
+{
+ my Array[Str] @in-grid = read-in-the-grid( $file );
+
+ "Input from $file:".put;
+ " %s\n".printf: .join: ' ' for @in-grid;
+
+ my Array[Str] @out-grid = number-the-grid( @in-grid );
+
+ "\nOutput:".put;
+ " %s\n".printf: .join: ' ' for @out-grid;
+}
+
+#------------------------------------------------------------------------------
+sub read-in-the-grid
+(
+ Str:D $file #= Input file
+--> Array:D[Array:D[Str:D]] #= Input grid
+)
+#------------------------------------------------------------------------------
+{
+ my Array[Str] @grid;
+
+ for $file.IO.lines -> Str $line is copy
+ {
+ $line ~~ s:g/ \s+ //;
+
+ @grid.push: Array[Str].new: $line.split: '', :skip-empty;
+ }
+
+ @grid.elems > 0 or error( 'Empty grid' );
+
+ my UInt $width = @grid[ 0 ].elems;
+
+ $width > 0 or error( 'Empty first row' );
+
+ for 0 .. @grid.end -> UInt $row
+ {
+ @grid[ $row ].elems == $width
+ or error( 'The grid is not a rectangle' );
+
+ for 0 .. @grid[ $row ].end -> UInt $col
+ {
+ my Str $point = @grid[ $row; $col ];
+
+ $point eq $MINE || $point eq $EMPTY
+ or error( qq["$point" is not a valid input character] );
+ }
+ }
+
+ return @grid;
+}
+
+#------------------------------------------------------------------------------
+sub number-the-grid
+(
+ Array:D[Array:D[Str:D]] $in-grid #= Input grid
+--> Array:D[Array:D[Str:D]] #= Output grid
+)
+#------------------------------------------------------------------------------
+{
+ my UInt $max-row = $in-grid.end;
+ my UInt $max-col = $in-grid[ 0 ].end;
+ my Array[Str] @out-grid;
+
+ @out-grid.push: Array[Str].new: '0' xx ($max-col + 1) for 0 .. $max-row;
+
+ for 0 .. $max-row -> UInt $row
+ {
+ for 0 .. $max-col -> UInt $col
+ {
+ if $in-grid[ $row; $col ] eq $MINE
+ {
+ @out-grid[ $row; $col ] = $MINE;
+ }
+ else
+ {
+ my UInt $count = 0;
+
+ for $row - 1 .. $row + 1 -> Int $r
+ {
+ next if $r < 0 || $r > $max-row;
+
+ for $col - 1 .. $col + 1 -> Int $c
+ {
+ next if $r == $row && $c == $col ||
+ $c < 0 || $c > $max-col;
+
+ ++$count if $in-grid[ $r; $c ] eq $MINE;
+ }
+ }
+
+ @out-grid[ $row; $col ] = $count.Str if $count;
+ }
+ }
+ }
+
+ return @out-grid;
+}
+
+#------------------------------------------------------------------------------
+sub error( Str:D $message )
+#------------------------------------------------------------------------------
+{
+ "ERROR: $message".put;
+
+ USAGE();
+
+ exit;
+}
+
+#------------------------------------------------------------------------------
+sub USAGE()
+#------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+##############################################################################