How to get the string Cartesian Products of 2 list

How to get the string Cartesian Products of 2 list

am 23.11.2007 02:53:22 von xueweizhong

Give 2 string list such as: a..b and 1..3, i want to get a list which
is (a1, a2, a3, b1, b2, b3). Is there an elegant way in perl to
fullfill this withou using loop BLOCK? Or Is there a elegant one line
expression to get this?

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 03:45:40 von Ben Morrow

Quoth xueweizhong@gmail.com:
> Give 2 string list such as: a..b and 1..3, i want to get a list which
> is (a1, a2, a3, b1, b2, b3). Is there an elegant way in perl to
> fullfill this withou using loop BLOCK? Or Is there a elegant one line
> expression to get this?

I don't know whether you count this as using a loop (it does, of course,
underneath; but you can't possibly avoid that at some level)

use List::MoreUtils qw/pairwise/;

my @letters = (a..b);
my @numbers = (1..3);

print for pairwise { "$a$b" } @letters, @numbers;

You have to put the lists into arrays so Perl can tell which items
belong to which list.

Ben

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 04:22:57 von xueweizhong

Hi Ben,

> use List::MoreUtils qw/pairwise/;
>
> my @letters = (a..b);
> my @numbers = (1..3);
>
> print for pairwise { "$a$b" } @letters, @numbers;

It's cool, but seems too long, also List::MoreUtils is not standard
distribution

Also i find this URL for adding this into the core language:
http://www.nntp.perl.org/group/perl.perl6.language.data/2000 /09/msg462.html

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 04:30:03 von xueweizhong

> http://www.nntp.perl.org/group/perl.perl6.language.data/2000 /09/msg462.html
I thought it should be
http://www.nntp.perl.org/group/perl.perl6.language.data/2000 /09/msg437.html

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 06:40:06 von xueweizhong

Finally i got this one on bash3.0:

print qx'bash -c "echo {1..3}{a..c}"'

Perl is the glue language and there are more than one way to do it:-)

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 11:02:57 von Lars Haugseth

* xueweizhong@gmail.com wrote:
>
> Give 2 string list such as: a..b and 1..3, i want to get a list which
> is (a1, a2, a3, b1, b2, b3). Is there an elegant way in perl to
> fullfill this withou using loop BLOCK? Or Is there a elegant one line
> expression to get this?

$ perl -le '@list = glob "{a,b}{1,2,3}"; print join(",", @list);'
a1,a2,a3,b1,b2,b3

--
Lars Haugseth

"If anyone disagrees with anything I say, I am quite prepared not only to
retract it, but also to deny under oath that I ever said it." -Tom Lehrer

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 13:30:35 von Michele Dondi

On Thu, 22 Nov 2007 19:22:57 -0800 (PST), xueweizhong@gmail.com wrote:

>Also i find this URL for adding this into the core language:
>http://www.nntp.perl.org/group/perl.perl6.language.data/200 0/09/msg462.html

Into the core of *another* language! ;)


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 13:31:15 von Michele Dondi

On Thu, 22 Nov 2007 21:40:06 -0800 (PST), xueweizhong@gmail.com wrote:

>Finally i got this one on bash3.0:
>
> print qx'bash -c "echo {1..3}{a..c}"'
>
>Perl is the glue language and there are more than one way to do it:-)

Perl does glob() espansion too.


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 15:30:10 von xueweizhong

Hi Michele,

perl glob in perl5.8 is not power enough than the bash3.0 glob, it
doesn't support .. operator which is fatal to this issue:

#!/bin/perl

sub X {split / /,qx/bash -c "echo @_"/}

print "glob:\n";
print join "\n", glob "{a..b}{1..2}";

print "\n\nX:\n";
print join "\n", X "{a..b}{1..2}";

glob:
a..b1..2

X:
a1
a2
b1
b2

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 15:56:50 von Lars Haugseth

* xueweizhong@gmail.com wrote:
>
> Hi Michele,
>
> perl glob in perl5.8 is not power enough than the bash3.0 glob, it
> doesn't support .. operator which is fatal to this issue:

