No, no, there's a much better way.
NB. x is output, y is input, result is fifo allocation
fifo =: 4 : 0
NB. Convert to running sum
outs =: +/\ x
ins =: +/\ y
NB. Interleave in & out to give the unique intervals
uniq =: ~. /:~ ins , outs
NB. Look up each interval in input & output, append length
(outs I. uniq) ,. (ins I. uniq) ,. (2 -~/\ 0,uniq)
)
out fifo in
0 0 500
1 0 500
1 1 2000
1 2 500
2 2 1000
3 3 1000
Notice that this shows the amount left over at the end.
Henry Rich
Henry Rich wrote:
> 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
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm