Hello Raul, I have been able to understand the code you sent me. Thanks. Your code helped me to learn some other nuances of J as well! I had come to a somewhat different solution before I saw you reply. Here it is for comparison. Actually I did not use ;: at all. Instead, I chose a more traditional textbook definition of a state machine (here I skip the input mapping stage, and consider 0,1,2 for a,b,c):
sm=:3 :'(s=: s sf y) ] s of y' NB. s=state (a global), sf=state function, of=output function sf and of can be defined any way I like. Here I used the table look up method. sf=.4 :'(<x, y,0){ sot ' of=.4 :'(<x, y,1){ sot ' The state/output table sot is again like a traditional table, the output being 0,1,2,3 (0=none, 1='alpha',2='beta',3='c') sot=. 4 3 2 $ 1 1 2 2 3 3 1 0 2 2 3 3 1 1 2 0 3 3 1 1 2 2 3 3 The output mapping is om=.(i.0);'alpha';'beta';'c' To run the machine: s=.0 out=.(sm"0) 0 0 0 1 1 1 1 2 2 ;out { om I was trying to compare your approach with mine: 1) I guess yours is more efficient as it uses the primitive ;: 2) I am relying on the undocumented feature that (sm"0) will apply on each entry sequentially from left to right. 3) My approach is more flexible, especially when I use the machine as a driver for some software (say in robotics). I say this with some apprehension, as J might have some surprise up its long sleeve to disprove this point. For example, what if I want something like this: a run of a's should become 'alpha' if preceeded by a 'b', but should become 'zeta' otherwise. Then I guess in your approach the replacer function will need to be made more complex (please correct me if I am wrong here). 4) There are some situtations where the state function can be efficiently implemented algorithmically (instead of by table look up, which will require a huge table). Then use of ;: will become difficult. I would love to hear your comments. Thanks and regards, Arnab On Mon, Feb 19, 2018 at 2:02 PM, Arnab Chakraborty <arnab...@gmail.com> wrote: > Wow, thank you so much, friends, for so much help. With my present level > of profficiency in J, I'll need some time before I can make complete sense > of the J codes. Shall report back after that. > > > On 19 Feb 2018 01:10, "Cliff Reiter" <reit...@lafayette.edu> wrote: > >> A cut variant of "words" >> (<;.1~1,2 ~:/\ ])I >> >> +-+----+---+---+-----+----+ >> >> |a|bbbb|aaa|ccc|aaaaa|bbbb| >> >> +-+----+---+---+-----+----+ >> >> >> >> >> On 2/18/2018 1:22 PM, David Lambert wrote: >> >>> While not answering your question, the verbs f f g and h solve the >>> problem. The first f uses complex copy to expand the input into same >>> letter groups then applies the correct substitutions to each group. >>> >>> group=: #~ (1 j. 0 ,~ 2 ~:/\ ]) >>> words=: ;:@:group >>> substitute=: [: ; ('alpha'"_)`('beta'"_)`]@.('abc' i. {.)&.> >>> >>> f=: [: substitute words >>> >>> I=:'abbbbaaacccaaaaabbbb'[O=:'alphabetaalphacccalphabeta' >>> (O -: f) I >>> 1 >>> >>> >>> Realizing I had overlooked `cut', words can also be written more >>> directly as >>> >>> words=: <;.2~ (1 ,~ 2 ~:/\ ]) >>> (O -: f) I >>> 1 >>> >>> We can mash it together >>> g=: [: ; (<@(('alpha'"_)`('beta'"_)`]@.('abc'i.{.));.2~ (1,~2~:/\])) >>> (O-:g) I >>> 1 >>> >>> >>> Or use no boxes, but this idea depends on your actual application. >>> Accept the fill and remove it later. >>> >>> h=: ' ' -.~ [: , ((('alpha'"_)`('beta'"_)`]@.('abc'i.{.));.2~ >>> (1,~2~:/\])) >>> (O-:h) I >>> 1 >>> >>> >>> On 02/18/2018 07:00 AM, programming-requ...@forums.jsoftware.com wrote: >>> >>>> Date: Sun, 18 Feb 2018 14:08:45 +0530 >>>> From: Arnab Chakraborty<arnab...@gmail.com> >>>> To:programm...@jsoftware.com >>>> Subject: [Jprogramming] sequential machine >>>> Message-ID: >>>> <CAM3RRn36JTQdtq_=cvhmwxycsgafjbmufmi4ougo00zuruz...@mail.gmail.com >>>> > >>>> Content-Type: text/plain; charset="UTF-8" >>>> >>>> Hello, >>>> >>>> I use state machines a lot in my programs (in other >>>> languages). I am trying to understand how I can use J for >>>> those purposes. I have read the Sequential Machines and >>>> Huffman Coding labs. But I am unable to see how to solve this >>>> toy problem (without using regexp): >>>> >>>> Input alphabet {a,b,c} >>>> I want to replace runs of 'a' with the word 'alpha', runs of 'b' >>>> with the word 'beta', and leave the 'c's unchanged. >>>> >>>> For example, abbbbaaacccaaaaabbbb becomes >>>> alphabetaalphacccalphabeta. >>>> >>>> The state diagram is like this, where the arcs are labelled as >>>> inp/out. >>>> >>>> >>>> [Cannot inline image] >>>> >>>> I have created the input map successfully (not sure if it is a >>>> good way, though): >>>> >>>> makemap =. 3 : '+/ (>:i.#y) *"0 1 a.="1 0 y' >>>> m=.makemap 'abc' >>>> >>>> I guess that this can be achieved using only outputs 0 and >>>> 2, since I am just interested in the runs. >>>> >>>> >>>> Also, since the output is not just a part of the input, f >>>> must be 2 or 3 or 4. >>>> >>>> But I am stuck at this point. If I use f=.2, then I can get >>>> a list of boundaries of all the runs. If I have to write another >>>> verb that will convert this list to the desired output, then >>>> basically I have to implement a simplified version of the same >>>> state machine inside that verb, which does not look good. >>>> >>>> f=.3 does not look promising either, since for 'c' I need to >>>> know the length of the run. >>>> >>>> How should I proceed? >>>> >>>> >>>> Thanks and regards, >>>> >>>> Arnab >>>> >>> >>> ---------------------------------------------------------------------- >>> 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