Why? In practice, the lists being globbed are likely to be variables,
not hard coded inside the glob call.

{
local $" = ','; # List separator

my @letters = 'a'..'c';
my @numbers = 1..3;

my @globbed = glob "{@letters}{@numbers}";

print "@globbed\n";
}

Highly preferrable to forking a new shell process.

--
Lars Haugseth

"If anyone disagrees with anything I say, I am quite prepared not only to
retract it, but also to deny under oath that I ever said it." -Tom Lehrer

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 16:55:58 von brian d foy

In article
<3bc8b657-828f-4cde-bbf5-9d9c09b8e59f@s8g2000prg.googlegroups.com>,
wrote:

> Give 2 string list such as: a..b and 1..3, i want to get a list which
> is (a1, a2, a3, b1, b2, b3). Is there an elegant way in perl to
> fullfill this withou using loop BLOCK? Or Is there a elegant one line
> expression to get this?

Although you've already said that you don't want non-core modules,
Set::CrossProduct can help here. It wouldn't be useful for this trivial
example, but for large sets it comes in handy. It provides an iterator
to get the next item so you don't have to compute the entire list at
once.

Good luck, :)

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 16:59:26 von xueweizhong

> > perl glob in perl5.8 is not power enough than the bash3.0 glob, it
> > doesn't support .. operator which is fatal to this issue:
>
> Why? In practice, the lists being globbed are likely to be variables,
> not hard coded inside the glob call.
>
> {
> local $" = ','; # List separator
>
> my @letters = 'a'..'c';
> my @numbers = 1..3;
>
> my @globbed = glob "{@letters}{@numbers}";
>
> print "@globbed\n";
>
> }
I do think these lines are worse than using loop BLOCK. What I want is
an single expression, not statements with so many nosiy lines.

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 17:13:15 von xueweizhong

Hi brian,

> Although you've already said that you don't want non-core modules,
> Set::CrossProduct can help here. ...

Really cool. I'll study it.

BTW, bash is more common than non-standard perl module, right? :-)

-Todd

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 20:15:29 von Michele Dondi

On Fri, 23 Nov 2007 08:13:15 -0800 (PST), xueweizhong@gmail.com wrote:

>> Although you've already said that you don't want non-core modules,
>> Set::CrossProduct can help here. ...
>
>Really cool. I'll study it.
>
>BTW, bash is more common than non-standard perl module, right? :-)

It depends... what if you want your program to run under Windows as
well? Of course Win32 ports of bash do exist. But would you expect
people to install one for a single line in your script?


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 20:29:48 von Ben Morrow

Quoth xueweizhong@gmail.com:
> > Although you've already said that you don't want non-core modules,
> > Set::CrossProduct can help here. ...
>
> Really cool. I'll study it.
>
> BTW, bash is more common than non-standard perl module, right? :-)

Depending on your frame of reference, maybe. However, if you package up
your Perl program properly (see perlnewmod), you can get perl to install
modules for you automatically, which is rather harder to arrange for
bash. :)

Ben

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 20:52:21 von Lars Haugseth

* xueweizhong@gmail.com wrote:
>
> > > perl glob in perl5.8 is not power enough than the bash3.0 glob, it
> > > doesn't support .. operator which is fatal to this issue:
> >
> > Why? In practice, the lists being globbed are likely to be variables,
> > not hard coded inside the glob call.
> >
> > {
> > local $" = ','; # List separator
> >
> > my @letters = 'a'..'c';
> > my @numbers = 1..3;
> >
> > my @globbed = glob "{@letters}{@numbers}";
> >
> > print "@globbed\n";
> >
> > }
> I do think these lines are worse than using loop BLOCK. What I want is
> an single expression, not statements with so many nosiy lines.

Err, what do you mean? The only "extra" statement here is the setting
of $" to make the glob and print more readable. The rest is assignments
and output, just there to make the example complete. How would you have
done this using loops with less expressions?

