Here's an array-oriented approach.

The key idea is to convert the list of quantities to a running total, so 
that each input and output is identified uniquely in the stream of results.

    in =: 1000 2000 1500 1000
    out =: 500 3000 1000
    ]ins =: 0 , +/\ in
0 1000 3000 4500 5500
    ]outs =: 0 , +/\ out
0 500 3500 4500

Now we can write a verb that takes an interval representing one output 
and looks up in the list representing all the inputs, to find which 
inputs correspond to that output:

NB. x is low#, high#, y is list of #s, result is table of
NB. (intvl in y), (amount allocated to intvl)
fifo1 =: ([: ((] ,. {~)  I.@:*) 2 -~/\ {:@[ <. {...@[ >. ])"1

The <. and >. have the effect of excluding all the intervals that don't 
apply, and then it's just a matter of converting the nonempty intervals 
to the desired output format.

    0 500 fifo1 ins
0 500
    500 3500 fifo1 ins
0  500
1 2000
2  500
    3500 4500 fifo1 ins
2 1000

To do all the calculations, just apply fifo1 on each interval of outputs:

NB. x is list of outputs, y is list of inputs
NB. Convert each to running total, then allocate each output
NB. among the correct inputs.  Then, prepend the number of
NB. the output to give a table of
NB. output-intvl input-intvl amount
fifo =: [: ; i...@#@[ ,.&.> (2&(]\)@[ <@fifo1 ])&(0 , +/\)

    out fifo in
0 0  500
1 0  500
1 1 2000
1 2  500
2 2 1000

WARNING!! This two-liner is not ready for production.  It runs in time 
O(*:n).  But I think it would be easy to bring to O((*^.)n) by adding a 
step where, after converting the lists to running sums, you use

(inputs I. outputs)

to reduce the number of inputs you have to examine for each output; then 
run fifo1 on the reduced set and add the starting index back into the 
result.  Details left to the motivated.

Henry Rich


bill lam wrote:
> I want to calculate a fifo problems to match in-qty to out-qty, 
> 
> Assuming all qty are positive
> in-qty  1000 2000 1500 1000
> out-qty  500 3000 1000
> then a verb fifo, such that
> 
> 500 3000 1000 fifo 1000 2000 1500 1000
> 
> will give
> 
> 0 0  500
> 1 0  500
> 1 1 2000
> 1 2  500
> 2 2 1000
> 
> where format in each row, 
> index-to-outqty   index-to-inqty   qty-allocated
> 
> I have written a simple scalar C algorithm below and want to learn how to do 
> it
> in vector J approach.
> 
> fifo=: 4 : 0
> out=. x
> in=. y
> ox=. ix=. 0 [ z=. 0 3$0
> while. (ox<#out) *. ix<#in do.
>   a=. ox{out
>   b=. ix{in
>   if. a=b do.
>     z=. z, ox, ix, a
>     out=. 0 ox}out
>     in=. 0 ix}in
>     ox=. >:ox [ ix=. >:ix
>   elseif. a<b do.
>     z=. z, ox, ix, a
>     out=. 0 ox}out
>     in=. (b-a) ix}in
>     ox=. >:ox
>   elseif. a>b do.
>     z=. z, ox, ix, b
>     out=. (a-b) ox}out
>     in=. 0 ix}in
>     ix=. >:ix
>   end.
> end.
> z
> )
> 
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to