Thread Pythagorische Tripel
(18 answers)
Opened by Ronnie at 2008-10-19 15:57
Mit nachfolgendem Modul gehts auch so:
Code (perl): (dl
)
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 Wobei $iterator eigentlich überflüssig ist. lazy() spart im Prinzip nur Tipparbeit, beim erstellen einer Closure und lcomp() funktioniert fast genauso wie comp(), nur dass die einzelnen Funktionen undef zurückgeben um zu signalisieren, dass sie keine weiteren Werte mehr liefern. Hier das Modul: Code (perl): (dl
)
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__ Falls man die Werte der Listen bei comp() / lcomp() in Variablen speichern möchte, kann man jetzt anstatt eines Strings eine Skalar-Referenz übergeben, in die geschrieben wird. Ein String ist immer noch möglich, dann wird die jeweilige package-Variable verändert. edit: Die Fehlermeldung der beiden die()s in die nächste Zeile geschoben. MfG perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
|