http://www.perlmonks.org?node_id=163786

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

Greetings, fellow monks,

I'm trying to come up with a clever way to solve the following problem and am convinced that I should be able to do it in one line (or thereabouts), but the gray matter isn't working up to full snuff. What I've got so far is:

my @x = (4, 4, 2); my @y; my $pref = 'XX'; foreach my $chunk (1 .. @x) { my $loc = sprintf("$pref%02d:", $chunk); push @y, map {$loc . $_} ( 1 .. $x[$chunk-1] ); }

That gives me:

@y = qw(XX01:1 XX01:2 XX01:3 XX01:4 XX02:1 XX02:2 XX02:3 XX02:4 XX03:1 XX03:2);

which is the right output, but I feel there should be a better way to achieve the end...

Replies are listed 'Best First'.
Re: Clever map / foreach algorithm sought
by Sidhekin (Priest) on May 03, 2002 at 14:02 UTC

    Anything can be done on one line ... if the line is just long enough. Possibly you are looking for something like this:

    my @x = (4, 4, 2); my $pref = 'XX'; my @y = map {my $chunk=$_; map{sprintf("$pref%02d:",$chunk).$_}1..$x[$ +chunk-1]}1..@x;

    The Sidhekin
    print "Just another Perl ${\(trickster and hacker)},"

Re: Clever map / foreach algorithm sought
by {NULE} (Hermit) on May 03, 2002 at 20:45 UTC
    Hi bmcatt,

    Ahhh - another friday afternoon and fine day it is for some golf.

    Fore!

    #! /usr/local/bin/perl -w use strict; my @x = ( 4, 4, 2 ); my @y; my $i = -1; #56 chars with whitespace removed. @y = map {sprintf("XX%02d:%d",!$_?++$i:$i,$_)} map {0..$_} @x; foreach (@y) { print ">$_\n"; }
    I'm afraid I can't offer useful advice on your algorithm at this time. I think I see what you are trying to accomplish and this approach seems reasonable enough to me.

    Good luck,
    {NULE}
    --
    http://www.nule.org

    P.S. I know this wasn't a golfing question, but I'm just in that kind of mood. I've never tried golfing before so be easy on me. :)

Re: Clever map / foreach algorithm sought
by demerphq (Chancellor) on May 03, 2002 at 14:15 UTC
    Im afraid to say that I doubt your going to get much of an answer without explaining what the intention is. Frankly I am completely at a loss as to what you want this to do. In this case is better to tell us what you need than how you are currently doing it.

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.

      Ok. :-)

      Underlying goal is data conversion. I'm processing the output from a (paper) scanning system and trying to convert it into something that's acceptable to our back-end input system. The original paper contains a bunch of mark-sense boxes (think of an SAT or similar test) and just produces a number related to the number of the box.

      So, for example, an individual block (bunch of mark sense boxes) will appear in the input data as: "EFD1=1,5,10,".

      The (4, 4, 2) refers to the actualy physical layout of those mark-sense boxes. So there are two rows of 4 boxes and one row of 2. In the above case (1,5,10), that means that the first box of the first two rows were marked as well as the second box of the last row.

      The 1,5,10 needs to be translated to what they actually "mean", so 1,5,10, needs to turn into (EF01:0, EF02:0, EF03:1). My original idea was to just build an array and index into there (1-1, 5-1, 10-1) and pick out the "right" answer.

      The algorithm question that started all this was on better ways to build that array (although, now that you mention it, suggestions on better ways to do this whole thing will also be appreciated :-).