[Cologne-pm] finde aritmatik operator fuer 57a27b37c17d47=777

A. Pagaltzis pagaltzis at gmx.de
Sun Nov 27 17:15:56 PST 2005


* Cem Sakaryali <cem.sakaryali at easi.de> [2005-11-28 01:00]:
> @a=@b=@c=@d=('*','-','+','/');
> 
> foreach $a (@a) {
> foreach $b (@b) {
> foreach $c (@c) {
> foreach $d (@d) {
> $string = eval ("57 $a 27 $b 37 $c 17 $d 47");
> if ($string==777) {print "a$a b$b c$c d$d\n"}
> }
> }
> }
> }
> 
> 
> Ich mag perl :D

Hübsch! :-)

Aber warum vier Arrays? :-)

Ausserdem würde ich die Bedingung gleich in den Ausdruck mit
reinschreiben. Dann kannst du den ganzen Ausdruck inkl. Ergebnis
an einer einzigen Stelle ummodeln. Dann würde ich das eval() auch
gleich in die if-Bedingung verschieben und den erfolgreichen
Ausdruck als solchen ausgeben.

Das ergibt zusammen:

    my @ops = qw( * - + / );

    for my $i ( @ops ) {
        for my $j ( @ops ) {
            for my $k ( @ops ) {
                for my $l ( @ops ) {
                    my $expr = "777 == 57 $i 27 $j 37 $k 17 $l 47";
                    print $expr, "\n" if eval $expr;
                }
            }
        }
    }

($a und $b solltest du übrigens generell meiden, weil das die
Spezialvariablen sind, die sort() verwendet.)

Das kannst du dann schön in ein bisschen Zauberei mit sprintf und
Set::CrossProduct umschreiben:

    use Set::CrossProduct;

    my @ops = qw( * + - / );
    my $expr = '777 == 57 %s 27 %s 37 %s 17 %s 47';

    my $xp = Set::CrossProduct->new( [ map \@ops, $expr =~ /%s/g ] );
    while( my @attempt = $xp->get ) {
        my $attempt = sprintf $expr, @attempt;
        print $attempt, "\n" if eval $attempt;
    }

Die Schachtelungstiefe ergibt sich hier implizit aus der Anzahl
der %s-Platzhalter im Ausdruck.

Gruss,
-- 
#Aristoteles
*AUTOLOAD=*_;sub _{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;


More information about the Cologne-pm mailing list