#!/usr/bin/perl use strict; use warnings; my $TRIANGLE = '..Z2.X6.V343.T2132312.RI.P4E4.N8A8.L3636363.J313231323132313.Hc..'; DrawPattern1($TRIANGLE); DrawPattern2($TRIANGLE); DrawPattern3($TRIANGLE); ##################################################################### # This function converts the input pattern from plain text to binary. # Also returns the length of the pattern and a couple of zeros. # Usage: ($PATTERN, $LENGTH, 0, 0) = GetPattern($TEXT) # sub GetPattern { my $PATTERN = defined $_[0] ? $_[0] : ''; # Remove everything except letters and numbers and periods. $PATTERN =~ tr|.0-9A-Za-z||cd; # Replace all numbers and letters with characters 00 - 3E $PATTERN =~ tr|.0-9A-Za-z|\x40\x00-\x3E|; return ($PATTERN, length($PATTERN), 0, 0); } ##################################################################### # This function prints a pattern to stdout. # The pattern should be plain text. Each even numbered letter # specifies the number of spaces to print, and odd numbered # letters specify the number of '#' signs to print. # A period creates a line break. # Usage: DrawPattern1(STRING) # sub DrawPattern1 { my ($PATTERN, $LENGTH, $MODE, $c) = GetPattern($_[0]); for (my $i = 0; $i < $LENGTH; $i++) { $c = ord(substr($PATTERN, $i, 1)); PrintPattern($MODE, $c); } } ##################################################################### # Prints a number of spaces or pound signs to stdout, or a new line. # Changes the value of the first argument. # Usage: PrintPattern(WHAT_TO_PRINT, COUNT) # sub PrintPattern { @_ == 2 or return; my ($MODE, $COUNT) = @_; $COUNT < 64 or return $_[0] = print "\n"; $_[0] = $MODE = $MODE & 1 ? 32 : 35; print chr($MODE) x $COUNT; } ##################################################################### # This function does exactly the same thing as DrawPattern1() # Usage: DrawPattern2(STRING) # sub DrawPattern2 { my ($PATTERN, $LENGTH, $MODE, $c) = GetPattern($_[0]); for (my $i = 0; $i < $LENGTH; $i++) { $c = ord(substr($PATTERN, $i, 1)); if ($c == 64) { $MODE = print "\n"; next; } print chr($MODE = $MODE & 1 ? 32 : 35) x $c; } } ##################################################################### # This function does exactly the same thing as DrawPattern1() # Usage: DrawPattern3(STRING) # sub DrawPattern3 { my ($PATTERN, $LENGTH, $MODE, $c) = GetPattern($_[0]); # This is nice but won't work: my $code_ref = \"if (\$c == 64) { \$MODE = print \"\\n\"; next; }" . " print chr(\$MODE = \$MODE & 1 ? 32 : 35) x \$c; "; # This will work: my $CODE_REF = \"if (\$c == 64) { \$MODE = print \"\\n\"; }" . " else { print chr(\$MODE = \$MODE & 1 ? 32 : 35) x \$c; } "; for (my $i = 0; $i < $LENGTH; $i++) { $c = ord(substr($PATTERN, $i, 1)); eval($$CODE_REF); # This is, of course, not a very good idea, because # repeatedly using eval() slows down the program. } } #####################################################################