Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Chess Board Single Loop

by xantithor (Novice)
on Oct 03, 2013 at 20:47 UTC ( [id://1056794]=perlquestion: print w/replies, xml ) Need Help??

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

Good Afternoon, I am attempting to help my sister-in-law with a question, and unfortunately my brain isn't what it once was. She is trying to construct an 8x8 number count so it will look similar to a chess board. She is trying to accomplish this utilizing a single loop, but all I keep coming up with is an array. I'm more than likely over thinking the process, and come to you for assistance. Thank-you in advance

Replies are listed 'Best First'.
Re: Chess Board Single Loop
by aaron_baugher (Curate) on Oct 04, 2013 at 01:57 UTC

    If one loop is better than two, zero loops must be better than one!

    #!/usr/bin/env perl use strict; use warnings; sub add { my $n = shift; return add($n-1) . sprintf( "%3d",$n) . ($n%8?'':"\n") if $n > 0; } print add(64); # output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

    Aaron B.
    Available for small or large Perl jobs; see my home node.

      I wish I could ++ this more. Who ever would think of using recursion for this?! Beautiful? Ugly? Fun! (I think that's 2nd term CS in most community college Comp Sci programs.)


      Dave

        Heh, thanks. The funny thing is, I've almost never used recursion in a serious project. But it comes in handy for those "My solution is more obscure than yours" competitions.

        Aaron B.
        Available for small or large Perl jobs; see my home node.

        > Who ever would think of using recursion for this?

        LISPing people with recursing tails? ;-)

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: Chess Board Single Loop
by davido (Cardinal) on Oct 03, 2013 at 21:01 UTC

    Is this what you mean?

    use Data::Dumper; my @array; for my $i ( 0 .. 63 ) { push @array, [] if $i % 8 == 0; push @{$array[-1]}, $i; } print Dumper \@array;

    Dave

Re: Chess Board Single Loop
by bigsipper (Initiate) on Oct 04, 2013 at 00:36 UTC
    Have you considered using the 'modulus' operator:
    #!/usr/local/bin/perl5.8.8 -w for $x ( 1.. 64 ){ printf "%2d ", $x; printf "\n" if (($x % 8)==0); } [401] ; ./test.pl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
      bigsipper,
      I upvoted this node because it is the same idea I would have used. Here is how I would have written it:
      #!/usr/bin/perl use strict; use warnings; for my $x (1 .. 64) { printf("%.2d ", $x); print "\n" if not $x % 8; }
      I noticed in another thread where you indicated you have been programming Perl for 13 years. That's longer than myself as I have only been at it for 11. I find it odd with so many years of experience that you still use the -w flag rather than the lexically scoped warnings pragma and chose to treat $x as an undeclared global. These things have been considered best practices for ages. Is there a reason you don't use them?

      Cheers - L~R

Re: Chess Board Single Loop
by BrowserUk (Patriarch) on Oct 03, 2013 at 22:06 UTC

    Like this

    print for map{ join '|', map sprintf( "%02d", $_ ), $_*8+1 .. $_*8+8 } + 0 .. 7;; 01|02|03|04|05|06|07|08 09|10|11|12|13|14|15|16 17|18|19|20|21|22|23|24 25|26|27|28|29|30|31|32 33|34|35|36|37|38|39|40 41|42|43|44|45|46|47|48 49|50|51|52|53|54|55|56 57|58|59|60|61|62|63|64

    Or perhaps this comes closer to your "one loop" ideal?:

    print for unpack '(A24)*', join'|','01' .. '64', '';; 01|02|03|04|05|06|07|08| 09|10|11|12|13|14|15|16| 17|18|19|20|21|22|23|24| 25|26|27|28|29|30|31|32| 33|34|35|36|37|38|39|40| 41|42|43|44|45|46|47|48| 49|50|51|52|53|54|55|56| 57|58|59|60|61|62|63|64|

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Chess Board Single Loop
by jaredor (Priest) on Oct 04, 2013 at 06:13 UTC

    Step aside everyone. Someone who took a BASIC programming class at a local college in the mid 80s coming through....

    If this is an "old school" procedural programming course, then the answer would typically be something like this:

    #!/usr/bin/env perl use strict; use warnings; my ($row, $col) = (1,1); while ($row <= 8 and $col <= 8) { print (($row - 1) * 8 + $col, "\t"); if ($col == 8) { # start next row print "\n"; $row = $row + 1; $col = 1; } else { $col = $col + 1; } }

    Aside from my painfully primitive code above, whatever else I wrote will now be read as derivative of davido's excellent posts so I buried it in readmore tags because it did take me down memory lane and I hadn't the heart to cull it. (In particular, I did go to the one-liner, which he held off from writing because he doesn't want to scare off beginners. Not me ... BOO! ;-)

Re: Chess Board Single Loop
by marinersk (Priest) on Oct 03, 2013 at 22:54 UTC
    While it can be done with a single loop, it seems to me you have to use less intuitive coding techniques to enforce that arbitrary constraint.

    I'm beyond understanding why not just use a nested loop and be done with it.

    #!/usr/bin/perl -w use strict; foreach my $y_axis (1..8) { my $output_text = ''; foreach my $x_axis (1..8) { $output_text .= " $x_axis$y_axis "; } print "$output_text\n"; } exit; __END__ C:\Steve\Dev\PerlMonks\P-2013-10-03@1652-8x8-Loop>8x8.pl 11 21 31 41 51 61 71 81 12 22 32 42 52 62 72 82 13 23 33 43 53 63 73 83 14 24 34 44 54 64 74 84 15 25 35 45 55 65 75 85 16 26 36 46 56 66 76 86 17 27 37 47 57 67 77 87 18 28 38 48 58 68 78 88

    That said, BrowserUK produced, as usual, a brilliant one-loop solution.

      In week one or two of intro to CS at a community college level, students may not have been introduced to the concept of arrays, nested loops, unpack templates, map, and so on. However, anyone with grade-school math in their past understands remainders with integer division (ie, the modulus operator). What's amazing is that such a simple thing, taught in 4th grade, is useful to low-level-language programmers even today when using arithmetic to simulate multi-dimensional structures in flat memory.


      Dave

        Ironically, all my math teachers in elementary school glossed over the chapters which covered other bases (generally base 12 for the clock and we were done) and completely skipped over modulo operations.

        I first learned about the concept of "modulo" in my first programming course in high school -- and that was taught after nested loops.

        It's funny how we keep having to learn that the rest of the world didn't have our life experiences; they had their own. To me, nested loops seems like the third thing you learn in programming; to you, knowing modulo seems like a 4th grade thing.

        Excellent post, davdio, as always.

        Update: After posting this, I see a metric ton of the same approach being done, including re-reading one of your prior posts, davido, and realize that the code snippet was unnessesary.

Re: Chess Board Single Loop
by LanX (Saint) on Oct 04, 2013 at 01:33 UTC
    two solutions which try to avoid any modulo or printf:

    DB<198> for my $row (0..7) { for my $col (0..7) { print "$row/$col\t" } print "\n" } 0/0 0/1 0/2 0/3 0/4 0/5 0/6 0/7 1/0 1/1 1/2 1/3 1/4 1/5 1/6 1/7 2/0 2/1 2/2 2/3 2/4 2/5 2/6 2/7 3/0 3/1 3/2 3/3 3/4 3/5 3/6 3/7 4/0 4/1 4/2 4/3 4/4 4/5 4/6 4/7 5/0 5/1 5/2 5/3 5/4 5/5 5/6 5/7 6/0 6/1 6/2 6/3 6/4 6/5 6/6 6/7 7/0 7/1 7/2 7/3 7/4 7/5 7/6 7/7 DB<199> for my $row (0..7) { for my $col (0..7) { print $row*8+$col,"\t" } print "\n" } 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Chess Board Single Loop
by aaron_baugher (Curate) on Oct 04, 2013 at 06:49 UTC

    To continue the silliness, here's one that hides the loop in a regex:

    #!/usr/bin/env perl use strict; use warnings; $_ = '1' x 64; s{1}{ my $p=pos()+1; sprintf("%3d",$p).($p%8?'':"\n") }ge; print;

    Aaron B.
    Available for small or large Perl jobs; see my home node.

      How about this?

      print join( " ", 1..64 ) =~ s/(\d+\s?){8}\K/\n/gr;
Re: Chess Board Single Loop
by MidLifeXis (Monsignor) on Oct 04, 2013 at 12:13 UTC

    Nobody used octal yet?

    for my $x (0..7) { for my $y (0..7) { printf("%3d", 1+eval "0$x$y"); } print "\n"; }

    --MidLifeXis

Re: Chess Board Single Loop
by hippo (Bishop) on Oct 04, 2013 at 12:41 UTC

    Here's one more, and this one is actually like a chess board.

    #!/usr/bin/perl -w use strict; use warnings; my $i = 8; my $c = 'a'; while ($i > 0) { printf " %1s%1s", $c++, $i; if ($c gt 'h') { $i--; $c = 'a'; print "\n"; } }
Re: Chess Board Single Loop
by Laurent_R (Canon) on Oct 03, 2013 at 22:32 UTC

    Sorry, what you need exactly is unclear to my mind. Please explain further.

      I created an array for her, but she was becoming more confused the longer I spoke about it. Apparently she is taking a class at the local community college, and she hasn't gotten to learning about array's just yet. I'm attempting to simplify it for her by using a for_loop, and for some unknown reason I am stumped on this. The array came natural, but I feel like Ol' McDonald from the Geico commercials.
        This is probably what will help her most, but how do I make it stop at 8, and start at the next row?
        #!/usr/bin/perl -w use strict; print "$_\n" foreach ('1'..'64');
Re: Chess Board Single Loop
by Marshall (Canon) on Oct 04, 2013 at 12:02 UTC
    There are many ways to make a data struct like that.
    Use a "single loop", I don't get it.

    What does your sister-in-law want to accomplish?

    There are many suggestions in this thread about
    various things, but I'd like a clear statement of the
    problem to solved.

Re: Chess Board Single Loop
by Anonymous Monk on Oct 04, 2013 at 17:30 UTC
    my %CHESS; foreach (1...8) { $CHESS{$_}{$_} = $_*$_ };
      For the fun of it I want to try the same thing, however with random variable numbers.
      #!/usr/bin/perl -w use strict; my $num1; my $num2; print "Enter in a whole number: "; chomp ($num1 = <STDIN>); print "Enter in another whole number: "; chomp ($num2 = <STDIN>); print "\n"; foreach ( $num1 .. $num2 ) { print "$_ "; print "\n" if ( $_ == ($num1 +4) ); }
      the last line of the code I am stumped on. I want it to start a new line after five numbers. It works if the number range is smaller than 10 numbers, however if I expand past 10 numbers it keeps on trucking.

        $_ == ($num1 +4) will only ever be true once at most; if $num2 is small enough, it will never be true.

        Given the number of times "%" (the modulo operator) has been mentioned in this thread, I'm surprised you haven't looked into it. [follow the link I've provided for details of this operator]

        To produce a newline after every 5 numbers, you'll need to change

        print "\n" if ( $_ == ($num1 +4) );

        to something like

        print "\n" unless ($_ - $num1 + 1) % 5;

        You may need to sit down with paper and pencil to understand why this code works. That would probably be time well spent.

        -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1056794]
Approved by davido
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2024-04-20 03:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found