Re: Get all combinations of n digits among m digits

new topic     » goto parent     » topic index » view thread      » older message » newer message

Very good, my 15.1s -> your 8.9s -> next's 5.3s -> hopefully last one's 4.9s, not a bad day week's work!
I couldn't understand why you were testing nr=1, if nr=1 and ns!=ne then ?9/0 end if never triggered, so I took it out...

Slicing just the once for both recursive calls saves a fair chunk

sequence combis = {}  
  
procedure recurse(sequence remaining,               /* digits remaining to compute */  
                  integer ne,                       /* number of digits expected for a valid combination */  
                  sequence selected = {})           /* digits already selected for a potential combination */  
  integer nr = length(remaining)   -- number of digits remaining to compute  
  integer ns = length(selected)    -- number of digits already selected for a potential combination  
  if ns+nr = ne then  
    combis = append(combis, selected & remaining)  
  elsif ns = ne then  
    combis = append(combis, selected)  
  else 
    object r1 = remaining[1] 
    remaining = remaining[2..$] 
    -- select next  
    recurse(remaining, ne, selected & r1)  
    -- skip next  
    recurse(remaining, ne, selected)  
  end if  
end procedure  

Not slicing at all, except for when "all the rest", saves another 10%

sequence combis = {}  
  
procedure recurse(sequence remaining,               /* digits remaining to compute ... */  
                  integer needed,                   /* number of digits expected for a valid combination */  
                  integer done=0,                   /* ... but do not use remaining[1..done] */  
                  sequence selected = {})           /* digits already selected for a potential combination */  
  if done=0 then combis = {} end if /* you can and probably will thank me later for that! */ 
  integer nr = length(remaining)-done   -- number of digits remaining to compute  
  integer ns = length(selected)    -- number of digits already selected for a potential combination  
  if ns+nr = needed then  
    combis = append(combis, selected & remaining[done+1..$]) 
  elsif ns = needed then 
    combis = append(combis, selected)  
  else 
--  elsif ns+nr>needed then 
    done += 1 
    -- select next  
    recurse(remaining, needed, done, selected & remaining[done])  
    -- skip next  
    recurse(remaining, needed, done, selected)  
  end if 
end procedure  

Slightly miffed that final commented-out test doesn't help and actually slows it down a smidge, but oh well.
Then again, that's the main point here: "all the rest" is not only slightly faster but cuts out a whole heap of pointless "not enough" recursions, I think.

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu