Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Printing a hollow square of Asterisks

by puudeli (Pilgrim)
on Mar 04, 2009 at 14:10 UTC ( [id://748157]=note: print w/replies, xml ) Need Help??


in reply to Printing a hollow square of Asterisks

Sounds like homework to me :-P. Anyway, you need to figure out an algorithm that removes the asterisks in the middle on rows 2 & 3.

--
seek $her, $from, $everywhere if exists $true{love};

Replies are listed 'Best First'.
Re^2: Printing a hollow square of Asterisks
by Anonymous Monk on Mar 04, 2009 at 14:19 UTC
    homework? nah, im 24 and self studying for Perl.. Come across this question but cant figure it out.
      Ah, so it is homework after all :-)!

      Even self-imposed homework is homework, but in this case I think you will be a willing participant if I tell you we'll be happy to help you think it through and even tell you once you've got it right, but not to give the answer. :-)

      So here is a review of your code:

      # *always* use these - they do (some of) your error # checking for you! - saves *lots* of time use strict; use warnings; #this is right my $x = 4; my $y = 4; for (1..$x) { #this bit is wrong - see discussion below print "*" x $y, "\n"; }

      The bit I marked wrong is where your problem is. To get a hole in the middle you need dark space for the edges, i.e. asterisks and white space for the hole, i.e. spaces. If you print "*" x $y you will just get the dark stuff and no white space. So how do you get white space? Ask yourself these questions:

      1. How many rows do you want to mark the top edge of the box? You can use a solid line of asterisks for each row in the edge since an edge is solid with no whitespace.
      2. How many rows do you want to mark the bottom edge of the box?
      3. How many rows are left for the part between the top and bottom edge? If you want to see a hole, each of the lines in the middle will need some white space in it.
      4. Now inside your for loop, can you think of a way to tell if you are on the top edge, middle, or bottom edge?
      5. Can you use that to create an if...elsif...else statement that does different things depending on whether you are on the top, middle or bottom?

      Printing out the top and bottom is easy: you have that bit already - just print out a solid line of asterisks. But what about the middle? Here's how to think that through:

      1. How many asterisks do you want for your sides: 1? 2?
      2. If each of your edges has N asterisks and your total line size is M, how many spaces will you need in the middle?
      3. Can you think of a way to print out three separate strings on a single line to make a line with a hole in it: one containing N asterisks (left edge), one containing the spaces (middle), and one containing N asterisks (right edge)?

      When you've thought this through, update your original post with the changes. If it still isn't working quite right, I'm sure people will be glad to help you further.

      Best, beth

      A couple of thoughts further to ELISHEVA's comments.

      • The normal convention is to use x to represent left and right and y for up and down. You might want to swap your $x and $y to avoid confusion.

      • Rather than employing a for loop to iterate over every line you want to print, consider printing your "solid" top border then using the for to iterate over 2 fewer lines than your total y dimension whilst printing the "hollow" lines then finally printing the "solid" bottom border. That way, you have no need to detect where you are in the loop.

      • Consider putting this code in a subroutine, passing your dimensions as arguments (see perlsub) as a further learning exercise. Think about doing some basic validation, e.g. how would you cope with a negative or non-numeric dimension?

      I hope these thoughts are helpful.

      Cheers,

      JohnGG

      perl -le 'my $n = shift; die q{Please provide a positive number.} if ($n < 0); print q{*} x $n; if ($n > 1) { foreach (2 .. $n - 1) { print q{*}, q{ } x ($n - 2), q{*}; } print q{*{ x $n; }'

      The above snippet takes a number afterward to select the size. In the case of nothing given, $n gets a value of 0. The q{*} x $n will give nothing if $n is 0, or $n asterisks. The if statement prevents the loop for the sides and printing a bottom if $n is 1. The loop is triggered only if $n - 1 is greater than 2 (ie, 3 or more), and prints only the asteristks on either edge, producing the "hole" in the middle.

      Hope that helps.

        hey thanks for this.. but i cant seem to run this code..

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://748157]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (9)
As of 2024-04-24 08:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found