> I've already posted code for changing a board and extracting legal moves > from it that satisfactorily produced a path to a win. If you like, you're > free to take a swing at finishing it any way you think will work.
I thought I had posted a finished implementation? http://www.jsoftware.com/pipermail/programming/2017-June/047522.html solitaire 5 14 9 5 2 5 9 3 4 5 10 6 3 1 3 6 12 7 3 13 8 4 9 5 2 2 4 7 11 7 4 6 3 1 0 1 3 3 4 5 If you feel there's something wrong with this approach, let me know and I'll see if I can wrap my head around those issues. Thanks, -- Raul On Wed, Jun 7, 2017 at 11:21 PM, Michael Rice <[email protected]> wrote: > @ Raul Miller > > "I guess I disagree with the model you posted here, about how to > implement the peg game" > > I've already posted code for changing a board and extracting legal moves > from it that satisfactorily produced a path to a win. If you like, you're > free to take a swing at finishing it any way you think will work. Here's my > Clojure code (see below) for the two remaining functions, *search* and > *solitaire*. > > The *recur* function calls just act as calls to the original function that > called them, and could be replaced with the name of that function and get > the same result. > > Search function: > That first *if-let* tries to pull a move off the top of the incoming moves > list. If it fails, i.e., moves was empty, it drops through to the *if* > statement below it where it checks the board for just one remaining peg. If > true, it returns the path to the solution. If not it checks the history > stack. If it's empty, it prints "No solution." Otherwise it pulls a board > and move-list (the move list being the rest of the moves for a previous > move that led to a dead-end) off the history stack, and recurs with that > board, its move list, the path list minus the last move added, and the rest > of the history stack. As you can see, the elements of the history stack are > lists with two sublists, one for the board, the other for its remaining > moves. > > If the search function gets a move, you can see for yourself what it does: > 1) create the next board > 2) recur(next-board, moves for next-board, move added to path, the current > board and the rest of its moves pushed onto the history stack) > > Solitaire function: > The board is modeled like the J code I posted. > The recursion is kicked off with that board, its moves, an empty vector to > accumulate the path (see note below), and an empty history stack (a list). > > Note: A nice feature of Clojure is using a vector instead of a list to > accumulate a path. An item is added to a list at its top. An item is added > to a vector at its end. Popping a list removes the first element. Popping a > vector removes the last element. Using a list to accumulate a path requires > reversing the list before printing it. Using a vector eliminates that > requirement. Lists are enclosed in parentheses, vectors in brackets. > > If you, or anyone else, pursues this, feel free to ask any questions you > might have. > > Michael > > Code (Change font to fixed-width if it doesn't come across as that. It's > easier to read with proper indentatation): > > (defn search > [board moves path history] > (if-let [move (when-let [s (seq moves)] (first s))] > (let [next-board (make-move board move)] > (recur next-board (find-moves next-board) (conj path move) (conj > history (list board (rest moves))))) > (if (= (reduce + 0 board) 1) > path > (if-let [backtrack (when-let [s (seq history)] (first s))] > (let [[board moves] backtrack] > (recur board moves (pop path) (rest history))) > "No solution.")))) > > (defn solitaire > ; lst: empty board location(s) > [lst] > (let [board (reduce #(assoc %1 %2 0) [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] > lst)] > (search board (find-moves board) [] ()))) > > ;user=> (solitaire '(5)) > ;[[0 2 5] [3 1 0] [5 4 3] [6 3 1] [0 1 3] [11 7 4] [3 4 5] [9 5 2] [13 12 > 11] [10 11 12] [12 8 5] [2 5 9] [14 9 5]] > > > > On Wed, Jun 7, 2017 at 3:23 PM, Raul Miller <[email protected]> wrote: > >> Oh... well... >> >> I guess I disagree with the model you posted here, about how to >> implement the peg game: I think that a spec requiring five arrays is >> unnecessarily redundant. >> >> That said, I did make an error in one of my posts, which I am only >> just now realizing: the move_table depends on the size of the board, >> and I didn't deal with that in my supposed general case >> implementation. Fortunately, the fix is straightforward, and I could >> post that if you wanted. >> >> Anyways... to address the complexity argument you're raising, you can >> have up to four hetrogenous unboxed array parameters in a recursive >> context in J without resorting to objects to represent them. >> Specifically: verbs can take one or two arguments, adverbs give you an >> additional argument and conjunctions another on top of that. With >> objects, or with boxing, you can go much higher - but that can indeed >> feel kludgy if you need an object or box for every recursive >> invocation. But you can also often rearrange things to not need so >> many recursive parameters. >> >> And for the peg problem, I only see three significant arrays: the >> board, the moves to reach that board and the list of legal moves. >> Recursive contexts give you a stack, allowing you to backtrack with >> these arrays. I'm not seeing why you need more than that? >> >> Thanks, >> >> -- >> Raul >> >> On Wed, Jun 7, 2017 at 2:26 PM, Michael Rice <[email protected]> wrote: >> > Thanks for the paste tip. I was unaware of that feature. >> > >> > I'm "giving up on" the peg game. I didn't think that needed identifying >> as >> > it's been my only focus. I think of "academic exercises" as homework, >> > seeking answers to which is, rightly, taboo on computer language >> web-sites. >> > >> > The peg game search function has five arrays it recursively manipulates >> to >> > a solution, three of which begin as empty, all having varying shapes, >> even >> > empty, as they pass through recursions. From what I've read in >> *Learning J*, >> > for their heterogeneous shapes they would have to be boxed to be passed >> as >> > a functional parameter, un-boxed inside a recursive pass to be altered, >> and >> > then boxed again to be passed on to the next recursion. I didn't say it >> was >> > impossible, just that it seemed kludgy, or, as you put it "forced." >> > >> > I spent quite a bit of time with Haskell. As a functional language it's >> > hard to beat, but some problems on which I used it I felt like I was >> having >> > to go around the block just to get next door. Why bother? >> > >> > Thanks for your input. >> > >> > >> > On Wed, Jun 7, 2017 at 1:11 PM, Raul Miller <[email protected]> >> wrote: >> > >> >> When pasting into gmail, please use "Paste and match style" to avoid >> >> the extra blank lines that someone at google somehow managed to work >> >> into the default Paste action. >> >> >> >> That said: >> >> >> >> my_empty =: }. 1 >> >> < my_empty >> >> ┌┐ >> >> ││ >> >> └┘ >> >> >> >> What you are seeing here is not an empty list of boxes but a box >> >> containing an empty. Or, ok, yes: "an empty box". >> >> >> >> Note also that a: is the same: >> >> >> >> a: >> >> ┌┐ >> >> ││ >> >> └┘ >> >> a: -: <}.1 >> >> 1 >> >> >> >> (Finally, I should perhaps note that I have no idea what problem you >> >> are giving up on. Usually, though, "academic exercises" - which >> >> typically focus more on how the goal is reached than on reaching the >> >> goal - tend to feel forced in J.) >> >> >> >> Thanks, >> >> >> >> -- >> >> Raul >> >> >> >> >> >> On Wed, Jun 7, 2017 at 1:03 PM, Michael Rice <[email protected]> >> wrote: >> >> > @robert therriault >> >> > >> >> > my_empty =: }. 1 >> >> > >> >> > my_empty >> >> > >> >> > >> >> > f my_empty >> >> > >> >> > 1 >> >> > >> >> > < my_empty >> >> > >> >> > ┌┐ >> >> > >> >> > ││ >> >> > >> >> > └┘ >> >> > >> >> > >> >> > An empty box? >> >> > >> >> > >> >> > I'm beginning to see the problem I was thinking of doing in J is >> >> ill-suited >> >> > to the language. It could be done, as it could in any computer >> language, >> >> > but the solution would be pretty kludgy. >> >> > >> >> > >> >> > I'll soon think of something else on which to apply J. It's already >> >> > invading my sleep. Going through exercises is no way to get into a >> >> > language. One needs a problem on which to focus it. I've been wanting >> to >> >> > explore cryptography more deeply, and J seems ideal for it. >> >> > >> >> > >> >> > Thanks to all, >> >> > >> >> > >> >> > Michael >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > On Wed, Jun 7, 2017 at 12:01 PM, robert therriault < >> >> [email protected]> >> >> > wrote: >> >> > >> >> >> I'm going to look at these results through the lens of Shape ($) >> >> >> >> >> >> f =: (1&,) >> >> >> f 2 >> >> >> 1 2 >> >> >> $ f 2 NB. shape is 2 >> >> >> 2 >> >> >> f '' >> >> >> 1 >> >> >> $ f '' NB. shape is 1 >> >> >> 1 >> >> >> empty NB. it is a verb in my environment >> >> >> (i.0 0)"_ >> >> >> f empty >> >> >> f empty NB. result of two verbs and no arguments is just the two >> verbs >> >> >> f empty 2 NB. this is where you expect to have a 1 returned >> >> >> >> >> >> $ f empty 2 NB. shape is 1 0 >> >> >> 1 0 NB. one line of no items means no display >> >> >> >> >> >> I think it is the second dimension of EMPTY as opposed to NULL that >> is >> >> >> tripping you up. >> >> >> >> >> >> NULL=.'' >> >> >> $ NULL >> >> >> 0 >> >> >> EMPTY >> >> >> $EMPTY >> >> >> 0 0 >> >> >> EMPTY-:empty 1 >> >> >> 1 >> >> >> >> >> >> In answer to your most recent question Michael, I would say just make >> >> sure >> >> >> that the empty list that you pass is the right shape. >> >> >> >> >> >> Cheers, bob >> >> >> >> >> >> > On Jun 7, 2017, at 8:48 AM, Raul Miller <[email protected]> >> >> wrote: >> >> >> > >> >> >> > empty is a verb >> >> >> > f is a verb >> >> >> > >> >> >> > so f empty is a verb (a hook) >> >> >> > >> >> >> > f=: 1&, >> >> >> > (f empty) 3 >> >> >> > >> >> >> > >> >> >> > >> >> >> > $(f empty) 3 >> >> >> > 3 0 >> >> >> > $(f empty) 5 >> >> >> > 5 0 >> >> >> > >> >> >> > The reasons for this are documented at >> >> >> > http://www.jsoftware.com/help/dictionary/dictf.htm (hooks) and >> >> >> > http://www.jsoftware.com/help/dictionary/d630n.htm (x m&v y). >> >> >> > >> >> >> > That said, verbs take arguments and empty is a verb - it always >> >> >> > produces an empty result, but only when it gets an argument. >> >> >> > >> >> >> > I hope this helps, >> >> >> > >> >> >> > -- >> >> >> > Raul >> >> >> > >> >> >> > >> >> >> > On Wed, Jun 7, 2017 at 11:39 AM, Michael Rice <[email protected] >> > >> >> >> wrote: >> >> >> >> Oops! Guess I creamed empty. Will close and regen Jqt before >> >> proceeding. >> >> >> >> >> >> >> >> Done! >> >> >> >> >> >> >> >> f =: (1&,) >> >> >> >> f 2 >> >> >> >> 1 2 >> >> >> >> f empty >> >> >> >> f empty >> >> >> >> >> >> >> >> Shouldn't it have returned >> >> >> >> >> >> >> >> 1 >> >> >> >> >> >> >> >> ? >> >> >> >> >> >> >> >> On Wed, Jun 7, 2017 at 11:22 AM, robert therriault < >> >> >> [email protected]> >> >> >> >> wrote: >> >> >> >> >> >> >> >>> One thing to remember is that empty is already defined as a verb >> >> >> >>> >> >> >> >>> empty >> >> >> >>> (i.0 0)"_ >> >> >> >>> >> >> >> >>> So if you overwrite this you may break some code if you have >> >> previously >> >> >> >>> relied on the existing verb definition. >> >> >> >>> >> >> >> >>> I think along the lines that Pascal mentioned that null could be >> >> >> similarly >> >> >> >>> defined as >> >> >> >>> >> >> >> >>> null NB. check that it is not already used >> >> >> >>> |value error: null >> >> >> >>> null=:(i.0)"_ >> >> >> >>> NULL NB. check that it is not already used - uppercase for >> global >> >> >> >>> nouns is a convention I like and is often seen in J code >> >> >> >>> |value error: NULL >> >> >> >>> NULL=:'' NB. I use this as the null string (same as what John >> >> >> suggested) >> >> >> >>> NULL-:null 2 NB. any argument produces NULL from null >> >> >> >>> 1 >> >> >> >>> >> >> >> >>> Hope this helps, >> >> >> >>> >> >> >> >>> Cheers, bob >> >> >> >>> >> >> >> >>>> On Jun 7, 2017, at 8:09 AM, 'Jon Hough' via Programming < >> >> >> >>> [email protected]> wrote: >> >> >> >>>> >> >> >> >>>> >> >> >> >>>> I may be wrong in doing this, but I usually write >> >> >> >>>> empty=: '' >> >> >> >>>> to signify an empty list, array, matrix etc. >> >> >> >>>> >> >> >> >>>> >> >> >> >>>> On Jun 7, 2017, 23:59, at 23:59, Michael Rice < >> [email protected] >> >> > >> >> >> >>> wrote: >> >> >> >>>>> Is there a special "noun" for an empty list? >> >> >> >>>>> >> >> >> >>>>> Creating one seems enigmatic. >> >> >> >>>>> >> >> >> >>>>> empty =: 1 2 >> >> >> >>>>> empty >> >> >> >>>>> 1 2 >> >> >> >>>>> empty =: }. empty >> >> >> >>>>> empty >> >> >> >>>>> 2 >> >> >> >>>>> empty =: }. empty >> >> >> >>>>> empty >> >> >> >>>>> >> >> >> >>>>> empty1 =: >> >> >> >>>>> |syntax error >> >> >> >>>>> | empty1=: >> >> >> >>>>> ------------------------------------------------------------ >> >> >> ---------- >> >> >> >>>>> 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 >> >> >> > ------------------------------------------------------------ >> >> ---------- >> >> >> > 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 >> >> >> > ---------------------------------------------------------------------- >> > 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
