[Purdue-pm] an improved solution

Mark Senn mark at purdue.edu
Mon Apr 1 15:45:45 PDT 2019


(Purdue Weekly Challenge, thought you might be interested in this.
I don't know if anyone else thought of this solution.)

Purdue Perl Mongers,    Here is an improved solution with no
conditional statements or loops.  The new stuff is at the end
of the following.    -mark

#
# Retrieved from
#     https://perlweeklychallenge.org/blog/a-new-week-a-new-challenge
# on 2019-03-27 at 11:28 -04:
#
#     Challenge #2
#
#     Write one-liner to solve FizzBuzz problem and print number 1-20.
#     However, any number divisible by 3 should be replaced by the
#     word fizz and any divisible by 5 by the word buzz. Numbers
#     divisible by both become fizz buzz.
#
# Since we are not playing Perl Golf I'm going to concentrate on making
# the code understandable.
#
# The
#     Numbers divisible by both become fizz buzz.
# condition would make this a complicated structure of if statements.  It
# might be easier for people to understand if a
#     (conndition)  and  print "...";
# construct was used instead.  This will make it easier to add conditions
# like if divisible by 3, 5, and 7 print "fizz buzz baz".  "If" statements
# are hard enough to read when formatted in two dimensions---they're
# even worse when typeset in one dimension.  (I am assuming the one-liner
# must be one physical line---not one logical line.)
#
# We could use
#     perl6 -e '(1..20).map({  my $t="";  my $e3 = $_ %% 3;  my $e5 = $_ %% 5;  $e3 and $t~="fizz";  $e3 && $e5 and $t~=" ";  $e5 and $t~="buzz";  !$e3 && !$e5 and $t~=$_;    say $t;})'
#
# Using "for" instead of "map" will be understood by people that don't
# already know about "map" and the "{...}" needed inside of it.  Put
# two spaces around each statement in the for body to make it easier to read.
#     perl6 -e 'for (1..20) {  my $t="";  my $e3 = $_ %% 3;  my $e5 = $_ %% 5;  $e3 and $t~="fizz";  $e3 && $e5 and $t~=" ";  $e5 and $t~="buzz";  !$e3 && !$e5 and $t~=$_;  say $t;}'
#
# Instead of building the string in $t and printing it at the end of
# the loop we can make this more clear by doing print statements as we go.
# For uniformity use only "print" instead of a combination of "print" and
# "say".  Multi-line commented version:
#     for (1..20)
#     {
#         # Is $_ evenly divisible by 3?
#         my $e3 = $_ %% 3;
#         # Is $_ evenly divisible by 5?
#         my $e5 = $_ %% 5;
#         $e3           and  print "fizz";
#         $e3 && $e5    and  print " ";
#         $e5           and  print "buzz";
#         !$e3 && !$e5  and  print $_;
#         print "\n";
#     }
#
# Ugh, can we do better than
#     perl6 -e 'for (1..20) {  my $e3 = $_ %% 3;  my $e5 = $_ %% 5;  $e3 and print "fizz";  $e3 && $e5 and print " ";  $e5 and print "buzz";  !$e3 && !$e5 and print $_;  print "\n";  }'
# ?
#
# Yes!
# Conditional statements cause complexity.
# Loops cause complexity.
# Let's get rid of both.
# Multi-line commented version:
#     # @x is (0, 1, ..., 20);
#     my @x = (0..20);
#     # Set every third element to "fizz".
#     @x[0,3...*] = "fizz" xx *;
#     # Set every fifth element to "buzz".
#     @x[0,5...*] = "buzz" xx *;
#     # Set every fifteenth element to "fizz buzz".
#     @x[0,15...*] = "fizz buzz" xx *;
#     # Print the output.
#     say @x[1..20].join("\n");
#

perl6 -e 'my @x = (0..20);  @x[0,3...*]="fizz"xx*;  @x[0,5...*]="buzz"xx*;  @x[0,15...*]="fizz buzz"xx*;  say @x[1..20].join("\n");'


More information about the Purdue-pm mailing list