Leser: 5
![]() |
|< 1 2 >| | ![]() |
19 Einträge, 2 Seiten |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
use Data::Dumper; print Dumper map { my $a=$_; map { my $b=$_; map { $a**2 == $b **2 + $_ **2 ? [ $_, $b, $a ] : () } (1..$b) } (1..$a) } (1..10); print Dumper grep { $_->[0]**2 == $_->[1] **2 + $_->[2] **2 } map { my $a=$_; map { my $b=$_; map { [ $a, $b, $_ ] } (1..$b) } (1..$a) } (1..10);
LanX-+2008-10-29 17:26:00--BTW: Auch kann man es so (noch) NICHT schachteln!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
{ my @list; sub gather (&) { my( $sub ) = @_; push @list, []; $sub->(); return @{ pop @list }; } # gather sub take { push @{ $list[-1] }, @_ } }
LanX-+2008-10-29 17:26:00--Danke, trotz googeln übersehen ... aber es ist AFAIS zu billig um auf Ronnies Problem angesetzt zu werden, man übergibt fixe Arrayrefs, d.h. $j kann nicht dynamisch bis (1..$i) laufen.
Bei meienm Ansatz kann das ganze semantische Spektrum von Python abgedeckt werden.
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
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; sub comp { my( $sub, $var, $list, @x ) = @_; my @l; no strict 'refs'; for ( $list->() ) { ${"::$var"} = $_; push @l, @x ? comp( $sub, @x ) : $sub->(); } # for return @l; } # comp my @tripel = comp sub{ $::i**2 == $::j**2 + $::k**2 ? [$::k, $::j, $::i] : () }, 'i' => sub{ 1.. 10 }, 'j' => sub{ 1..$::i }, 'k' => sub{ 1..$::j }; print Dumper( \@tripel ), "\n";
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
package Comp; use strict qw( vars subs ); use warnings; sub import { my( $class ) = caller(); my $comp; $comp = sub { my( $sub, $var, $list, @x ) = @_; my @l; for ( $list->() ) { ${$class.'::'.$var} = $_; push @l, @x ? $comp->( $sub, @x ) : $sub->(); } # for return @l; }; *{$class.'::comp'} = $comp; } # import 1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#!/usr/bin/perl use strict; use warnings; use Comp; use Data::Dumper; our( $i, $j, $k ); my @tripel = comp sub{ $i**2 == $j**2 + $k**2 ? [$k, $j, $i] : () }, 'i' => sub{ 1..10 }, 'j' => sub{ 1..$i }, 'k' => sub{ 1..$j }; print Dumper( \@tripel ), "\n";
MatthiasW+2008-10-29 22:13:33--LanX-+2008-10-29 17:26:00--BTW: Auch kann man es so (noch) NICHT schachteln!
Aber wenigstens untereinander verwenden ;)
Möchte man es noch verschachteln, kann man für jedes gather eine eigene Liste verwenden:
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
### gather schachteln? { my $list_ref=[]; sub gather (&){ my $code_ref=shift; my @list=(); my $safe=$list_ref; $list_ref=\@list; &$code_ref; $list_ref=$safe; return @list; } sub take { push @$list_ref, @_; return; } } #- simple test @x= gather{ take [$_] for (1..3) }; print Dumper \@x; #- nested test @x=(); @x= gather{ take gather{ my $x=$_; take [$_,$x] for (1..$x) } for (1..5); }; print Dumper \@x;
MatthiasW+2008-10-29 22:13:33--Besonders störend finde ich die ::, mir ist nur nichts besseres eingefallen, was halbwegs sauber wäre.
Ronnie+2008-10-29 22:44:08--sehr schick was ihr da gemacht habt. Die Lösung mit der while-Schleife und dem Closure habe ich erstmal 'ne Weile angestarrt, bis ich endlich die Curlies (und damit das Closure) außenrum wahrgenommen habe. Das gefällt mir sehr gut. Den Rest muss ich mir morgen nochmal in Ruhe betrachten, aber ich finde es schon jetzt sehr spannend.
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
{ my ($c,$b,$a)=(1,1,1); sub lazy { for ( ; $c <= $max ; $c++ ) { for ( ; $b <= $c ; $b++ ) { for ( ; $a <= $b ; $a++ ) { return [$c,$b,$a++] if $c**2 == $b**2 + $a**2; }; $a=1; #reset }; $b=1; #reset } $c=1; return; } } while ( $triple = lazy() ) { print Dumper $triple; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
my( $i, $j, $k ); my $li = lazy { ${$_[0]}++ } 1; my $lj = lazy { ${$_[0]} > $i ? undef : ${$_[0]}++ } 1; my $lk = lazy { ${$_[0]} > $j ? undef : ${$_[0]}++ } 1; my $iterator = sub { lcomp { $i**2 == $j**2 + $k**2 ? [$k,$j,$i] : undef } \$i => $li, \$j => $lj, \$k => $lk; }; while ( defined( my $elem = $iterator->() ) ) { print Dumper( $elem ); <STDIN> eq "q\n" and exit; } # while
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
package Comp; use strict qw( vars subs ); use warnings; sub import { my( $class, $file, $line ) = caller(); # # comp { ... } ?VAR? => SUB, ... # my $comp; $comp = sub (&;@) { my( $sub, $var, $list, @x ) = @_; if ( my $r = ref($var) ) { if ( $r eq 'CODE' ) { push @x, $list; $list = $var; $var = undef; } # if elsif ( $r ne 'SCALAR' ) { die "Neither a SCALAR nor a CODE reference in comp() in file '$file' at line $line.\n"; } # elsif } # if else { $var = \${$class.'::'.$var}; } # else my @l; for ( $list->() ) { $$var = $_ if defined $var; push @l, @x ? $comp->( $sub, @x ) : $sub->(); } # for return @l; }; # # lcomp { ... } ?VAR? => LAZYSUB, ... # my $lcomp; $lcomp = sub (&;@) { my( $sub, $var, $list, @x ) = @_; if ( my $r = ref($var) ) { if ( $r eq 'CODE' ) { push @x, $list; $list = $var; $var = undef; } # if elsif ( $r ne 'SCALAR' ) { die "Neither a SCALAR nor a CODE reference in comp() in file '$file' at line $line.\n"; } # elsif } # if else { $var = \${$class.'::'.$var}; } # else while ( defined( my $elem = $list->() ) ) { $$var = $elem if defined $var; my($res) = @x ? $lcomp->( $sub, @x ) : $sub->(); return $res if defined $res; } # for return undef; }; # # lazy { ... } START # my $lazy = sub (&$) { my( $sub, $val ) = @_; my $start = $val; return sub{ my($res) = $sub->(\$val); $val = $start if ! defined $res; return $res; }; }; *{$class.'::comp' } = $comp ; *{$class.'::lcomp'} = $lcomp; *{$class.'::lazy' } = $lazy ; } # import 1; __END__
QuotePerl programmers are obsessed with syntax!
--- M.J.Dominus
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
{ my $j=0; my $resume=0; my $db=0; # Debugflag sub gather { goto $resume if $resume; # Dispatcher while (++$j<=5) { $resume="rein", goto raus unless ( $j%2 ); # Take rein: print "$j\n" if $db; } $resume=0; # Ausgang return; raus: print "-" if $db; return $j; } } while ( my $a=gather() ) { print "<<$a>>"; }
![]() |
|< 1 2 >| | ![]() |
19 Einträge, 2 Seiten |