@ Bill Lam C-style. That's funny. I know just enough C to get around. It's not that I dislike it, just never went in that direction.
I actually modeled my flip function after the hailstone example at the top of Chapter 10 in <i>Learning J</i>: http://www.jsoftware.com/help/learning/10.htm halve =: -: mult =: 1: + (* 3:) odd =: 2 & | COLLATZ =: 3 : 'if. odd y do. mult y else. halve y end. ' ---------------------------- *flip =: (~: 3 : 'if. ((< & 2) @: #) y do. ({ & id) y else. (+./ @: ({ & id)) y end. ')* *since +. is idempotent so there is no need for 2 branches and can* *be simplified as* *((+./y{x)~:y{x) y } x* *not sure why id is needed. moreover branch is bad for performance,* *evaluation of +./boolean should already optimized by the J interpreter.* -------------------------- This is what it replaced: xor =: ((+.)*.(-.@:*.)) board =: 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 NB. 0s for vacant, 1s occupied board 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 move =: 0 2 5 move 0 2 5 board xor +./((1 0 0 0 0 0 0 0 0 0 0 0 0 0 0) |.!.0~ 3 1 $ -) move 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 NB. The desired result, a new board It worked fine for moves but was unsatisfactory for initializing a board with a single position empty. 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (xor +./((1 0 0 0 0 0 0 0 0 0 0 0 0 0 0) |.!.0~ 3 1 $ -)) 5 would return a new board that was all 0s. I thought a single function (flip) to both initialize the board and update the board with moves was better. I also thought of the id matrix as an improvement over recreating the arrays for each move that needed to be +.-ed together, and then xor-ed with the old board. Just pull them out of the id matrix, instead. On Mon, Jun 5, 2017 at 6:19 AM, bill lam <[email protected]> wrote: > Thank you for explanation. I think code will be easier to read > if you had written in a c-style, because your j-ish code is not > the J that I am familiar with. eg, the flip. > > flip =: (~: 3 : 'if. ((< & 2) @: #) y do. ({ & id) y else. (+./ @: ({ & > id)) y end. ') > > since +. is idempotent so there is no need for 2 branches and can > be simplified as > ((+./y{x)~:y{x) y } x > > not sure why id is needed. moreover branch is bad for performance, > evaluation of +./boolean should already optimized by the J interpreter. > > it would better be switch x and y into a more natural form > ((+./x{y)~:x{y) x } y > > This should be good enough, but if you wanted a tacit form, > it is something like > > f=. (+./@:{ ~: {)`[`] } > > see j dictionary for the meaning of (v0`v1`v2) } > > 5 f 15$1 > 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 > 0 2 5 f 5 f 15$1 > 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 > 3 1 0 f 0 2 5 f 5 f 15$1 > 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 > > Пн, 05 июн 2017, Michael Rice написал(а): > > The gap between J and most computer languages is pretty wide. > > > > Maybe this will help. > > > > The board, a noun, is represented by a 15 element binary array with 1s > for > > full positions and 0s for empty ones. It is initially all 1s. Id, a noun, > > is a 15x15 identity matrix. > > > > Function flip, given a board and position(s) that are to be flipped, > i.e., > > not-ed, returns a new updated board with the position(s) not-ed. It first > > checks the size (#) of positions. If there's only one, it pulls the row > > with that position number from id, xors (:~) it with the board, and > returns > > the result. If there is more than one position, all the rows of id for > > those positions are first or-ed together, that result xor-ed with the > > board, and the result returned. > > > > There's to be a monadic function, solitaire, that initiates the search. > > > > solitaire 5 - begin the search with position 5 empty. > > > > There's also to be a function search, called by solitaire, with a single > > parameter, a list of > > 1) the current board > > 2) a list of moves for the current board > > 3) a path list for the solution, initially empty > > 4) a history stack (for back-tracking) composed of past boards and their > > lists of moves not yet explored, initially empty > > > > Recursive function search (depth first) always moves the move at the head > > of its given move list and saves the rest of the moves and the board > > associated with them in the history stack. When the search reaches a > board > > with no moves and just one peg remaining on the board, it prints the > > solution path. Otherwise it back-tracks to the last board and its > > associated list of remaining moves and moves the next move on the list. > If > > it reaches a state where there are no moves in its given move list and an > > empty history, "No solution" is printed. > > > > On Sun, Jun 4, 2017 at 11:45 AM, bill lam <[email protected]> wrote: > > > > > I have difficulty in reading your code, perhaps you want to > > > make everything looks functional. To that end, you may > > > replace the if/then with @. (agenda) > > > (+./ @: ({ & id))`({ & id)@.((< & 2) @: #) > > > > > > (untested and not sure if this is a simplication) > > > > > > Вс, 04 июн 2017, Michael Rice написал(а): > > > > Two things come to mind: 1) *reductio ad absurdum* and 2) a Dustin > > > Hoffman > > > > film, wherein he says to a man, "I going to explain something so > you'll > > > > understand it!" and then shoots him. > > > > > > > > I already had a function that does what I needed (see below) but was > > > musing > > > > about left/right parameter style, when one of the parameters remains > > > > constant and the other changes "functionally" in the program. > > > > > > > > Just looking at your first "simplification," I can see I have a lot > of > > > > familiarization work to do. For example, what's the difference > between > > > > > > > > 2 3 <@, 3 4 and 1 2 <@:, 3 4 > > > > > > > > when the result is the same? > > > > > > > > Must be something subtle. > > > > > > > > ================= > > > > > > > > Note: The moves marked with "<-" are moves to a known solution. > > > > > > > > > > > > NB. 15 position peg solitaire > > > > NB. The board (position 5 initially vacant) > > > > > > > > NB. 0 > > > > NB. 1 2 > > > > NB. 3 4 5 > > > > NB. 6 7 8 9 > > > > NB. 10 11 12 13 14 > > > > > > > > move_table =: 36 3 $ 0 2 5 5 2 0 0 1 3 3 1 0 1 3 6 6 3 1 1 4 8 8 > 4 1 > > > 2 4 > > > > 7 7 4 2 2 5 9 9 5 2 3 6 10 10 6 3 3 7 12 12 7 3 3 4 5 5 4 3 4 7 11 > 11 7 > > > 4 4 > > > > 8 13 13 8 4 5 8 12 12 8 5 5 9 14 14 9 5 6 7 8 8 7 6 7 8 9 9 8 7 10 > 11 12 > > > 12 > > > > 11 10 11 12 13 13 12 11 12 13 14 14 13 12 > > > > id =: e. i. 15 > > > > flip =: (~: 3 : 'if. ((< & 2) @: #) y do. ({ & id) y else. (+./ > @: ({ > > > & > > > > id)) y end. ') > > > > legal_moves =: (#~ ((-: & 1 1 0)"1 @: ({~ & move_table))) > > > > board =: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 > > > > board > > > > 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 > > > > board =: board flip 5 > > > > board > > > > 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 > > > > move_table legal_moves board > > > > 0 2 5 <- > > > > 3 4 5 > > > > 12 8 5 > > > > 14 9 5 > > > > board =: board flip 0 2 5 > > > > board > > > > 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 > > > > move_table legal_moves board > > > > 3 1 0 <- > > > > 7 4 2 > > > > 9 5 2 > > > > board =: board flip 3 1 0 > > > > board > > > > 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 > > > > move_table legal_moves board > > > > 8 4 1 > > > > 7 4 2 > > > > 9 5 2 > > > > 10 6 3 > > > > 12 7 3 > > > > 5 4 3 <- > > > > board =: board flip 5 4 3 > > > > board > > > > 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 > > > > move_table legal_moves board > > > > 6 3 1 <- > > > > 11 7 4 > > > > 13 8 4 > > > > 12 8 5 > > > > 14 9 5 > > > > board =: board flip 6 3 1 > > > > board > > > > 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 > > > > move_table legal_moves board > > > > 0 1 3 <- > > > > 12 7 3 > > > > 11 7 4 > > > > 13 8 4 > > > > 12 8 5 > > > > 14 9 5 > > > > 8 7 6 > > > > board =: board flip 0 1 3 > > > > board > > > > 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 > > > > move_table legal_moves board > > > > 11 7 4 <- > > > > 13 8 4 > > > > 12 8 5 > > > > 14 9 5 > > > > 8 7 6 > > > > board =: board flip 11 7 4 > > > > board > > > > 0 0 0 1 1 0 0 0 1 1 1 0 1 1 1 > > > > move_table legal_moves board > > > > 8 4 1 > > > > 3 4 5 <- > > > > 12 8 5 > > > > 14 9 5 > > > > 9 8 7 > > > > 13 12 11 > > > > board =: board flip 3 4 5 > > > > board > > > > 0 0 0 0 0 1 0 0 1 1 1 0 1 1 1 > > > > move_table legal_moves board > > > > 9 5 2 <- > > > > 13 8 4 > > > > 9 8 7 > > > > 13 12 11 > > > > board =: board flip 9 5 2 > > > > board > > > > 0 0 1 0 0 0 0 0 1 0 1 0 1 1 1 > > > > move_table legal_moves board > > > > 13 8 4 > > > > 12 8 5 > > > > 13 12 11 <- > > > > board =: board flip 13 12 11 > > > > board > > > > 0 0 1 0 0 0 0 0 1 0 1 1 0 0 1 > > > > move_table legal_moves board > > > > 10 11 12 <- > > > > board =: board flip 10 11 12 > > > > board > > > > 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 > > > > move_table legal_moves board > > > > 12 8 5 <- > > > > board =: board flip 12 8 5 > > > > board > > > > 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 > > > > move_table legal_moves board > > > > 5 2 0 > > > > 2 5 9 <- > > > > board =: board flip 2 5 9 > > > > board > > > > 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 > > > > move_table legal_moves board > > > > 14 9 5 <- > > > > board =: board flip 14 9 5 > > > > board > > > > 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 > > > > move_table legal_moves board > > > > > > > > > > > > > > > > > > > > On Sun, Jun 4, 2017 at 10:03 AM, Raul Miller <[email protected]> > > > wrote: > > > > > > > > > Like this? > > > > > > > > > > (#~ 5=2#.@:|])z > > > > > 3 4 5 > > > > > > > > > > -- > > > > > Raul > > > > > > > > > > > > > > > On Sun, Jun 4, 2017 at 9:43 AM, Michael Rice <[email protected]> > > > wrote: > > > > > > How about > > > > > > 1 0 1 0 1 0 (#~ ((-: & 0 1 0)"1 @: ({~ & z)))~ z > > > > > > ? > > > > > > > > > > > > Odd, that's the KISS way, the way that always works, and the one > way > > > I > > > > > > hadn't considered. > > > > > > > > > > > > On to your "simplifications." > > > > > > > > > > > > On Sat, Jun 3, 2017 at 10:16 PM, Louis de Forcrand < > [email protected] > > > > > > > > > wrote: > > > > > > > > > > > >> How about > > > > > >> 1 0 1 0 1 0 (#~ ((-: & 0 1 0)"1 @: ({~ & z)))~ z > > > > > >> ? > > > > > >> You can then "simplify": > > > > > >> > > > > > >> First the hook (and {~&z) > > > > > >> ([ #~ -:&0 1 0"1@:(z&{)@])~ > > > > > >> ([ #~ -:&0 1 0"1@:(z&{)@])~ > > > > > >> > > > > > >> Then ~ can be "distributed" over the resulting fork: > > > > > >> [~ #~ -:&0 1 0"1@:(z&{)@(]~) > > > > > >> ] #~ -:&0 1 0"1@:(z&{)@[ > > > > > >> > > > > > >> You can keep going; > > > > > >> From bonding to forks: > > > > > >> ] #~ (] -: 0 1 0"_)"1@:(z { ])@[ > > > > > >> Composition and -: commutativity: > > > > > >> ] #~ (0 1 0 -: ])"1@:(z { ]@[) > > > > > >> Because 1=#$0 1 0: > > > > > >> ] #~ (0 1 0 -:"1 ])@:(z { [) > > > > > >> Trains: > > > > > >> ] #~ (0 1 0 -:"1 ]@:(z { [)) > > > > > >> ] #~ 0 1 0 -:"1 ]@:(z { ]) > > > > > >> ] #~ 0 1 0 -:"1 z { [ > > > > > >> > > > > > >> Can't get it any simpler. > > > > > >> > > > > > >> Cheers, > > > > > >> Louis > > > > > >> > > > > > >> > On 4 Jun 2017, at 03:45, Michael Rice <[email protected]> > > > wrote: > > > > > >> > > > > > > >> > z (#~ ((-: & 0 1 0)"1 @: ({~ & z))) 1 0 1 0 1 0 > > > > > >> > > > > > >> ------------------------------------------------------------ > > > ---------- > > > > > >> 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 see http://www.jsoftware.com/ > forums.htm > > > > > > -- > > > regards, > > > ==================================================== > > > GPG key 1024D/4434BAB3 2008-08-24 > > > gpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3 > > > gpg --keyserver subkeys.pgp.net --armor --export 4434BAB3 > > > ---------------------------------------------------------------------- > > > For information about J forums see http://www.jsoftware.com/forums.htm > > > > > ---------------------------------------------------------------------- > > For information about J forums see http://www.jsoftware.com/forums.htm > > -- > regards, > ==================================================== > GPG key 1024D/4434BAB3 2008-08-24 > gpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3 > gpg --keyserver subkeys.pgp.net --armor --export 4434BAB3 > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
