# RabbitFarm

### 2021-08-22

#### Count Numbers / MineSweeper game: The Weekly Challenge 126

The examples used here are from The Weekly Challenge problem statement and demonstrate the working solution.

## Part 1

You are given a positive integer \$N. Write a script to print count of numbers from 1 to \$N that donâ€™t contain digit 1.

### Solution

``````
use strict;
use warnings;
sub has_1{
my(\$x) = @_;
return 1 if \$x =~ tr/1//d > 0;
return 0;
}

sub count_with_1{
my(\$n) = @_;
my \$x = 1;
my \$count = 0;
{
\$count += has_1(\$x);
\$x += 1;
redo if \$x <= \$n;
}
return \$count;
}

sub count_without_1{
my(\$n) = @_;
return \$n - count_with_1(\$n);
}

MAIN:{
my \$N;
\$N = 15;
print count_without_1(\$N) . "\n";
\$N = 25;
print count_without_1(\$N) . "\n";
}
``````

### Sample Run

``````
\$ perl perl/ch-1.pl
8
13
``````

### Notes

Given the flexibility and richness of Perl there were many choices of how to determine the presence of a '1'. I decided to use `tr` which will helpfully return the number of changes made. In this case, what is returned is the number of 1's deleted. If this number is greater than zero then we know a `1` was found.

## Part 2

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.

### Solution

``````
use strict;
use warnings;
sub initialize_grid{
my(\$m, \$n) = @_;
my @grid;
for my \$i (0 .. \$m - 1){
for my \$j (0 .. \$n - 1){
\$grid[\$i][\$j] = "*";
\$grid[\$i][\$j] = "x" if rand() <= (1 / 3);
}
}
return @grid;
}

sub make_grid{
my(\$m, \$n) = @_;
my @initial_grid = initialize_grid(\$m, \$n);
my @grid = map {[@\$_]} @initial_grid;
for my \$i (0 .. \$m - 1){
for my \$j (0 .. \$n - 1){
unless(\$grid[\$i][\$j] eq "x"){
my \$mine_count = 0;
\$mine_count++ if \$i >= 1 && \$j >= 1 && \$grid[\$i - 1][\$j - 1] eq "x";
\$mine_count++ if \$i >= 1 && \$grid[\$i - 1][\$j] eq "x";
\$mine_count++ if \$i >=1 && \$j < \$n - 1 && \$grid[\$i - 1][\$j + 1] eq "x";
\$mine_count++ if \$j >= 1 && \$grid[\$i][\$j - 1] eq "x";
\$mine_count++ if \$j < \$n - 1 && \$grid[\$i][\$j + 1] eq "x";
\$mine_count++ if \$i < \$m - 1 && \$j >= 1 && \$grid[\$i + 1][\$j - 1] eq "x";
\$mine_count++ if \$i < \$m - 1 && \$grid[\$i + 1][\$j] eq "x" ;
\$mine_count++ if \$i < \$m - 1 && \$j < \$n - 1 && \$grid[\$i + 1][\$j + 1] eq "x";
\$grid[\$i][\$j] = \$mine_count;
}
}
}
return (\@initial_grid, \@grid);
}

sub print_grid{
my @grid = @_;
for my \$row (@grid){
print "\t" . join(" ", @{\$row}) . "\n"
}
}

MAIN:{
my(\$m, \$n) = @ARGV;
my(\$initial_grid, \$grid) = make_grid(\$m, \$n);
print "Input:\n";
print_grid(@{\$initial_grid});
print "Output:\n";
print_grid(@{\$grid});
}
``````

### Sample Run

``````
\$ perl perl/ch-2.pl 5 10
Input:
x x * * * * x * * x
* * x * x x x * x *
* * * * * * * * * *
x * x x * * * * * x
* * x * x * * * x *
Output:
x x 2 2 2 4 x 3 2 x
2 3 x 2 x x x 3 x 2
1 3 3 4 3 3 2 2 2 2
x 3 x x 2 1 0 1 2 x
1 3 x 4 x 1 0 1 x 2
``````

### Notes

• The grid is randomly determined. Any cell has a 1/3 chance of being a mine.

• The code for finding all adjacent cells, if they exist, is largely taken from my solution to Challenge 077.

• Once the tedious business of finding the adjacent cells is done counting up the "mines" and labelling the cells is straightforward!

## References

Challenge 126

C++ solution for Part 1

C++ solution for Part 2

History of Minesweeper

posted at: 17:39 by: Adam Russell | path: /perl | permanent link to this entry