--
Lars Haugseth

"If anyone disagrees with anything I say, I am quite prepared not only to
retract it, but also to deny under oath that I ever said it." -Tom Lehrer

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 21:14:20 von xhoster

xueweizhong@gmail.com wrote:
> Hi brian,
>
> > Although you've already said that you don't want non-core modules,
> > Set::CrossProduct can help here. ...
>
> Really cool. I'll study it.
>
> BTW, bash is more common than non-standard perl module, right? :-)

Apparently "bash3.0" isn't common enough. All the machines I've looked
at, many fairly new, don't have it. And on those versions, ".."
is just literal.


Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: How to get the string Cartesian Products of 2 list

am 23.11.2007 22:38:54 von Ted Zlatanov

On Fri, 23 Nov 2007 07:59:26 -0800 (PST) xueweizhong@gmail.com wrote:

>> > perl glob in perl5.8 is not power enough than the bash3.0 glob, it
>> > doesn't support .. operator which is fatal to this issue:
>>
>> Why? In practice, the lists being globbed are likely to be variables,
>> not hard coded inside the glob call.
>>
>> {
>> local $" = ','; # List separator
>>
>> my @letters = 'a'..'c';
>> my @numbers = 1..3;
>>
>> my @globbed = glob "{@letters}{@numbers}";
>>
>> print "@globbed\n";
>>
>> }
x> I do think these lines are worse than using loop BLOCK. What I want is
x> an single expression, not statements with so many nosiy lines.

What you perceive as noise are actually good Perl programming
practices. If you don't like them, you could do:

# the original is much better code
print glob sprintf("{%s}{%s}", join(',', 'a'..'c'), join(',', 1..3));

# even more bash-like, using in-place interpolation hacks
local $" = ','; # List separator
print glob "{@{['a'..'c']}}{@{[1..3]}}\n";

You should realize that Perl is a programming language and thus does not
have all the shortcuts that bash offers. No Perl solution will satisfy
you if you just want bash. If you want bash, use bash.

Ted

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 03:08:37 von rvtol+news

Ted Zlatanov schreef:

> local $" = ','; # List separator
> print glob "{@{['a'..'c']}}{@{[1..3]}}\n";

Command line version:

$perl -wle '
$"=",";
print for glob "{@{[ q{a}..q{c} ]}}{@{[ 1..3 ]}}"
'
a1
a2
a3
b1
b2
b3
c1
c2
c3

--
Affijn, Ruud

"Gewoon is een tijger."

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 07:08:23 von xueweizhong

Hi Ruud,


Really nice, a pure perl way now rather than dependant on my bash one.

After your inspiration, i get another solution using map:

>perl -e 'print join ",", map { my $g=$_; map $g.$_,1..3 } "a".."c"'
a1,a2,a3,b1,b2,b3,c1,c2,c3

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 07:15:05 von xueweizhong

> You should realize that Perl is a programming language and thus does not
> have all the shortcuts that bash offers. No Perl solution will satisfy
> you if you just want bash. If you want bash, use bash.
I use everything I have. Why not do the programming in mutiple
lanugages which complements each other.

--Todd

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 13:53:07 von rvtol+news

Dr.Ruud schreef:
> Ted Zlatanov schreef:
>
>> local $" = ','; # List separator
>> print glob "{@{['a'..'c']}}{@{[1..3]}}\n";
>
> Command line version:
>
> perl -wle '
> $"=",";
> print for glob "{@{[ q{a}..q{c} ]}}{@{[ 1..3 ]}}"
> '

Others:

