diff options
| author | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2025-08-23 11:42:29 +1000 |
|---|---|---|
| committer | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2025-08-23 11:42:29 +1000 |
| commit | fdd4f0381c39b40614795ab0e17577ff0ac632fe (patch) | |
| tree | 075859152d569361a85b717469ab1e6f52c18b40 | |
| parent | 89c11ad8c143a56322780e2bbdfeddd09951a749 (diff) | |
| download | perlweeklychallenge-club-fdd4f0381c39b40614795ab0e17577ff0ac632fe.tar.gz perlweeklychallenge-club-fdd4f0381c39b40614795ab0e17577ff0ac632fe.tar.bz2 perlweeklychallenge-club-fdd4f0381c39b40614795ab0e17577ff0ac632fe.zip | |
Perl & Raku solutions to Tasks 1 & 2 for Week 335
| -rw-r--r-- | challenge-335/athanasius/perl/ch-1.pl | 174 | ||||
| -rw-r--r-- | challenge-335/athanasius/perl/ch-2.pl | 295 | ||||
| -rw-r--r-- | challenge-335/athanasius/raku/ch-1.raku | 164 | ||||
| -rw-r--r-- | challenge-335/athanasius/raku/ch-2.raku | 294 |
4 files changed, 927 insertions, 0 deletions
diff --git a/challenge-335/athanasius/perl/ch-1.pl b/challenge-335/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..46192cdbc8 --- /dev/null +++ b/challenge-335/athanasius/perl/ch-1.pl @@ -0,0 +1,174 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 335 +========================= + +TASK #1 +------- +*Common Characters* + +Submitted by: Mohammad Sajid Anwar + +You are given an array of words. + +Write a script to return all characters that is in every word in the given array +including duplicates. + +Example 1 + + Input: @words = ("bella", "label", "roller") + Output: ("e", "l", "l") + +Example 2 + + Input: @words = ("cool", "lock", "cook") + Output: ("c", "o") + +Example 3 + + Input: @words = ("hello", "world", "pole") + Output: ("l", "o") + +Example 4 + + Input: @words = ("abc", "def", "ghi") + Output: () + +Example 5 + + Input: @words = ("aab", "aac", "aaa") + Output: ("a", "a") + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A list of words is entered on the command-line. + +=cut +#=============================================================================== + +use v5.32; # Enables strictures +use warnings; +use Const::Fast; +use Set::Bag; +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 [<words> ...] + perl $0 + + [<words> ...] A list of words +END +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 335, Task #1: Common Characters (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my @words = @ARGV; + + printf "Input: \@words = (%s)\n", join ', ', map { qq["$_"] } @words; + + my $common = find_common_chars( \@words ); + + printf "Output: (%s)\n", join ', ', map { qq["$_"] } @$common; + } +} + +#------------------------------------------------------------------------------- +sub find_common_chars +#------------------------------------------------------------------------------- +{ + my ($words) = @_; + my $shared = Set::Bag->new; + + if (scalar @$words > 0) + { + $shared->insert( $_ => 1 ) for split //, $words->[ 0 ]; + + for my $i (1 .. $#$words) + { + my $chars = Set::Bag->new; + $chars->insert( $_ => 1 ) for split //, $words->[ $i ]; + + $shared = $shared & $chars; # Keep only the intersection + } + } + + my @common; + push @common, ($_) x $shared->grab( $_ ) for sort $shared->elements; + + return \@common; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $words_str, $exp_str) = split / \| /x, $line; + + for ($test_name, $words_str, $exp_str) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @words = split / \s+ /x, $words_str; + my $common = find_common_chars( \@words ); + my @expected = split / \s+ /x, $exp_str; + + is_deeply $common, \@expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|bella label roller|e l l +Example 2|cool lock cook |c o +Example 3|hello world pole |l o +Example 4|abc def ghi | +Example 5|aab aac aaa |a a diff --git a/challenge-335/athanasius/perl/ch-2.pl b/challenge-335/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..2eaebea10a --- /dev/null +++ b/challenge-335/athanasius/perl/ch-2.pl @@ -0,0 +1,295 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 335 +========================= + +TASK #2 +------- +*Find Winner* + +Submitted by: Mohammad Sajid Anwar + +You are given an array of all moves by the two players. + +Write a script to find the winner of the TicTacToe game if found based on the +moves provided in the given array. + +UPDATE: Order move is in the order - A, B, A, B, A, …. + +Example 1 + + Input: @moves = ([0,0],[2,0],[1,1],[2,1],[2,2]) + Output: A + + Game Board: + [ A _ _ ] + [ B A B ] + [ _ _ A ] + +Example 2 + + Input: @moves = ([0,0],[1,1],[0,1],[0,2],[1,0],[2,0]) + Output: B + + Game Board: + [ A A B ] + [ A B _ ] + [ B _ _ ] + +Example 3 + + Input: @moves = ([0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2]) + Output: Draw + + Game Board: + [ A A B ] + [ B B A ] + [ A B A ] + +Example 4 + + Input: @moves = ([0,0],[1,1]) + Output: Pending + + Game Board: + [ A _ _ ] + [ _ B _ ] + [ _ _ _ ] + +Example 5 + + Input: @moves = ([1,1],[0,0],[2,2],[0,1],[1,0],[0,2]) + Output: B + + Game Board: + [ B B B ] + [ A A _ ] + [ _ _ A ] + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A non-empty list of move coordinates (0, 1, or 2) is entered on the command- + line. For example, the moves [0,0],[1,1] are entered as follows: + + >perl ch-2.pl 0 0 1 1 + +Assumptions +----------- +1. A move to a square already filled is an error, as is a move to a nonexistent + square. +2. Even if it is not winnable, a game is not considered Drawn until all the + squares have been filled. +3. Once the game has been decided (won or drawn), any further moves are simply + ignored. +4. The Game Board for Example 1 is incorrect; it should be: + [ A _ _ ] + [ _ A _ ] + [ B B A ] + +=cut +#=============================================================================== + +use v5.32; # Enables strictures +use warnings; +use Const::Fast; +use List::Util qw( pairs ); +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 [<coords> ...] + perl $0 + + [<coords> ...] List of move coordinates, e.g., 0 0 2 0 1 1 2 1 2 2 +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 335, Task #2: Find Winner (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + + if ($argc == 0) + { + run_tests(); + } + elsif ($argc % 2 == 1) + { + error( 'Expected an even number of command-line arguments, found ' . + $argc ); + } + else + { + my @coords = @ARGV; + + / ^ [012] $ /x or error( qq[Invalid coordinate "$_"] ) for @coords; + + my @moves = get_moves( \@coords ); + + printf "Input: \@moves = (%s)\n", + join ', ', map { '[' . join( ', ', @$_ ) . ']' } @moves; + + my ($winner, $grid) = find_winner( \@moves ); + + print "Output: $winner\n\nGame Board:\n"; + + printf "[ %s %s %s ]\n", @$_ for @$grid; + } +} + +#------------------------------------------------------------------------------- +sub find_winner +#------------------------------------------------------------------------------- +{ + my ($moves) = @_; + my $winner = 'Pending'; + my $player = 'A'; + my @grid; + push @grid, [ ('_') x 3 ] for 1 .. 3; + + for my $move (@$moves) + { + my ($row, $col) = @$move; + + if ($grid[ $row ][ $col ] eq '_') + { + $grid[ $row ][ $col ] = $player; + } + else + { + die "\nERROR: Illegal move: [$row, $col]\n"; + } + + $winner = check_grid( \@grid ); + + last unless $winner eq 'Pending'; + + $player = $player eq 'A' ? 'B' : 'A'; + } + + return ($winner, \@grid); +} + +#------------------------------------------------------------------------------- +sub check_grid +#------------------------------------------------------------------------------- +{ + my ($grid) = @_; + + # Has the game been won? Test columns first, then rows, then diagonals + + for my $coords ([ 0, 0, 0, 1, 0, 2 ], [ 1, 0, 1, 1, 1, 2 ], + [ 2, 0, 2, 1, 2, 2 ], [ 0, 0, 1, 0, 2, 0 ], + [ 0, 1, 1, 1, 2, 1 ], [ 0, 2, 1, 2, 2, 2 ], + [ 0, 0, 1, 1, 2, 2 ], [ 0, 2, 1, 1, 2, 0 ]) + { + if (line_complete( $coords, $grid )) + { + return $grid->[ $coords->[ 0 ] ][ $coords->[ 1 ] ]; # Winner + } + } + + # No winner yet; is the game drawn? + + for my $i (0 .. 2) + { + for my $j (0 .. 2) + { + return 'Pending' if $grid->[ $i ][ $j ] eq '_'; # No + } + } + + return 'Draw'; # Yes +} + +#------------------------------------------------------------------------------- +sub line_complete +#------------------------------------------------------------------------------- +{ + my ($coords, $grid) = @_; + + my $square_a = $grid->[ $coords->[ 0 ] ][ $coords->[ 1 ] ]; + my $square_b = $grid->[ $coords->[ 2 ] ][ $coords->[ 3 ] ]; + my $square_c = $grid->[ $coords->[ 4 ] ][ $coords->[ 5 ] ]; + + return ($square_a eq 'A' || $square_a eq 'B') && + $square_a eq $square_b && + $square_a eq $square_c; +} + +#------------------------------------------------------------------------------- +sub get_moves +#------------------------------------------------------------------------------- +{ + my ($coords) = @_; + + return map { [ @$_ ] } pairs @$coords; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $moves_str, $expected) = split / \| /x, $line; + + for ($test_name, $moves_str, $expected) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @coords = split / [\s,]+ /x, $moves_str; + my @moves = get_moves ( \@coords ); + my ($winner, undef) = find_winner( \@moves ); + + is $winner, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|0,0 2,0 1,1 2,1 2,2 |A +Example 2|0,0 1,1 0,1 0,2 1,0 2,0 |B +Example 3|0,0 1,1 2,0 1,0 1,2 2,1 0,1 0,2 2,2|Draw +Example 4|0,0 1,1 |Pending +Example 5|1,1 0,0 2,2 0,1 1,0 0,2 |B diff --git a/challenge-335/athanasius/raku/ch-1.raku b/challenge-335/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..138dc06561 --- /dev/null +++ b/challenge-335/athanasius/raku/ch-1.raku @@ -0,0 +1,164 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 335 +========================= + +TASK #1 +------- +*Common Characters* + +Submitted by: Mohammad Sajid Anwar + +You are given an array of words. + +Write a script to return all characters that is in every word in the given array +including duplicates. + +Example 1 + + Input: @words = ("bella", "label", "roller") + Output: ("e", "l", "l") + +Example 2 + + Input: @words = ("cool", "lock", "cook") + Output: ("c", "o") + +Example 3 + + Input: @words = ("hello", "world", "pole") + Output: ("l", "o") + +Example 4 + + Input: @words = ("abc", "def", "ghi") + Output: () + +Example 5 + + Input: @words = ("aab", "aac", "aaa") + Output: ("a", "a") + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A list of words is entered on the command-line. + +=end comment +#=============================================================================== + +use Test; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 335, Task #1: Common Characters (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + *@words where { .all ~~ Str:D } #= A list of words +) +#=============================================================================== +{ + "Input: @words = (%s)\n".printf: @words\.map( { qq["$_"] } ).join: ', '; + + my Str @common = find-common-chars( @words ); + + "Output: (%s)\n"\ .printf: @common.map( { qq["$_"] } ).join: ', '; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub find-common-chars( List:D[Str:D] $words --> List:D[Str:D] ) +#------------------------------------------------------------------------------- +{ + my BagHash $common = BagHash.new; + + if $words.elems > 0 + { + $common.add( $_ ) for $words[ 0 ].split: '', :skip-empty; + + for 1 .. $words.end -> UInt $i + { + my Bag $chars = Bag.new: $words[ $i ].split: '', :skip-empty; + + $common ∩= $chars; # Keep only the intersection + } + } + + return $common ?? |$common.kxxv.sort !! (); +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $words-str, $exp-str) = $line.split: / \| /; + + for $test-name, $words-str, $exp-str + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Str @words = $words-str.split: / \s+ /, :skip-empty; + my Str @common = find-common-chars( @words ); + my Str @expected = $exp-str\ .split: / \s+ /, :skip-empty; + + is-deeply @common, @expected, $test-name; + } + + done-testing; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +#------------------------------------------------------------------------------- +sub test-data( --> Str:D ) +#------------------------------------------------------------------------------- +{ + return q:to/END/; + Example 1|bella label roller|e l l + Example 2|cool lock cook |c o + Example 3|hello world pole |l o + Example 4|abc def ghi | + Example 5|aab aac aaa |a a + END +} + +################################################################################ diff --git a/challenge-335/athanasius/raku/ch-2.raku b/challenge-335/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..6f69443cb8 --- /dev/null +++ b/challenge-335/athanasius/raku/ch-2.raku @@ -0,0 +1,294 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 335 +========================= + +TASK #2 +------- +*Find Winner* + +Submitted by: Mohammad Sajid Anwar + +You are given an array of all moves by the two players. + +Write a script to find the winner of the TicTacToe game if found based on the +moves provided in the given array. + +UPDATE: Order move is in the order - A, B, A, B, A, …. + +Example 1 + + Input: @moves = ([0,0],[2,0],[1,1],[2,1],[2,2]) + Output: A + + Game Board: + [ A _ _ ] + [ B A B ] + [ _ _ A ] + +Example 2 + + Input: @moves = ([0,0],[1,1],[0,1],[0,2],[1,0],[2,0]) + Output: B + + Game Board: + [ A A B ] + [ A B _ ] + [ B _ _ ] + +Example 3 + + Input: @moves = ([0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2]) + Output: Draw + + Game Board: + [ A A B ] + [ B B A ] + [ A B A ] + +Example 4 + + Input: @moves = ([0,0],[1,1]) + Output: Pending + + Game Board: + [ A _ _ ] + [ _ B _ ] + [ _ _ _ ] + +Example 5 + + Input: @moves = ([1,1],[0,0],[2,2],[0,1],[1,0],[0,2]) + Output: B + + Game Board: + [ B B B ] + [ A A _ ] + [ _ _ A ] + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A non-empty list of move coordinates (0, 1, or 2) is entered on the command- + line. For example, the moves [0,0],[1,1] are entered as follows: + + >raku ch-2.raku 0 0 1 1 + +Assumptions +----------- +1. A move to a square already filled is an error, as is a move to a nonexistent + square. +2. Even if it is not winnable, a game is not considered Drawn until all the + squares have been filled. +3. Once the game has been decided (won or drawn), any further moves are simply + ignored. +4. The Game Board for Example 1 is incorrect; it should be: + [ A _ _ ] + [ _ A _ ] + [ B B A ] + +=end comment +#=============================================================================== + +use Test; + +subset Index of Int where 2 >= * >= 0; +subset Move of List where (Index, Index); +subset Square of Str where { $_ eq < A B _ >.any }; +subset Row of List where (Square, Square, Square); +subset Grid of List where (Row, Row, Row); +subset Winner of Str where { $_ eq < A B Draw Pending >.any }; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 335, Task #2: Find Winner (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + #| List of move coordinates, e.g., 0 0 2 0 1 1 2 1 2 2 + + *@coords where { .elems > 0 && .elems %% 2 && .all ~~ Index:D } +) +#=============================================================================== +{ + my Move @moves = get-moves( @coords ); + + "Input: \@moves = (%s)\n".printf: + @moves.map( { '[' ~ .join( ', ' ) ~ ']' } ).join: ', '; + + my (Winner $winner, Grid $grid) = find-winner( @moves ); + + "Output: $winner\n\nGame Board:".put; + + "[ %s %s %s ]\n".printf: @$_ for @$grid; + + CATCH + { + when X::AdHoc + { + "\n%s\n".printf: .message; + exit 0; + } + } +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub find-winner( List:D[Move:D] $moves --> List:D[Winner:D, Grid:D] ) +#------------------------------------------------------------------------------- +{ + my Winner $winner = 'Pending'; + my Grid $grid = [ [ '_' xx 3 ] xx 3 ]; + my Str $player = 'A'; + + for @$moves -> Move $move + { + my Index ($row, $col) = @$move; + + if $grid[ $row; $col ] eq '_' + { + $grid[ $row; $col ] = $player; + } + else + { + die "ERROR: Illegal move: [$row, $col]"; + } + + $winner = check-grid( $grid ); + + last unless $winner eq 'Pending'; + + $player = $player eq 'A' ?? 'B' !! 'A'; + } + + return $winner, $grid; +} + +#------------------------------------------------------------------------------- +sub check-grid( Grid:D $grid --> Winner:D ) +#------------------------------------------------------------------------------- +{ + # Has the game been won? Test columns first, then rows, then diagonals + + for [ 0, 0, 0, 1, 0, 2 ], [ 1, 0, 1, 1, 1, 2 ], [ 2, 0, 2, 1, 2, 2 ], + [ 0, 0, 1, 0, 2, 0 ], [ 0, 1, 1, 1, 2, 1 ], [ 0, 2, 1, 2, 2, 2 ], + [ 0, 0, 1, 1, 2, 2 ], [ 0, 2, 1, 1, 2, 0 ] -> Array $coords + { + if line-complete( $coords, $grid ) + { + return $grid[ $coords[ 0 ]; $coords[ 1 ] ]; # Winner + } + } + + # No winner yet; is the game drawn? + + for 0 .. 2 -> UInt $i + { + for 0 .. 2 -> UInt $j + { + return 'Pending' if $grid[ $i; $j ] eq '_'; # No + } + } + + return 'Draw'; # Yes +} + +#------------------------------------------------------------------------------- +sub line-complete( List:D[Index:D] $coords, Grid:D $grid --> Bool:D ) +#------------------------------------------------------------------------------- +{ + my Str $square-a = $grid[ $coords[ 0 ] ][ $coords[ 1 ] ]; + my Str $square-b = $grid[ $coords[ 2 ] ][ $coords[ 3 ] ]; + my Str $square-c = $grid[ $coords[ 4 ] ][ $coords[ 5 ] ]; + + return ($square-a eq 'A' || $square-a eq 'B') && + $square-a eq $square-b && + $square-a eq $square-c; +} + +#------------------------------------------------------------------------------- +sub get-moves +( + List:D[Index:D] $coords where { .elems %% 2 } +--> List:D[Move:D] +) +#------------------------------------------------------------------------------- +{ + return $coords.rotor( 2 ).map( { [ +$_[ 0 ], +$_[ 1 ] ] } ).list; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $moves-str, $expected) = $line.split: / \| /; + + for $test-name, $moves-str, $expected + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Index @coords = $moves-str.split( / \s+ || \, /, :skip-empty ) + .map: { .Int }; + my Move @moves = get-moves( @coords ); + my (Winner $winner, Grid) = find-winner( @moves ); + + is $winner, $expected, $test-name; + } + + done-testing; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +#------------------------------------------------------------------------------- +sub test-data( --> Str:D ) +#------------------------------------------------------------------------------- +{ + return q:to/END/; + Example 1|0,0 2,0 1,1 2,1 2,2 |A + Example 2|0,0 1,1 0,1 0,2 1,0 2,0 |B + Example 3|0,0 1,1 2,0 1,0 1,2 2,1 0,1 0,2 2,2|Draw + Example 4|0,0 1,1 |Pending + Example 5|1,1 0,0 2,2 0,1 1,0 0,2 |B + END +} + +################################################################################ |
