in reply to Re: Efficient enumeration of pandigital fractions
in thread Efficient enumeration of pandigital fractions
==== for instance if you decide to go from left to right left with $i=4
i * efgh = abcd
the multiplication table would look like
DB<14> $i=4; for $x (1..9) { next if $x==$i; $p = $i*$x; $C=int($p/1 +0); $S=$p%10; print "$i * $x = $p \t$C $S\n" } 4 * 1 = 4 0 4 4 * 2 = 8 0 8 4 * 3 = 12 1 2 4 * 5 = 20 2 0 4 * 6 = 24 2 4 4 * 7 = 28 2 8 4 * 8 = 32 3 2 4 * 9 = 36 3 6
# 987654321 @carry0 = (1,2) , $carry0 = vec(11) @carry1 = (3) , $carry1 = vec(0100) @carry2 = (5,6,7) , $carry2 = vec(1110000) @carry3 = (8,9) , $carry3 = vec(110000000)
( update when going from left to right you have to also put 7 into @carry3, because 28 could add to a former carry. going from right to left is indeed easier ...)
==== after trying $e=1 you know that
@remaing=(2,3,5,6,7,8,9) => $remaining = vec(111110110)
$a = $i*$e + carry(4*f) = 4*1 + range(0..3)
the carry range filter for 0..3 is vec(1111) shifted accordingly for 4 is $carryrange=vec(1111000)
$remaining & $carryrange = vec(1110000) => possible $a are in (5,6,7)
=> carry=0 is (obviously) forbidden $remaining & ($carry1 | $carry2 | $carry3) = vec(111110100) => possible $f are in (9,8,7,6,5,3)
using this approach has several advantages
this approach will lead to a very efficient branch and bound already, I'm confident you can find even more "filter rules" to bound more efficiently.
Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery
FootballPerl is like chess, only without the dice
|
|---|