perl -le'
sub c{local $"=","; "{@_}"}
print for glob c("a".."c").c(1..3)
'

perl -le'
sub c{"{". join(",", @_) ."}"}
print for glob c("a".."c").c(1..3)
'

--
Affijn, Ruud

"Gewoon is een tijger."

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 14:26:24 von xueweizhong

> >> local $" = ','; # List separator
> >> print glob "{@{['a'..'c']}}{@{[1..3]}}\n";

Is this difference below a language feature or bug?

>perl -e 'local $" = ","; print join ",", '
a001,a002,a003,a004,a005,a006,a007,a008,a009,a010,a011,a012, a013,a014,a015,a016,a017,a018,a019,a020,a021,a022,a023,a024, a025,a026,a027,a028,a029,a030,a031,a032,a033,a034,a035,a036, a037,a038,a039,a040,a041,a042,a043,a044,a045,a046,a047,a048, a049,a050,a051,a052,a053,a054,a055,a056,a057,a058,a059,a060, a061,a062,a063,a064

>perl -e 'local $" = ","; print join ",", '
a

-Todd

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 14:53:12 von Michele Dondi

On Fri, 23 Nov 2007 06:30:10 -0800 (PST), xueweizhong@gmail.com wrote:

>perl glob in perl5.8 is not power enough than the bash3.0 glob, it
>doesn't support .. operator which is fatal to this issue:

I didn't know that bash 3.* did that. In any case, that's good.

In perl, you can currently use a workaround:

>#!/bin/perl
>
>sub X {split / /,qx/bash -c "echo @_"/}
>
>print "glob:\n";
>print join "\n", glob "{a..b}{1..2}";

local ($",$,)=(",", "\n");
print glob "{@{['a'..'b']}}{@{[1..2]}}"

Of course, someone may implement a bash30_glob() to add to File::Glob.


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 14:55:52 von Michele Dondi

On Fri, 23 Nov 2007 07:59:26 -0800 (PST), xueweizhong@gmail.com wrote:

>> {
>> local $" = ','; # List separator
>>
>> my @letters = 'a'..'c';
>> my @numbers = 1..3;
>>
>> my @globbed = glob "{@letters}{@numbers}";
>>
>> print "@globbed\n";
>>
>> }
>I do think these lines are worse than using loop BLOCK. What I want is
>an single expression, not statements with so many nosiy lines.

You can have a single statement, but that's probably even more noisy:

my @globbed = do { local $"=',';
glob "{@{['a'..'c']}}{@{[1..3]}}" };


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 14:58:53 von Michele Dondi

On Sat, 24 Nov 2007 05:26:24 -0800 (PST), xueweizhong@gmail.com wrote:

>> >> local $" = ','; # List separator
>> >> print glob "{@{['a'..'c']}}{@{[1..3]}}\n";
>
>Is this difference below a language feature or bug?
>
>>perl -e 'local $" = ","; print join ",", '
>a001,a002,a003,a004,a005,a006,a007,a008,a009,a010,a011,a012 ,a013,a0

Feature. Try

perl -le 'print for "aa".."bb"'


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 15:08:41 von xueweizhong

> >>perl -e 'local $" = ","; print join ",", '
> >a001,a002,a003,a004,a005,a006,a007,a008,a009,a010,a011,a012 ,a013,a0
>
> Feature. Try
>
> perl -le 'print for "aa".."bb"'
>
You misunderstood me. What i want to understand is the difference
between the output of 2 commands below:
1. perl -e 'local $" = ","; print join ",", '
2. perl -e 'local $" = ","; print join ",", '

The 2nd one doesn't out of our expection, can you try this to see
what's going on?:
$perl -e 'local $" = ","; print join ",", '
a


-Todd

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 15:09:23 von rvtol+news

xueweizhong@gmail.com schreef:
> Ruud:

>> glob "{@{[ q{a}..q{c} ]}}{@{[ 1..3 ]}}"
>
> Really nice, a pure perl way now rather than dependant on my bash one.
>
> After your inspiration, i get another solution using map:
>
> perl -e 'print join ",", map { my $g=$_; map $g.$_,1..3 } "a".."c"'
> a1,a2,a3,b1,b2,b3,c1,c2,c3

$ perl -wle'
sub mm{my $_0=shift; map {my $g=$_; map $g.$_, @_>1?mm(@_):@{$_[0]}}
@$_0}
print for mm ["a".."c"], [1..3], ["x".."z"], [7..9];
'
a1x7
a1x8
....
c3z8
c3z9

--
Affijn, Ruud

"Gewoon is een tijger."

Re: How to get the string Cartesian Products of 2 list

am 24.11.2007 18:54:10 von Michele Dondi

On Sat, 24 Nov 2007 06:08:41 -0800 (PST), xueweizhong@gmail.com wrote:

>You misunderstood me. What i want to understand is the difference
>between the output of 2 commands below:
>1. perl -e 'local $" = ","; print join ",", '
>2. perl -e 'local $" = ","; print join ",", '

I'm astonished: unless I'm missing something *very* obvious, the only
difference is that the former prints up to the 064 and the second to
065.

>The 2nd one doesn't out of our expection, can you try this to see
>what's going on?:
>$perl -e 'local $" = ","; print join ",", '
>a

Aren't you by any chance just experiencing some problem with the
prompt and not printing a newline?


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Re: How to get the string Cartesian Products of 2 list

am 26.11.2007 18:59:58 von Jim Gibson

In article
<9749e8a7-09d0-4382-a10c-52d3df326b2d@s36g2000prg.googlegroups.com>,
wrote:

> > You should realize that Perl is a programming language and thus does not
> > have all the shortcuts that bash offers. No Perl solution will satisfy
> > you if you just want bash. If you want bash, use bash.
> I use everything I have. Why not do the programming in mutiple
> lanugages which complements each other.

I can think of three reasons: efficiency, consistency, and
maintainability. There are no doubt others.

Efficiency: it is expensive to fork a separate process to perform a
function. While this may not be important for most applications, it can
become a bottleneck for the most critical applications.

Consistency: languages differ in syntax and semantics. I often have
trouble moving from one language to another.

Maintainability: while you may be proficient in multiple languages, the
next guy who has to maintain your code may not be.

So for programs that only you use occasionally, go ahead and mix perl
and bash to your heart's delight. Just don't argue that this is the
best approach for all.

--
Jim Gibson

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

How about csh-like (nested, etc)? Re: How to get the string Cartesian Products of 2 list

am 21.12.2007 04:38:19 von dkcombs

In article <3bc8b657-828f-4cde-bbf5-9d9c09b8e59f@s8g2000prg.googlegroups.com>,
wrote:
>Give 2 string list such as: a..b and 1..3, i want to get a list which
>is (a1, a2, a3, b1, b2, b3). Is there an elegant way in perl to
>fullfill this withou using loop BLOCK? Or Is there a elegant one line
>expression to get this?

Lots of neat solutions to *this* problem in this thread!

Now, how about generalizing it to eg what csh, etc, has:

{a, b, c, {e, f, g}{1,2}, x}{" hello", "goodbye"} etc

How to even *approach* this problem, or even *think* about it.

A whole set of coroutines or generators or something?

Any ideas?

Thanks

David

Not that I really need a solution -- seems to me
like a very interesting problem, various possible data structures,
various possible control structures, ...

Re: How about csh-like (nested, etc)? Re: How to get the string Cartesian Products of 2 list

am 21.12.2007 13:19:06 von Michele Dondi

On Fri, 21 Dec 2007 03:38:19 +0000 (UTC), dkcombs@panix.com (David
Combs) wrote:

>>Give 2 string list such as: a..b and 1..3, i want to get a list which
>>is (a1, a2, a3, b1, b2, b3). Is there an elegant way in perl to
>>fullfill this withou using loop BLOCK? Or Is there a elegant one line
>>expression to get this?
>
>Lots of neat solutions to *this* problem in this thread!
>
>Now, how about generalizing it to eg what csh, etc, has:
>
> {a, b, c, {e, f, g}{1,2}, x}{" hello", "goodbye"} etc
>
>How to even *approach* this problem, or even *think* about it.

Well Perl 6 should have that. I know because I once asked in p6l,
however I can't remember the syntax offhand, and it may have changed
in the meanwhile. Currently, we have Algorithm::Loops::NestedLoops().


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^ ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,