This looks very interesting and I will read through it in detail as soon as
I can
It is good to have a fun application like this to study in detail
2008/1/9, Raul Miller <[EMAIL PROTECTED]>:
>
> Ok, so it looks like Roger's moo guesses
> the number sequence you have chosen, and
> you are responsible for (a) declaring the range
> of possibilities, and (b) telling it how many "bulls"
> and "cows" it has gotten with its guesses.
>
> Here is an example session where I am thinking
> of the sequence 1 2 3.
>
> moo 5 5 5
> 3 3 0 c
> 30 choices left
> 4 1 3 bc
> 4 choices left
> 2 4 3 bc
> one choice left; it must be 1 2 3
> 1 2 3
>
> Here's a simpler session, which I will use to illustrate
> the code. I am thinking of the sequence 0 1:
> moo 2 2
> 0 0 b
> 2 choices left
> 1 0 cc
> one choice left; it must be 0 1
> 0 1
>
> I supplied the initial command line (moo 5 5 5), and
> I responded with the sequences of 'b's and 'c's. The
> numbers to the left of those sequences were its guesses.
>
> Anyways, univ 5 5 5 computes all the possible things
> I could be thinking of. The program will be eliminating
> entries from this list based on my responses.
>
> univ 2 2
> 0 0
> 0 1
> 1 0
> 1 1
>
> These are equivalent:
> (#: i.@(*/))2 2
> 2 2 (#: i.@(*/)) 2 2
> 2 2 #: i. */ 2 2
> 2 2 #: i. 4
> 2 2 #: 0 1 2 3
>
> I will use this last line to represent the various universe
> states as this routine executes.
>
> moo1 is the heart of this program. It takes as its argument some
> universe of choices, and if there are multiple possibilities it picks
> one at random and prompts the user with that choice and eliminates
> choices from the universe which conflict with that answer, and
> displays a line describing this result universe.
>
> Since moo1^:_ repeats this process until the result stops
> changing, this process repeats until there are less than
> two choices.
>
> Here's the definition of moo1:
> ([state)@([EMAIL PROTECTED] prune ])^:(1&<@#)
>
> That ^:(1&<@#) means that moo1 only does something
> when there's more than one choice.
>
> The routine guess just picks something at random. The
> definition of guess is [EMAIL PROTECTED] { ] and for the first run through,
> this is equivalent to 0 { ]
>
> The definition of score is
> ; prompt@(,&' ')@":
>
> This prompts the user with its argument and returns
> two boxes. The left box contains its argument and
> the right box contains the user's response. So if
> I run
> score 2 2 #:0
> I am prompted with
> 0 0
>
> And if I respond with b
> the result of score would be
> 0 0;,'b'
> +---+-+
> |0 0|b|
> +---+-+
>
> Next, prune takes this (as its left argument) and the
> current universe of valid results (as its right argument)
> and returns the refined universe of valid results
> (0 0;,'b') prune 2 2#:0 1 2 3
> 0 1
> 1 0
>
> Finally, the verb state describes this new universe, based
> on how many entries it contains (0, 1 or many), and its
> use in the hook ([state) means that the result of state is
> ignored and its argument is returned as its final result.
>
> state (0 0;,'b') prune 2 2#:0 1 2 3
> 2 choices left
> 2 choices left
> ([state)(0 0;,'b') prune 2 2#:0 1 2 3
> 2 choices left
> 0 1
> 1 0
>
> That first line after each line is displayed, and subsequent
> lines are the corresponding result.
>
> The definition of prune is
> ((bull *. bc) # ])`(''"_)@.solved
>
> If the users' answer indicates that the puzzle has been
> solved, prune returns a blank. Otherwise, it eliminates
> impossible answers from the universe.
>
> The definition of solved is
> (('b' $~ [EMAIL PROTECTED]) -: ])&>/@[
>
> If the user has provided a list of 'b's the same length as
> the length of the guess then the problem is solved,
> otherwise it's not.
>
> (0 1;'bb') solved _
> 1
> (0 1;'bc') solved _
> 0
>
> These are equivalent:
> (0 1;'bc') solved _
> (('b' $~ [EMAIL PROTECTED]) -: ])&>/ 0 1;'bc'
> (('b' $~ [EMAIL PROTECTED]) -: ])&>/ ((<0 1),<'bc')
> (<0 1) (('b' $~ [EMAIL PROTECTED]) -: ])&> <'bc'
> 0 1 (('b' $~ [EMAIL PROTECTED]) -: ]) 'bc'
> ('b' $~ $0 1) -: 'bc'
> ('b' $~ 2) -: 'bc'
> (2 $ 'b') -: 'bc'
> 'bb' -: 'bc'
> 0
>
> The rest of the definition of prune selects lines
> from the universe that match the "bull" criterion and
> the "bc" criterion. In the first step of my simple
> example, these are the same:
> (0 0;,'b') bull 2 2#:0 1 2 3
> 0 1 1 0
> (0 0;,'b') bc 2 2#:0 1 2 3
> 0 1 1 0
>
> The "bull" criterion only concerns itself with the
> appearance of the letter 'b' in my typed answer.
>
> The "bc" criterion only concerns itself with the
> number of letters in my typed answer.
>
> Here's the definition of "bull"
> +/@('b'&=)@(>@{:@[) = >@[EMAIL PROTECTED] +/@(="1) ]
> This has the structure
> verb1 = verb2 +/@(="1) ]
>
> The result of verb1 is the number of 'b's I typed.
> The result of verb2 is the current guess.
> The result of ] is the previous universe of valid choices.
>
> (0 0;,'b') +/@('b'&=)@(>@{:@[) 2 2 #:0 1 2 3
> 1
> (0 0;,'b') >@[EMAIL PROTECTED] 2 2 #:0 1 2 3
> 0 0
>
> These are equivalent
> (0 0;,'b') bull 2 2 #: 0 1 2 3
> 1 = 0 0 +/@(="1) 2 2 #:0 1 2 3
> 1 = 2 1 1 0
> 0 1 1 0
>
> Hopefully, it's clear that +/@(="1) counts
> how many exact matches there are between
> the current guess and each item in the universe
> of valid choices?
>
> Here's the definition of bc
> #@(>@{:@[) = ] ([ +/@:([ <. -~) [EMAIL PROTECTED] {. ])&(#/.~)"1 ] ,"1
> >@[EMAIL PROTECTED]
>
> This one is a bit more complicated, since it needs to ignore
> the order of the guess and valid choices. The top level structure
> of bc is
> verb1 = ] verbA ] ,"1 verb2
>
> The result of verb1 is the number of characters I typed.
> The result of verb2 is the current guess.
> The result of ] is the previous universe of valid choices.
>
> The result of verbA is the number of any position matches
> between the universe of valid choices and the current guess.
> By verbA, I mean: ([ +/@:([ <. -~) [EMAIL PROTECTED] {. ])&(#/.~)"1
>
> The result of (] ,"1 verb2) has one row for each previous
> valid choice. These rows consist of that choice followed
> by the guess. In other words, these are equivalent:
> (0 0;,'b') (] ,"1 >@[EMAIL PROTECTED]) 2 2 #:0 1 2 3
> (2 2 #:0 1 2 3),"1(0 0)
> 0 0 0 0
> 0 1 0 0
> 1 0 0 0
> 1 1 0 0
>
> These rows will be the right argument for verbA. The left
> argument will be the previous universe of valid choices.
>
> Anyways, verbA has the structure f&g"1 where
> f is ([ +/@:([ <. -~) [EMAIL PROTECTED] {. ]) and g is #/.~
>
> We can look at each of these pairs of arguments to f
> by replacing f with ;
> (2 2 #:0 1 2 3) ;&(#/.~)"1 (2 2 #:0 1 2 3),"1(0 0)
> +---+---+
> |2 |4 |
> +---+---+
> |1 1|3 1|
> +---+---+
> |1 1|1 3|
> +---+---+
> |2 |2 2|
> +---+---+
>
> In essence, g (or #/.~) has broken items in our arguments
> down into groups and has counted the number of members
> in each. Since all groups have the same prefix, we can
> meaningfully compare entries on the right with entries on
> the left (after we have discarded any extra entries on the
> right). In other words, these entries will be in the same
> order.
>
> The definition of f was
> [ +/@:([ <. -~) [EMAIL PROTECTED] {. ]
>
> This has the structure [ h [EMAIL PROTECTED] {. ]
>
> And the verb ([EMAIL PROTECTED] {. ]) says "take only the elements from
> the right argument which have corresponding elements in
> the left argument". In other words: we are discarding any
> surplus.
>
> Thus, the core of f is +/@:([ <. -~)
>
> In other words: the right argument to f includes the
> counts on the left, so we first need to subtract those.
> Once we have done so, for each element we choose
> the number on the left side of f or this difference -- that's
> how many times the guessed value can relevantly
> appear in the choice. In other words, these are equivalent
> 1 1 +/@:([ <. -~) 1 3
> +/ 1 1 ([ <. -~) 1 3
> +/ 1 1 <. 1 1 -~ 1 3
> +/ 1 1 <. 1 3 - 1 1
> +/ 1 1 <. 0 2
> +/ 0 1
> 1
>
> The guess was 0 0 and the choice was 1 0,
> and the row with both was 1 0 0 0. In this
> choice we have two values, each of which
> appears once (thus: 1 1). In the row with both,
> we have a 1 and we have three 0s (thus: 1 3).
> When we subtract out the choice this means that
> our guess had 0 of that first value, and 2 of that
> second value (thus: 0 2). But since the choice
> only had one of each, that means that when we
> are counting bulls and cows we would expect me
> to have typed one character if that guess matched
> that choice. (And, as an aside, that one character
> would have to be a zero, but we do not need to
> record that detail.)
>
> In other words, f first trims the argument pairs
> so that their lengths match:
> +---+---+
> |2 |4 |
> +---+---+
> |1 1|3 1|
> +---+---+
> |1 1|1 3|
> +---+---+
> |2 |2 |
> +---+---+
>
> And then, f subtracts the values on the left (choices)
> from the values on the right (which was choices and
> guess combined) to get values for just the guess
>
> +---+---+
> |2 |2 |
> +---+---+
> |1 1|2 0|
> +---+---+
> |1 1|0 2|
> +---+---+
> |2 |0 |
> +---+---+
>
> And, then f clips the guess counts so they do not exceed
> the choice counts
>
> +---+
> |2 |
> +---+
> |1 0|
> +---+
> |0 1|
> +---+
> |0 |
> +---+
>
> And, finally, f adds these counts
> 2 1 1 0
>
> Since my typed answer had one character,
> 1 = 2 1 1 0
> 0 1 1 0
>
> All of this means that for my simple universe of four
> choices, with the random guess 0 0 that my answer 'b'
> means that the valid remaining choices must each have
> both a zero and a one.
>
> I have skimmed over some elements of this routine and gone
> over others in perhaps excessive detail. If you feel there is some
> subject I should cover in more detail, or from a different angle,
> or whatever, let us know.
>
> Thanks,
>
> --
> Raul
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
--
Björn Helgason, Verkfræðingur
Fugl&Fiskur ehf, Þerneyjarsund 23, Box 127
801 Grímsnes ,t-póst: [EMAIL PROTECTED]
Skype: gosiminn, gsm: +3546985532
Landslags og skrúðgarðagerð, gröfuþjónusta
http://groups.google.com/group/J-Programming
Tæknikunnátta höndlar hið flókna, sköpunargáfa er meistari einfaldleikans
góður kennari getur stigið á tær án þess að glansinn fari af skónum
/|_ .-----------------------------------.
,' .\ / | Með léttri lund verður |
,--' _,' | Dagurinn í dag |
/ / | Enn betri en gærdagurinn |
( -. | `-----------------------------------'
| ) | (\_ _/)
(`-. '--.) (='.'=)
`. )----' (")_(")
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm