@ 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

Reply via email to