Re: help with simplifying program
by BrowserUk (Patriarch) on May 24, 2013 at 05:36 UTC
|
That makes no sense?
Each of your inner loops is limited to the value of the preceding loop counter-1, so can never attain a value that would trigger your condition.
Ie. $x is limited to $w-1, so $x can never become equal to $w + $s for any value of $s, unless $s was -1 or less, but your $s loop start from 1 and increases.
In other words; your unless condition will always be false, and so it is doing nothing (except consuming cycles).
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
|
| [reply] [d/l] [select] |
Re: help with simplifying program
by tobyink (Canon) on May 24, 2013 at 05:38 UTC
|
Untested, but makes sense to me...
foreach my $w (3..100) {
foreach my $x (2..$w-1) {
foreach my $y (1..$x-1) {
foreach my $z (0..$y-1) {
next if ($z-$y==$y-$x and $y-$x==$x-$w);
...;
}
}
}
}
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
| [reply] [d/l] |
Re: help with simplifying program
by BillKSmith (Monsignor) on May 24, 2013 at 14:19 UTC
|
| [reply] |
|
# $lep means smallest nonzero root in the interval [0, $rep]
# $rep means right endpoint of the interval [0, $rep]
my $lep = int 1;
my $rep = int 100;
foreach my $x ($lep+2 .. $rep ) {
foreach my $y ($lep+1 .. $x-1 ) {
foreach my $z ($lep .. $y-1 ) {
foreach my $s (1..$rep/4) {
unless ($y == $x + $s && $z == $y + $s ) {
# assigns a truth value to whether or not it is wi
+thin 0.0001 of an integer (1=true, 0=false)
sub is_approximately_an_integer {
my $eps = 0.0001;
while( my $w = shift ) {
# need to use "round", "int" does not work!
return 0 if abs( $w-round($w) ) > $eps;
}
return 1
}
}
}
push @wants,
map { { join(', ', $x, $y, $z) => $_ } }
grep { is_approximately_an_integer( @$_ ) } [
poly_roots(
poly_derivative(
# expanded form of x*(x - $x)*(x - $y)*(x
+- $z)
1, -$x - $y - $z, $x*$y + $x*$z + $y*$z, -
+$x*$y*$z, 0
)
)
];
}
}
}
| [reply] [d/l] |
|
Oops, I was slightly wrong. Combinations will only replace three of your loops. You still have to select the applicable combinations.
use Algorithm::Combinatorics qw(combinations);
my $lep = int 1;
my $rep = int 100;
my $iter = combinations( [$lep+2 ..$rep], 3 );
while (my $c = $iter->next) {
my ($x, $y, $z) = @$c;
foreach my $s (1..$rep/4) {
# as before
}
}
| [reply] [d/l] |
|
use strict;
use warnings;
use Algorithm::Combinatorics qw(combinations);
my $rep = 5; # should be 100
my @data = 0..$rep;
my $iter = combinations( \@data, 4 );
while( my $p = $iter->next ) {
my ( $z, $y, $x, $w ) = @$p;
next unless $w-2*$x+$y or $x-2*$y+$z;
print "$w, $x, $y, $z\n";
}
| [reply] [d/l] |
|
Re: help with simplifying program
by snoopy (Curate) on May 24, 2013 at 05:50 UTC
|
Hi There,
I'm not sure, if the unless condition is actually filtering anything:
use strict;
my $n1;
my $n2;
foreach my $w (3..100) {
foreach my $x (2..$w-1) {
foreach my $y (1..$x-1) {
foreach my $z (0..$y-1) {
foreach my $s (1..20) {
$n1++;
unless ( $x == $w + $s
&& $y == $x + $s
&& $z == $y + $s ) {
$n2++;
}
}
}
}
}
}
print "n1: $n1\n";
print "n2: $n2\n";
Output:
n1: 81658500
n2: 81658500
| [reply] [d/l] [select] |
Re: help with simplifying program
by hdb (Monsignor) on May 24, 2013 at 08:40 UTC
|
From your description I take you want (w, x, y, z) such that 0 <= z < y < x < w <= 100 and not w-x == x-y == y-z. In order to achieve this I would parametrize the loops using the differences dwx = w-x, dxy = x-y, dyz = y-z.
use strict;
use warnings;
my $n = 5; # should be 100
my $c1 = my $c2 = 0;
for my $w (3..$n) {
for my $dwx (1..$w-2) {
my $x = $w - $dwx;
for my $dxy (1..$x-1) {
my $y = $x - $dxy;
for my $dyz (1..$y) {
my $z = $y - $dyz;
$c1++;
next unless $dwx != $dxy or $dxy != $dyz;
$c2++;
print "$w $x $y $z\n";
}
}
}
}
print "Found $c2 out of $c1 combinations\n";
UPDATE: Changes next unless... for better readibility.
| [reply] [d/l] [select] |
|
next unless $dwx != $dxy and $dxy != $dyz;
otherwise you will not get all of the valid combinations | [reply] [d/l] [select] |
|
next if $dwx == $dxy and $dxy == $dyz;
which I should have used in the first place.
| [reply] [d/l] [select] |
|