http://qs1969.pair.com?node_id=546365

Andrew_Levenson has asked for the wisdom of the Perl Monks concerning the following question:

Okay, in preparing for my competition tomorrow, i'm doing some practice problems from the previous years. One problem has me printing a diamond of '@'s in the center of the screen using only 3 print commands. I decided to take it a step further and write it using only one print, but in the midst of writing it, I seem to have not been able to get the Text::Autoformat module to work for me. Can anyone troubleshoot this?

use strict; use warnings; use Text::Autoformat; my @array=qw/@/; for my $i(1..10){ @array = autoformat (@array, { justify => 'center' }); print "@array\n"; ((push @array, '@') x 2) if scalar(@array) < 10; ((pop @array) x 2) if scalar(@array) >= 10; }

One might also make not of the fact that I am shooting in the dark when it comes to doubling a command, haha.
Thanks!

Replies are listed 'Best First'.
Re: Text::Autoformat
by GrandFather (Saint) on Apr 28, 2006 at 20:06 UTC

    Your immediate problem is that x doesn't do what you want. To achieve what you want ("doubling" the commands) you need something like:

    push @array, ('@', '@') if scalar(@array) < 10; splice @array, -2, 2 if scalar(@array) >= 10;

    However that is only a tiny part of the problem. Your bigest problem is that an array is not appropriate, you need to use a string. Something like this:

    use strict; use warnings; use Text::Autoformat; my $str=qw/@/; for my $i(1..10){ $str = autoformat ($str, { justify => 'center' }); print "$str\n"; $str .= "@@" if length ($str) < 10; substr $str, -2, 2, '' if length ($str) > 10; }

    However that still fails because you clobber $str each time through the loop. Changing the first two lines in the loop to :

    my $newStr = autoformat ($str, { justify => 'center' }); print "$newStr\n";

    gets you closer, but leaves another logic problem (bug) which I'll leave you to puzzle over. :)


    DWIM is Perl's answer to Gödel
      Aha! That was interesting. I failed to notice that when figuring it out initially, but... huh. Thanks for your help!
      use strict; use warnings; use Text::Autoformat; my $str=qw/@/; for my $i(1..11){ my $newStr = autoformat ($str, { justify => 'center' }); print "$newStr\n"; $str .= '@@' if $i <= 5; substr $str, -2, 2, '' if $i > 5; }

        The trouble now is that the output is triple spaced. You can improve it to double spaced by removing the new line from the print. At the end of the day however Autoformat is not doing a good job for you. Nice idea, but no banana.

        I suspect in general that competitions don't expect you to have access to a full range of CPAN modules and that there is generally a reasonable way of solving the problem without resorting to a module such as Text::Autoformat.

        The single print version can be done without much modification of your current code and not using Text::Autoformat.


        DWIM is Perl's answer to Gödel
Re: Text::Autoformat
by GrandFather (Saint) on Apr 28, 2006 at 20:18 UTC

    When you have sorted out your single print variant you may be interested in this three print variant

    Prints:

    @ @@@ @@@@@ @@@@@@@ @@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@ @@@@@@@ @@@@@ @@@ @

    DWIM is Perl's answer to Gödel