Are you trying to do this?

   3 { I.   'b' = 'aaaaaaabbbbcccccc' NB. Find index of third b
10
   2 { I.   'c' = 'aaaaaaabbbbcccccc' NB. Find index of second c
13

> On 30 Aug 2022, at 17:57, 'Michael Day' via General <gene...@jsoftware.com> 
> wrote:
> 
> Pascal Jasmin's findxth benefits greatly from this tweak:
> 
> findxtha =: 4 : 0
> 'x m' =. xm x NB. m is sorted list of find indexes. x is match value.
> if. 0 = #m do. m =. 0 end.
> acc  =. i.0
> oset =. 0
> for_i. i. >./ m do.
> idx =. x i.~ oset }. y   NB. WAS idx =. x i.~ y
> if. idx = oset -~ # y do. acc return. end.
> if. i e. m do. acc =. acc , oset + idx end.
> oset =. oset + >: idx
> NB. y =. (>: idx) }. y  NB. Better NOT to do this!
> end.
> acc , oset + x i.~ oset }. y
> )
> 
>   (100; 0 2) (findxth -: findxtha) A
> 1
>    100 find2 A    NB. (One of) Raul's original suggestions
> 1599
>    (100; 0 1 2) ( findxtha) A
> 990 1599 2797
> 
> NB. These comparisons partly reproduce/endorse Devon's findings
> NB.  but also look at findxth and a couple of variants...
> 
> ts =:6!:2 , 7!:2@]
> 
>    ts'100 (1{I.@E.) A NB. Fails if there’s no (second) 100 in A'  NB. My 
> early offering!
> 0.512366 8.39904e6
>    ts'100 find2 A'    NB. (One of) Raul's original suggestions
> 4.1e_6 1280
>    ts'(100;0 1 2) findxth A'
> 0.708966 2.14749e9
>    ts'(100;0 1 2) findxtha A'
> 2.46e_5 2304
> 
>    ts'0 1 2 findxthdg 100; A'  NB. Don's proposal (renamed here)
> 0.232047 1.35533e8
> 
> 
> (All these in J904 under Windows 11 on this laptop.)
> 
> Not surprisingly,  (100; 99494) findxth A is really slow - I interrupted it!
> 
> 
> So it looks as if Raul's best to stick to one of his original methods,
> 
> especially since he points out that the Pritchard sieve only requires
> 
> an index of the second instance.
> 
> 
> Cheers,
> 
> 
> Mike
> 
> 
>> On 30/08/2022 15:04, Don Guinn wrote:
>> Oops! should have been
>> 
>> timespacex '100 findxth 1;A'
>> 
>> 0.0925588 1.35533e8
>> 
>> 
>> 
>>> On Tue, Aug 30, 2022 at 8:02 AM Don Guinn<dongu...@gmail.com>  wrote:
>>> 
>>> NB. Find the index of some instance of a value
>>> 
>>> findxth=:4 : 0
>>> 
>>> 'value list'=.y
>>> 
>>> try. x{,4$.$.value=list
>>> 
>>> catch. _1
>>> 
>>> end.
>>> 
>>> )
>>> 
>>> _20,\z=:?.100#10
>>> 
>>> 4 6 8 6 5 8 6 6 6 9 3 2 3 1 9 2 7 0 9 5
>>> 
>>> 7 7 9 7 4 8 7 4 2 1 1 0 4 3 9 3 2 7 4 4
>>> 
>>> 0 3 7 5 9 6 3 2 8 2 0 3 5 4 0 0 3 1 5 0
>>> 
>>> 4 0 2 9 2 4 0 0 7 7 5 7 3 1 6 3 1 5 8 9
>>> 
>>> 8 5 3 9 9 8 9 5 1 1 0 4 1 7 3 2 3 4 0 4
>>> 
>>> NB. Find index of the second occurence of 2
>>> 
>>> 1 findxth 2;z
>>> 
>>> 15
>>> 
>>> NB. Find index of the third from last of 7
>>> 
>>> _3 findxth 7;z
>>> 
>>> 69
>>> 
>>> NB. Try to find index of the tenth of 5 but does not exist
>>> 
>>> 9 findxth 5;z
>>> 
>>> _1
>>> 
>>> NB. find the index of the middle or next to middle 8
>>> 
>>> ({~<.@-:@#),4$.$.8=z
>>> 
>>> 48
>>> 
>>> A=. ?. 1e8#1e3
>>> 
>>> 100 (2 i.~ +/\)@:E. A
>>> 
>>> 1599
>>> 
>>> timespacex '100 (2 i.~ +/\)@:E. A'
>>> 
>>> 0.213069 1.20796e9
>>> 
>>> timespacex '100 findxth 2;A'
>>> 
>>> 0.0890775 1.35533e8
>>> 
>>> 
>>> On Mon, Aug 29, 2022 at 6:32 PM 'Pascal Jasmin' via General <
>>> gene...@jsoftware.com> wrote:
>>> 
>>>> I thought that perhaps this could be fast:
>>>> 
>>>> A=. ?. 1e8#1e3
>>>> 
>>>>  timespacex '100 (2 i.~ +/\)@:E. A'  NB. or = instead of E.
>>>> 0.460527 1.20796e9
>>>> 
>>>> 
>>>> This application happens to everyone at least once, if
>>>> 
>>>>  (u { I.@E.)
>>>> 
>>>> had special code where the result of u (or simply m) is presumed (for
>>>> speed optimization) to be a list/atom of top (rather than last) occurrences
>>>> of matches.
>>>> 
>>>> 
>>>> Here is a dyad that returns the xth occurrences (indexes) of x in y if
>>>> they exist.  where x is in format x (, or ;) m where m is the list of
>>>> indexes requested.
>>>> 
>>>> It is a bit slow due to the y =. n }. y step.
>>>> 
>>>> xm =: {. ,&boxopen }. NB. split arguments as head ; tail. assignment as
>>>> 'h t' =. xm y
>>>> 
>>>> findxth =: 4 : 0
>>>> 
>>>> 'x m' =. xm x NB. m is sorted list of find indexes. x is match value.
>>>> if. 0 = #m do. m =. 0 end.
>>>> acc =. i.0
>>>> oset =. 0
>>>> 
>>>> for_i. i. >./ m do.
>>>> 
>>>> idx =. x i.~ y
>>>> 
>>>> if. idx = # y do. acc return. end.
>>>> 
>>>> if. i e. m do. acc =. acc , oset + idx end.
>>>> 
>>>> oset =. oset + >: idx
>>>> 
>>>> y =. (>: idx) }. y
>>>> 
>>>> end.
>>>> 
>>>> acc , oset + x i.~ y
>>>> 
>>>> )
>>>> 
>>>> 1 1 3 4 6 findxth 0 1 0 0 1 0 1 1 1
>>>> 
>>>> 4 7 8
>>>> 
>>>> (1 ; 1 3 4 6) findxth 0 1 0 0 1 0 1 1 1
>>>> 
>>>> 4 7 8
>>>> 
>>>> 1 findxth 0 1 0 0 1 0 1 1 1
>>>> 
>>>> 1 NB. m is 0 (first item) if omitted.
>>>> 
>>>> 
>>>> 5 {. 100 I.@E. A
>>>> 
>>>> 990 1599 2797 4550 5073
>>>> 
>>>> 100 0 1 4 findxth A
>>>> 
>>>> 990 1599 5073
>>>> 
>>>> 
>>>> On Friday, August 26, 2022 at 05:27:46 p.m. EDT, Devon McCormick <
>>>> devon...@gmail.com> wrote:
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> I get these timings on J 9.04:
>>>> 
>>>>   A=. ?1e8#1e3
>>>>   ts '100 find2 A'
>>>> 2.4e_6 1536
>>>>   ts '100 (1{I.@E.) A'
>>>> 0.19722 8.39853e6
>>>>   ts '100 ({.@}.@(I.@E.)) A'
>>>> 0.200139 8.39866e6
>>>>   (100 find2 A) -: 100 (1{I.@E.) A
>>>> 1
>>>>   find2
>>>> ([: >: i.~) + [ i.~ ] }.~ [: >: i.~
>>>> 
>>>> 
>>>> On Fri, Aug 26, 2022 at 3:53 PM 'Mike Day' via General <
>>>> gene...@jsoftware.com> wrote:
>>>> 
>>>>> Does that include drop, }. ?  I suppose it can, since we only need to
>>>>> move the pointer to the start...  I’ll check on the laptop, once I’ve
>>>> done
>>>>> my Listener xwd.
>>>>> 
>>>>> (Last week’s was the quarterly numeric puzzle,  an ingenious
>>>> construction
>>>>> including among all the digits a few decimal points and solidus ( / )
>>>> for
>>>>> rationals!)
>>>>> 
>>>>> Cheers,
>>>>> Mike
>>>>> 
>>>>> 
>>>>> 
>>>>> Sent from my iPad
>>>>> 
>>>>>> On 26 Aug 2022, at 20:36, Raul Miller<rauldmil...@gmail.com>  wrote:
>>>>>> 
>>>>>> Updating arrays without generating a new copy was introduce in J805 --
>>>>>> https://code.jsoftware.com/wiki/System/ReleaseNotes/J805
>>>>>> 
>>>>>> So in J701, that approach would indeed be slower (since it's creating
>>>>>> a complete copy of the array).
>>>>>> 
>>>>>> Also, virtual blocks (which speed up the }. approach) were introduced
>>>>>> in J807. I guess I need to roll up my sleeves and do some
>>>>>> benchmarking...
>>>>>> 
>>>>>> Thanks,
>>>>>> 
>>>>>> --
>>>>>> Raul
>>>>>> 
>>>>>> On Fri, Aug 26, 2022 at 3:20 PM 'Mike Day' via General
>>>>>> <gene...@jsoftware.com>  wrote:
>>>>>>> These seem simpler and are possibly quicker,  at least in J701 on
>>>> this
>>>>> oldish iPad:
>>>>>>>  100 (1{I.@E.) A NB. Fails if there’s no (second) 100 in A
>>>>>>> 719
>>>>>>>  100 ({.@}.@(I.@E.)) A NB. Returns 0 in that case
>>>>>>> 719
>>>>>>> Easy to correct for such errors, of course.
>>>>>>> 
>>>>>>> I tried
>>>>>>>  A =. ?1000000#1000
>>>>>>>  find2 =: 13 : 'F + ((F=.>:y i. x) }. y) i. x' NB. No direct defs in
>>>>> J701
>>>>>>>  ts'100 find2 A'
>>>>>>> 0.020555 8.39091e6
>>>>>>>  ts'100 (1{I.@E.) A'
>>>>>>> 0.011503 76160
>>>>>>>  ts'100 ({.@}.@(I.@E.)) A'
>>>>>>> 0.007626 84864
>>>>>>> 
>>>>>>> Speed a bit better,  space quite a lot, if happy with time & space
>>>>> tests.
>>>>>>> Only you know if it’s wise to overwrite the first occurrence of V in
>>>> A!
>>>>>>> Cheers,
>>>>>>> 
>>>>>>> Mike
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> Sent from my iPad
>>>>>>> 
>>>>>>>> On 26 Aug 2022, at 19:36, Raul Miller<rauldmil...@gmail.com>
>>>> wrote:
>>>>>>>> i. returns the index of the first occurrence of a value within an
>>>>> array.
>>>>>>>> So, when implementing an algorithm which needs the index of the
>>>> second
>>>>>>>> occurrence of the value within a (large) array, we need to do some
>>>>>>>> additional work.
>>>>>>>> 
>>>>>>>> let's say that our array is A, the value is V
>>>>>>>> 
>>>>>>>>  F=: A i. V  NB. the index of the first occurrence of V
>>>>>>>> 
>>>>>>>> What's the most efficient way of finding the second occurrence?
>>>>>>>> 
>>>>>>>> One possibility is
>>>>>>>>  S=: (1+F) + ((1+F) }. A) i. V
>>>>>>>> 
>>>>>>>> Another possibility, assuming that V is numeric and not zero, would
>>>> be
>>>>>>>>  S=: (0 F} A) i. V
>>>>>>>> 
>>>>>>>> But A is large, so perhaps a faster approach would be:
>>>>>>>> S=: {{ while. V~:y{A do. y=. y+1 end. y }} F
>>>>>>>> 
>>>>>>>> (Which has me wishing that S=: A i.!.F V would do the job, though
>>>> I'm
>>>>>>>> not sure that that's completely appropriate...)
>>>>>>>> 
>>>>>>>> But, we can probably eliminate the need to generate a copy of A
>>>> with a
>>>>>>>> little extra work:
>>>>>>>> 
>>>>>>>>  A=: 0 F} A
>>>>>>>> S=: A i. V
>>>>>>>> A=: V F} A
>>>>>>>> 
>>>>>>>> It seems to me that this is probably going to be the fastest
>>>> approach.
>>>>>>>> Can anyone think of a faster approach (or something with comparable
>>>>>>>> speed which isn't quite so unwieldy?)
>>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> 
>>>>>>>> --
>>>>>>>> Raul
>>>>>>>> 
>>>> ----------------------------------------------------------------------
>>>>>>>> For information about J forums see
>>>> http://www.jsoftware.com/forums.htm
>>>> ----------------------------------------------------------------------
>>>>>>> For information about J forums see
>>>> http://www.jsoftware.com/forums.htm
>>>>>> ----------------------------------------------------------------------
>>>>>> For information about J forums see
>>>> http://www.jsoftware.com/forums.htm
>>>>> ----------------------------------------------------------------------
>>>>> For information about J forums seehttp://www.jsoftware.com/forums.htm
>>>>> 
>>>> 
>>>> --
>>>> 
>>>> Devon McCormick, CFA
>>>> 
>>>> Quantitative Consultant
>>>> 
>>>> ----------------------------------------------------------------------
>>>> For information about J forums seehttp://www.jsoftware.com/forums.htm
>>>> ----------------------------------------------------------------------
>>>> For information about J forums seehttp://www.jsoftware.com/forums.htm
>>>> 
>> ----------------------------------------------------------------------
>> For information about J forums seehttp://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to