When using dyad I, how does one control how to handle the various edge 
conditions gracefully (specifically out-of-bounds values and
values exactly between intervals)?  

        (1) y is greater or lesser than the head or tail of x
        (2) y is exactly equal to a value of x, and I want to 
            decide if that means it should fall to the left
            of the value or to the right.

All of this with an eye to performance, of course (I don't want to do the 
equality outer product x=/y to handle edge conditions, for
example). 

For example, how would you solve http://rosettacode.org/wiki/Price_Fraction 
cleanly? My first quick hack is:

        'ge lt out'=:ALL=:|: 0 ". ];._2 noun define
                0.00 0.06  0.1
                0.06 0.11 0.18
                0.11 0.16 0.26
                0.16 0.21 0.32
                0.21 0.26 0.38
                0.26 0.31 0.44
                0.31 0.36  0.5
                0.36 0.41 0.54
                0.41 0.46 0.58
                0.46 0.51 0.62
                0.51 0.56 0.66
                0.56 0.61  0.7
                0.61 0.66 0.74
                0.66 0.71 0.78
                0.71 0.76 0.82
                0.76 0.81 0.86
                0.81 0.86  0.9
                0.86 0.91 0.94
                0.91 0.96 0.98
                0.96 1.01    1
        )
        
                NB.  Price buckets; the infinities are sentinels allowing me 
                NB.  to handle any unknown price.
                BUCKETS =: __ , _ ,~ ge , {: lt
                
                NB.  Test exactly at buckets, and well within buckets
                TESTS   =:  _9999 9999 (1 _2) } }: , (,. _ ,~ 2 (+/%#)\]) 
BUCKETS
                
                NB.  Low unknown prices = __ , high unknown = _ .
                PRICES  =:  __ __ , _ ,~ out   
                
                smoutput TESTS ,: PRICES {~ (_1e_16 + BUCKETS) I. TESTS

(the handling of out-of-bounds values isn't required by the RC task, but I'm 
just using the RC task to illustrate common issues I
have with I.)

Reasons I don't like this hack (bearing in mind I didn't think much, just wrote 
code until I got a solution that mostly worked):

        (a) It's still not right (for the input 1.01 the output 
            is 1, where it should be _), 
        (b) The addition of _1e_16 feels hacky and will break if 
            I. ever gets tolerant (or under various other conditions)
        (c) I had to prepend 2 copies of __ to prices, instead of
            1, to get this to work.

Also, I note that the Python solution leverages a function called 
bisect.bisect_right -- implying there's a bisect.bisect_left.  Is
I. inherently biased in one direction or the other, or is this managed by using 
different grades or applying reversals?

-Dan
        

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

Reply via email to