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

Re^2: sending a scalar to the interpreter as a command

by silentq (Novice)
on Oct 08, 2012 at 22:39 UTC ( #997890=note: print w/ replies, xml ) Need Help??


in reply to Re: sending a scalar to the interpreter as a command
in thread sending a scalar to the interpreter as a command

Thanks for your quick response, David. I really appreciate it.

I would actually prefer to solve the problem without resorting to eval just as you have recommended. But, for some reason, I just can't quite wrap my head around how to do it. Maybe you or someone else can help.

What I have is a two-dimensional array filled with scores. That looks something like this:

67 42 99 28 15 14 92 12 45 57 16 41 99 67 28 15 57 12 45 14 92 12 92 42 67 28 15 45 57 16 12 99 14

The array can be varying widths and heights. In other words, there are variable numbers of rows and columns.

What I want to do is find all the possible combinations when taking one item from each row. I believe there are x^y possible combinations where x represents the number of rows and y represents the number of columns. What I want is this: 67-41-92, 67-41-42, 67-41-67, 67-41-28 ...

I believe it's just a matter of nesting arrays. The trick is setting up a dynamic number of these. I played around with the idea of using a while loop, but the problem is that this resulted in consecutive iterations through the arrays, not nested iterations.

So I'm really at a loss at this point. If anyone can help, I'd be very grateful.

Thanks,


Comment on Re^2: sending a scalar to the interpreter as a command
Download Code
Re^3: sending a scalar to the interpreter as a command
by BrowserUk (Pope) on Oct 08, 2012 at 23:28 UTC

    #! perl -slw use strict; sub loops { map { my $n = $_; @_ ? map{ $n . '-' . $_ } loops( @_ ) : $n; } @{ shift() }; } my @arrays = map [ split ], <DATA>; print for loops( @arrays ); __DATA__ 67 42 99 28 15 14 92 12 45 57 16 41 99 67 28 15 57 12 45 14 92 12 92 42 67 28 15 45 57 16 12 99 14

    Produces:

    67-41-92 67-41-42 67-41-67 67-41-28 67-41-15 67-41-45 67-41-57 67-41-16 67-41-12 67-41-99 67-41-14 67-99-92 67-99-42 67-99-67 ... 16-92-12 16-92-99 16-92-14 16-12-92 16-12-42 16-12-67 16-12-28 16-12-15 16-12-45 16-12-57 16-12-16 16-12-12 16-12-99 16-12-14

    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.

    RIP Neil Armstrong

      My apologies to BrowserUK whose earlier post I missed somehow.

      Your solution seems to do everything I needed to do. I'll play around with it and let you know if I have any additional questions, but that seems to work for now. Thanks so much!

      Thanks to everyone else, too, for your excellent suggestions. Clearly, I need to pay more attention to glob and look for more opportunities to take advantage of its functionality.

Re^3: sending a scalar to the interpreter as a command
by Kenosis (Priest) on Oct 09, 2012 at 01:34 UTC

    What I want is this: 67-41-92, 67-41-42, 67-41-67, 67-41-28 ...

    glob can help with this:

    use strict; use warnings; my $a = join ',', qw/67 42 99 28 15 14 92 12 45 57 16/; my $b = join ',', qw/41 99 67 28 15 57 12 45 14 92 12/; my $c = join ',', qw/92 42 67 28 15 45 57 16 12 99 14/; print "$_\n" for glob "{$a}-{$b}-{$c}";

    Output:

    67-41-92 67-41-42 67-41-67 67-41-28 ... 16-12-16 16-12-12 16-12-99 16-12-14
      Beautiful use of glob, I love it, thank you Kenosis!

        You're most welcome, cord-bin!

Re^3: sending a scalar to the interpreter as a command
by kcott (Abbot) on Oct 09, 2012 at 06:42 UTC

    G'day silentq,

    Welcome to the monastery.

    Extending ++Kenosis' excellent idea of using glob, here's a solution for variable rows and columns.

    #!/usr/bin/env perl use 5.010; use strict; use warnings; say for glob '{' . join('}-{' => map { join ',' => split } <DATA>) . ' +}'; __DATA__ 1 2 3 4 5 6 7 8 9

    Output:

    $ pm_2d_comb.pl 1-3-6-8 1-3-6-9 1-3-7-8 1-3-7-9 1-4-6-8 1-4-6-9 1-4-7-8 1-4-7-9 1-5-6-8 1-5-6-9 1-5-7-8 1-5-7-9 2-3-6-8 2-3-6-9 2-3-7-8 2-3-7-9 2-4-6-8 2-4-6-9 2-4-7-8 2-4-7-9 2-5-6-8 2-5-6-9 2-5-7-8 2-5-7-9

    -- Ken

      Thanks very much for your responses, guys. I've learned a lot, but I don't think I'm quite there yet. I took Kenosis's code and turned it into this:

      use strict; use warnings; my @array = ([0,.95,.114,0], [1,0,0,1], [1,3,5,7]); my $var; my @a; for (my $i = 0; $i <= $#array; $i++) { $a[$i] = join ',', @{$array[$i]}; $var .= "\{\$a\[$i\]\}-"; # can't use singl +e quotes here because $i won't resolve } #my $a = join ',', @{$array[0]}; #print "$_\n" for glob "{$a[0]}-{$a[1]}-{$a[2]}"; #this line works, + but it's not dynamic, ie. always prints out exactly three lines print "$_\n" for glob $var; #this line doesn' +t work; apparently you can't resolve a variable to glob (?) print "$var\n\n"; #this line shows +what the $var variable is passing to glob in line 17

      The 'for' loop works fine for the first step, but I get tripped up on the second step. I thought I might be able to push the new reference onto a variable each time through the loop and then pass that variable to glob, but I tried it with and without quotes, and it doesn't seem to work.

      As for kcott's idea, try as I might, I cannot parse the following line of code:

      say for glob '{' . join('}-{' => map { join ',' => split } <DATA>) . ' +}';

      I understand what join does, and I also understand map and split. But the way they are combined here is a little bit beyond my ability to comprehend. For example, where is the second argument for the first join?

      In any case, the problem that remains seems to be getting each row of the array together into one glob statement. If I could do that, the modified Kenosis code above would work, I think.

      Thanks again to everybody for the time you have taken to help me try to get this resolved.

        Here's pm_2d_comb_long.pl - a longer, annotated version of pm_2d_comb.pl:

        #!/usr/bin/env perl use 5.010; use strict; use warnings; # Original code #say for glob '{' . join('}-{' => map { join ',' => split } <DATA>) . +'}'; # Read raw data # @data_lines will be: ('1 2', '3 4 5', '6 7', '8 9') my @data_lines = <DATA>; # Convert spaces to commas by splitting each string on whitespace # to form a list whose elements are joined with commas # @spaces_to_commas will be: ('1,2', '3,4,5', '6,7', '8,9') my @spaces_to_commas = map { join ',' => split } @data_lines; # Join those strings with '}-{' # $brace_dash_brace_string will be '1,2}-{3,4,5}-{6,7}-{8,9' my $brace_dash_brace_string = join('}-{' => @spaces_to_commas); # Add opening and closing braces # $glob_string will be: '{1,2}-{3,4,5}-{6,7}-{8,9}' my $glob_string = '{' . $brace_dash_brace_string . '}'; # Finally glob '{1,2}-{3,4,5}-{6,7}-{8,9}' say for glob $glob_string; __DATA__ 1 2 3 4 5 6 7 8 9

        Outputs:

        $ pm_2d_comb_long.pl 1-3-6-8 1-3-6-9 1-3-7-8 1-3-7-9 1-4-6-8 1-4-6-9 1-4-7-8 1-4-7-9 1-5-6-8 1-5-6-9 1-5-7-8 1-5-7-9 2-3-6-8 2-3-6-9 2-3-7-8 2-3-7-9 2-4-6-8 2-4-6-9 2-4-7-8 2-4-7-9 2-5-6-8 2-5-6-9 2-5-7-8 2-5-7-9

        -- Ken

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (13)
As of 2014-08-28 15:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (263 votes), past polls