I have not studied this problem.  However, when I saw
your solution

    findH=:4 :0
H=. (>:x){.1
for_e. y do.
   H=.(+ (-e)&(|.!.0)) H
end.
H
)

I immediately thought "power operator", and I am surprised
that I don't find it in your latest

(# -~ (+/@:{ [: > [: (] + |.!.0)&.>/  <@- , <@({.&1)@>:@{:)) B



----- Original Message -----
From: Henry Rich <[email protected]>
Date: Saturday, March 12, 2011 14:38
Subject: Re: [Jprogramming] greplin challenge
To: Programming forum <[email protected]>

>     (# -~ (+/@:{ [: > [: (] + |.!.0)&.>/  
> <@- , <@({.&1)@>:@{:)) B
> 179
> 
> Henry Rich
> 
> On 3/12/2011 5:19 PM, Henry Rich wrote:
> > Hey presto!  You're right.  Since you don't need to 
> know the subsets,
> > you don't have to do the backtracking.  For that matter, 
> you can do it
> > with just one copy of the H vector: i{H tells how many ways 
> you can add
> > up items to get i; so just find H for the whole input vector, 
> and add
> > up the values corresponding to B.  You them have to 
> remove the
> > singletons that created one-element sets that added to equal 
> themselves,> because you were supposed to be looking at only 
> smaller numbers.  You get:
> >
> >      findH=:4 :0
> > H=. (>:x){.1
> > for_e. y do.
> >     H=.(+ (-e)&(|.!.0)) H
> > end.
> > H
> > )
> >
> >      (#B) -~ +/ B { ({:B) findH B
> > 179
> >
> >
> > Probably not to hard to make tacit, too.
> >
> > Henry Rich
> >
> > On 3/12/2011 4:57 PM, Marshall Lochbaum wrote:
> >> A solution with this method:
> >>
> >>      B=: 3 4 9 14 15 19 28 37 47 50 
> 54 56 59 61 70 73 78 81 92 95 97 99
> >>      sums=:4 :0
> >> H=. (>:x){.1
> >> for_e. y do.
> >>     H=.(+ (-e)&(|.!.0)) H
> >> end.
> >> {:H
> >> )
> >>      +/ B sums&>   (i.22) 
> {.&.>   (<B)
> >> 179
> >>
> >> Note that by changing +. to +, HH is not needed.
> >>
> >> Marshall
> >>
> >> -----Original Message-----
> >> From: [email protected]
> >> [mailto:[email protected]] On Behalf Of Henry Rich
> >> Sent: Saturday, March 12, 2011 9:49 AM
> >> To: Programming forum
> >> Subject: Re: [Jprogramming] greplin challenge
> >>
> >> I think there is, but I don't have time to code the 
> interesting part, which
> >> resembles the integer knapsack problem.  I will outline 
> the solution.
> >>
> >> Examining each value v in turn, the question is to count the 
> subsets of
> >> smaller values to find those that add up to v.  So: 
> count the subsets of a
> >> set S that add up to a desired target v.
> >>
> >> To do that, you create a Boolean vector H which is v+1 long 
> and represents
> >> which totals can be reached by combinations of elements of 
> the set.  The
> >> idea is to consider the elements of S in turn, making a new 
> copy of H after
> >> considering each element.  This will give an array HH 
> which you then
> >> backtrack through to find all the paths leading from the 
> bottom-right to the
> >> top-left.
> >>
> >> Initialize HH =. ,: H =. (>:v) {. 1
> >>
> >> for_e. S do.
> >>      NB. The values reachable 
> possibly using e are all the values
> >>      NB. reachable not using e, and 
> all those values plus e:
> >>      H =. H +. (-e) |.!.0 H
> >>      NB. Remember the new H after 
> considering e
> >>      HH =. HH , H
> >> end.
> >>
> >> Now, if {: H is 1, there is a combination of elements that 
> adds to v.
> >> It remains to find all such subsets.  You do this by 
> going back through the
> >> rows of HH.
> >>
> >> The plan is, keep a list of reachable values, and for each 
> one, the list of
> >> sets that reach.  Initially the list of reachable values 
> is just v, and its
> >> corresponding list of sets is empty.
> >>
> >> Discard the last row of HH.  Then, for each row starting 
> with the last, see
> >> which of the reachable values can be reached if you include, 
> or exclude, the
> >> Si that produced the row.  You will have a new set of 
> reachable values and
> >> corresponding subsets.
> >>
> >> When you get back to the first row of HH, you will have all 
> the subsets.
> >>
> >> The performance of this dynamic-programming solution is 
> proportional to
> >> (v*(number of items of S)); much faster than enumerating subsets.
> >>
> >> Henry Rich
> >>
> >>
> >> On 3/12/2011 5:37 AM, chris burke wrote:
> >>> This challenge http://challenge.greplin.com seems to have 
> missed the
> >>> forum. Each is straightforward in J.
> >>>
> >>> The last is to count the subsets of an array where the 
> largest number
> >>> is the sum of the remaining numbers. The given array is
> >>>
> >>> B=: 3 4 9 14 15 19 28 37 47 50 54 56 59 61 70 73 78 81 92 95 
> 97 99
> >>>
> >>> A brute force calculation is:
> >>>       <: +/ B ((+/=2*{:) @: 
> #~)"1 #:i.2^#B
> >>> 179
> >>>
> >>> This takes a few seconds. Is there a better way?

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to