diff options
| author | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-05-25 14:12:17 +0100 |
|---|---|---|
| committer | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-05-25 14:12:17 +0100 |
| commit | 32397cd7396185b9eaf93c8a453f6f3138c4461e (patch) | |
| tree | c95356a87d372f7a26f00cf113e1a25d092fcc48 /challenge-062/javier-luque/perl | |
| parent | b5c6faa68920292067b66e267a6ac99293beafdf (diff) | |
| download | perlweeklychallenge-club-32397cd7396185b9eaf93c8a453f6f3138c4461e.tar.gz perlweeklychallenge-club-32397cd7396185b9eaf93c8a453f6f3138c4461e.tar.bz2 perlweeklychallenge-club-32397cd7396185b9eaf93c8a453f6f3138c4461e.zip | |
- Added solutions by Javier Luque.
Diffstat (limited to 'challenge-062/javier-luque/perl')
| -rw-r--r-- | challenge-062/javier-luque/perl/ch-1.pl | 53 | ||||
| -rw-r--r-- | challenge-062/javier-luque/perl/ch-2.pl | 175 |
2 files changed, 228 insertions, 0 deletions
diff --git a/challenge-062/javier-luque/perl/ch-1.pl b/challenge-062/javier-luque/perl/ch-1.pl new file mode 100644 index 0000000000..a5cfe59990 --- /dev/null +++ b/challenge-062/javier-luque/perl/ch-1.pl @@ -0,0 +1,53 @@ +#!/usr/bin/perl +# Test: ./ch-1.pl -u +use strict; +use warnings; +use feature qw /say/; +use Getopt::Long; + +# Unique flag +my $unique; +GetOptions ("unique" => \$unique); + +# Hash to store unique emails +my %unique_emails; + +# Data +my @data = qw / + name@example.org + rjt@cpan.org + Name@example.org + rjt@CPAN.org + user@alpha.example.org +/; + +my @sorted_data = sort by_domain @data; +@sorted_data = grep { make_unique($_) } @sorted_data + if ($unique); +say join "\n", @sorted_data; + +# Check if the email is unique +sub make_unique { + my $email = shift; + my ($user, $domain) = split_email($email); + my $unique_email = $user . '@' . lc($domain); + + return 0 + if ($unique_emails{$unique_email}); + + $unique_emails{$unique_email} = 1; + return 1; +} + +# Sort by domain function +sub by_domain { + my ($user_a, $domain_a) = split ('\@', $::a); + my ($user_b, $domain_b) = split ('\@', $::b); + lc($domain_a) cmp lc($domain_b) or + $user_a cmp $user_b; +} + +# Split email into username and domain +sub split_email { + return split ('\@', shift); +} diff --git a/challenge-062/javier-luque/perl/ch-2.pl b/challenge-062/javier-luque/perl/ch-2.pl new file mode 100644 index 0000000000..aedfe1e3db --- /dev/null +++ b/challenge-062/javier-luque/perl/ch-2.pl @@ -0,0 +1,175 @@ +#!/usr/bin/perl +# Test: ./ch-2.pl +use strict; +use warnings; +use feature qw /say/; + +# Size of board +my $size = $ARGV[0] || 6; + +# Store best solution +our $bs_board = init_board( $size ); +our $bs_queen_count = 0; + +# Our Playing board +my $board = init_board( $size ); +if (nqueens($board, 0, 0, 0)) { + say "Real Solution:\n"; + say display_board($board); +} else { + say "Best Solution:\n"; + say display_board($bs_board); +} + +# Nqueens algorithm +sub nqueens { + my ($board, $next_z, $next_col, $placed) = @_; + my $size = scalar(@$board); + my $index = $next_z * $size + $next_col; + + # We found a solution + return 1 + if $index > ($size * $size) - 1 ; + + # We've moved to the next level + if ($next_col > $size - 1) { + $next_z++; + $next_col -= $size; + }; + + # Backtrack till we find a solution + for my $row (0 .. $size - 1) { + if (valid_placement($board, $size, $next_z, $row, $next_col)) { + $board->[$next_z]->[$row]->[$next_col] = 1; + + # Queen placed + $placed++; + + # Current best solution + if ($bs_queen_count < $placed) { + copy_board($board, $bs_board); + $bs_queen_count = $placed; + } + + # Solution found + return 1 + if (nqueens($board, $next_z, $next_col + 1, $placed)); + + # Backtrack + $placed--; + $board->[$next_z]->[$row]->[$next_col] = 0; + } + } + + # If we get here there is no + # possible solution to this chain + return 0; +} + +# Check valid placements +sub valid_placement { + my ($board, $size, $height, $row, $col) = @_; + + # Check rows + for (my $i = 0; $i < $col; $i++) { + return 0 + if ($board->[$height]->[$row]->[$i]); + } + + # Check 2d upper left diagonals + my $i = $row; my $j = $col; + while ($i >= 0 && $j >= 0) { + return 0 + if ($board->[$height]->[$i]->[$j]); + $i--; $j--; + } + + # Check 2d lower right + $i = $row; $j = $col; + while ($i <= $size && $j >= 0) { + return 0 + if ($board->[$height]->[$i]->[$j]); + $i++; $j--; + } + + # Check lower z + for (my $k = $height - 1; $k >= 0; $k--) { + my $range = $height - $k; + + for my $i (-$range, 0, $range) { + for my $j (-$range, 0, $range) { + my $a = $row + $i ; + my $b = $col + $j; + + # Out of bound; + next if ($a < 0 || $b < 0); + next if ($a >= $size || $b >= $size); + + return 0 + if ($board->[$k]->[$a]->[$b]); + } + } + } + + + # Return true if we don't + # collide with another queen + return 1; +} + +# Initializes the board +sub init_board { + my $size = (shift) - 1; + my @board; + + for my $i (0 .. $size) { + for my $j (0 .. $size) { + for my $k (0 .. $size) { + $board[$i][$j][$k] = 0; + } + } + } + + return \@board; +} + +# Displays the board +sub display_board { + my $board = shift; + my $size = scalar (@$board); + + # Store the board string into $b + my $b; + for my $k (0 .. $size - 1) { + $b .= "z = $k\n"; + $b .= '|' . '-' x (4 * $size - 1) . '|' . "\n"; + for my $i (0 .. $size - 1) { + $b .= '|'; + for my $j (0 .. $size - 1) { + my $space = ($board->[$k]->[$i]->[$j] == 1) ? + '*' : ' '; + $b .= " $space |" + } + $b .= "\n"; + } + $b .= '|' . '-' x (4 * $size - 1) . '|' . "\n\n"; + } + + # Return the board representation + return $b; +} + +# Copy board +sub copy_board { + my ($src, $copy) = @_; + my $size = scalar(@$src) - 1; + + for my $i (0 .. $size) { + for my $j (0 .. $size) { + for my $k (0 .. $size) { + $copy->[$i]->[$j]->[$k] = + $src->[$i]->[$j]->[$k]; + } + } + } +} |
