Thread Pythagorische Tripel (18 answers)
Opened by Ronnie at 2008-10-19 15:57

MatthiasW
 2008-10-29 23:13
#115839 #115839
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
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:
Code (perl): (dl )
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.

Auf den ersten Blick sah das Modul ganz gut aus, und auch der Name hat so schön gepasst ;) Aber hast Recht, ist tatsächlich nicht gerade toll..

Hier mein Ansatz:
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
#!/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";

Besonders störend finde ich die ::, mir ist nur nichts besseres eingefallen, was halbwegs sauber wäre.

Lagert man die comp-Funktion jedoch in ein Modul aus, dann kann man auch mit package-Variablen arbeiten.
Comp.pm:
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
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;

Hier ein Beispiel zu dem Modul:
Code (perl): (dl )
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";

MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'

View full thread Pythagorische Tripel