Here is a take on "coroutine" simulation in J.

NB. J "coroutine" simulation

NB. =========================================================
NB. "coroutine" utilitites

yield=: 3 : ('13!:8]200';'y.')
resume=: (13!:5) bind ''
crbegin=: (13!:0)@1:@(13!:15)
crend=: (13!:0)@0:(13!:15)

NB. =========================================================
NB. demo

iEnum1=: yield"[EMAIL PROTECTED]

iEnum2=: 3 : 0
  for_i. i.y. do.
    yield <i
  end.
)

iEnum3=: 3 : 0
  i=. 0
  while. yield i do. i=.i+1 end.
)

test=: 3 : 0
  crbegin 'resume smoutput y.'
  iEnum1 5
  crend ''

  r=: ''
  crbegin 'resume r=: r,y.'
  iEnum2 5
  crend ''
  smoutput r

  crbegin 'resume y.=.y.<3 [ smoutput y.'
  iEnum3 ''
  crend ''
)



NB. =========================================================

   test''
0
1
2
3
4
„¡„Ÿ„¦„Ÿ„¦„Ÿ„¦„Ÿ„¦„Ÿ„¢
„ 0„ 1„ 2„ 3„ 4„ 
„¤„Ÿ„¨„Ÿ„¨„Ÿ„¨„Ÿ„¨„Ÿ„£
0
1
2
3


--- p j <[EMAIL PROTECTED]> wrote:

> There's probably another name for this, but inspired
> from python terminolgy, a generator form of a function
> is one that is recursively called, but doesn't
> internally determine when to stop recursing.  In
> Python and other languages, generators produce a lazy
> stream of values, where a "coroutine" will tell it
> when to stop.  In J, a generator form is just a verb
> that returns the input for its next iteration.
> 
> Here is Oleg's very pretty but very slow solution to
> Euler104:
> http://mathschallenge.net/index.php?section=project&ref=problems&id=104
> 
>    fib=: >:@{. , {: , +/@}.
>    pan=: *./@(9 _9&(('123456789'"_ -: /:~)@{."0
> _))@":"0
>    [EMAIL PROTECTED]([EMAIL PROTECTED]:)^:(_) 1 1 1x
> 
> fib is actually 2 loosely related  generator forms for
> calculating the next fibonacci number as well as the
> index position in the fibonacci sequence of that
> number.  Oleg built a monolithic generator form
> because its hard to work with them separately.
> 
> J essentially encourages building a monolithic
> generator form as opposed to combining and reusing
> simpler generator forms.  The problem with this
> approach only becomes more apparent when combining
> several or complex generator forms: basically any
> effort used to create a generator form is partially
> wasted because it is not directly reusable without
> stipping away the context and other code you used with
> it the first time.
> 
> Look at the SIDE verb (which could be useful as an
> Evoke Gerund built in option).  SIDE takes a gerund
> left argument and boxed right arguments and returns a
> boxed list of the same shape as y,  the result of x0
> y0 ; x1 y1 ; ... xn yn (where x0, x1,... xn are verbs)
> 
> SIDE =: 4 : 0
> a=. 0$0
> for_i. i.(#x.) do.
>  a=. a , ((i_index{x.)`: 6) &.> i_index{y.
> end.
> )
> 
> fibG =: {: , +/
> >:`fibG SIDE ^:(10) 1; 1 1
> „¡„Ÿ„Ÿ„¦„Ÿ„Ÿ„Ÿ„Ÿ„Ÿ„Ÿ„¢
> „ 11„ 89 144„ 
> „¤„Ÿ„Ÿ„¨„Ÿ„Ÿ„Ÿ„Ÿ„Ÿ„Ÿ„£
>    fib ^:(10) 1 1 1
> 11 89 144
> 
> Taking the functions separately means defining them is
> much easier.
> 
> Going back to Oleg's solution to prob 104, the reason
> it is slow is that more work than is necessary is
> being done.  The problem is to find the first
> fibonacci number that is pandigital in its last 9 and
> first 9 digits.  fibonnacci sequence quickly gets to
> very large numbers.  An optimized logical approach is
> to just track the fibonacci mod 1e10 sequence, and
> only when that is pandigital, calculate the full kth
> fib element (using binet algorithm)
> 
> The AND verb uses the same format as the SIDE verb. 
> Boxed arguments.  It only returns 1 or 0.  1 if all
> its verb applications evaluate to non 0 values.  If
> any expression results in 0, no further evaluations
> take place, and 0 is returned. 
> 
> AND =: 4 : 0 NB. Implements short circuit for
> expressions (Stops evaluating on first false)
> for_i. i.(#x.) do.
>  if. 0 = (((i_index{x.)`: 6) > i_index{y.) do.  0
> return. end.
> end.
> 1
> )
> 
> Here is an improved version of Oleg's p104 solution
> using the SIDE and AND verbs.  Here first are some of
> the side calculating verbs for the equation.
> 
> fibfirst=: 3 : 0
> p=.
> 1.61803398874989484820458683436563811772030917980576286213544862270526046281890
> NB. -: >: ( %: 5)
> NB. y=. x: y.
> a =. ((y.) * (10^. p)) - 10^.2.2360679774997898  
> a =. 10 + a - (<. a) 
> 10^a
> )
> fibfirst9 =: 9&{. &.":@fibfirst
> fib9G=: {:, (1e9 | +/) NB. Calcs fib mod 1e9 sequence
> 
> (>:`fib9G & SIDE)[EMAIL PROTECTED](('123456789'"_ -:
> /:~)@":"0@(]`fibfirst9) AND (({:@>@{:);(>@{.)))(^:_)
> 2; 1 1x
> 
> runs 80 times faster with 95 times less space.
> ts '(>:`fib9G & SIDE)[EMAIL PROTECTED]((''123456789''"_ -:
> /:~)@":"0@(]`fibfirst9) AND (({:@>@{:);(>@{.)))(^:_)
> 2; 1 1x'
> 33.9278156861 19904
> ts '[EMAIL PROTECTED]([EMAIL PROTECTED]:)^:(_) 1 1 1x'
> 2463.95762646 1841792
> 
> 
> 
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around 
> http://mail.yahoo.com 
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to