diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-08-22 17:12:16 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-22 17:12:16 +0100 |
| commit | 5b613de45f45ec32cc4417a9f637bcb574152a23 (patch) | |
| tree | fe87bd1f3abf4095185eccefca74a525630e97da | |
| parent | e7c5bbc5e9ae19d558b0b000958e19eb6c47416b (diff) | |
| parent | ba85d6ddb9fd62909f68ff8d22558b1a0b741024 (diff) | |
| download | perlweeklychallenge-club-5b613de45f45ec32cc4417a9f637bcb574152a23.tar.gz perlweeklychallenge-club-5b613de45f45ec32cc4417a9f637bcb574152a23.tar.bz2 perlweeklychallenge-club-5b613de45f45ec32cc4417a9f637bcb574152a23.zip | |
Merge pull request #4760 from PerlMonk-Athanasius/branch-for-challenge-126
Perl & Raku solutions to Task 2 of the Perl Weekly Challenge #126
| -rw-r--r-- | challenge-126/athanasius/perl/Example.txt | 5 | ||||
| -rw-r--r-- | challenge-126/athanasius/perl/ch-2.pl | 201 | ||||
| -rw-r--r-- | challenge-126/athanasius/raku/Example.txt | 5 | ||||
| -rw-r--r-- | challenge-126/athanasius/raku/ch-2.raku | 187 |
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; +} + +############################################################################## |
