Your 10&|&.<: is probably more comprehensible than my 11 |&.<:

But for part B, how did you handle the smearing of scores that
resulted from those new positions and counts?

Thanks,

-- 
Raul

On Mon, Jan 10, 2022 at 7:07 PM 'Mike Day' via Programming
<[email protected]> wrote:
>
> Part 1 was relatively easy,  but I was annoyed that I couldn’t see how to 
> exploit its cyclic nature.  Here’s a comment to self from my script:
>
> “   m10 +/\"1}."1 |: 15 2 $+/|:30 3$die
> 4 6 6  4 10 4 6 6 4 10 4 6 6  4
> 3 4 3 10  5 8 9 8 5 10 3 4 3 10
>
> NB. Players 1 2 score 60 65 respectively every 10 plays
>    10 +/\"1 m10 +/\"1}."1 |: 15 2 $+/|:30 3$die
> 60 60 60 60 60
> 65 65 65 65 65
>
> NB. ... but cant quite see how to make it work! “
> (  where  m10 =:  10&|&.<: NB. does the modulo correction in origin 1.)
>
> No use at all for part 2, where I wasted an hour or two wondering how to get 
> the right orders of magnitude of the number of “universes” having forgotten 
> that each go is three throws, not just one! Anyway, I counted states too, 
> based on these constants:
>
>    die3,:ctdie3
> 3 4 5 6 7 8 9
> 1 3 6 7 6 3 1
>
> Given a set of positions, pos, and  counts of these, cts,  a new set of 
> positions and counts is:
>    pos   =. m10 , pos +/ die3
>    cts   =. ,cts <.@*/ ctdie3
>
> Cheers
>
> Mike
>
> Sent from my iPad
>
> > On 10 Jan 2022, at 22:26, Raul Miller <[email protected]> wrote:
> >
> > https://adventofcode.com/2021/day/21
> >
> > For day 21, we played a "dice game" with two chess pawns.
> >
> > The game was a two player game, with a track with 10 positions,
> > labeled 1 through 10, and the data for the puzzle was the player's
> > starting positions.
> >
> > example=:{{)n
> > Player 1 starting position: 4
> > Player 2 starting position: 8
> > }}
> >
> > Rather than write a parser for this, I used the starting positions
> > directly -- for this example: 4 8.
> >
> > The game itself was to roll a die three times, move that many
> > positions forward and then add the resulting position to the player's
> > score (which starts at 0). The first player to reach 1000 wins.
> >
> > Anyways, for part A of the puzzle, our "die" was a "deterministic 100
> > sided die". This die first rolls a 1 and then rolls a 2 and then a 3
> > and... so on up to 100 after which the next roll is 1. And our answer
> > for part A was the loser's score multiplied by the number of times the
> > die was rolled.
> >
> > My implementation for this was brute force and uninspired:
> >
> > NB. deterministic die
> > det=: 100 NB. value before start
> > k=: 0   NB. count of times rolled
> > roll=: {{
> >  k=: k+1
> >  det=: 1+100|det
> > }}
> >
> > NB. roll die 3 times
> > d3=: {{
> >  +/roll"0 i.3
> > }}
> >
> > NB. move
> > m10=: {{
> >  1+10|y-1
> > }}
> >
> > a21=:{{
> >  p=: y
> >  s=: 0 0
> >  while. 1 do.
> >    assert. k < 10000 NB. avoid infinite loops
> >    if. 1000<:>./s=: s+ 1 0 *p=:m10 p+1 0 * d3'' do. done p return.end.
> >    if. 1000<:>./s=: s+ 0 1 *p=:m10 p+0 1 * d3'' do. done p return.end.
> >  end.
> > }}
> >
> > NB. calculate puzzle value
> > done=: {{
> >  k*<./s
> > }}
> >
> > Thinking about this, I could have instead done something like
> >
> > play=: * (=i.2) $~ #
> >
> > A21=: {{
> >  die=: 1+100|i.6e3
> >  rolls=: _3 +/\ die
> >  positions=: 11 |&.<: y+"1 play+/\play rolls
> >  scores=:+/\play positions
> >  limit=: 1 i.~1000 <: >./"1 scores
> >  (3*1+limit)*<./limit{scores
> > }}
> >
> > Is that more comprehensible though? I am not sure...
> >
> > For part B, instead of a 100 sided deterministic die, we had a 3 sided
> > "dirac die". Every time we "roll" this die, the universe splits into
> > three copies, with the die having value 1, 2 or 3 in those three
> > universes. And, for part B, the puzzle was: count the number of
> > universes won by the player who wins the most times in these
> > universes.
> >
> > Also, to keep this game "simple" a win was a score of 21 instead of a
> > score of 1000.
> >
> > So, for this game, we needed to track the count of universes in each
> > "has not yet won" state. That's a score of 0 .. 20 and a board
> > position of 1..10. We do not care about the history of a universe
> > prior to reaching that state except in the sense that we are counting
> > those universes. We can also ignore universes after we have counted
> > their wins.
> >
> > I approached that this way:
> >
> > NB. we only care about the counts of "universes"
> > NB. each player's position and score marks a universe
> > NB. multiple copies of "identical" universe occur because
> > NB. of differing histories of die rolls reaching that state
> > map=:{{
> >  dirac=. ,1 2 3 +/1 2 3+/1 2 3
> >  c=. #/.~ dirac
> >  i=. ~.dirac
> >  'sc in' =.|:21 10 #:i.210 NB. sc: score, in: index into 1+i.10
> >  'SC CN IN'=. 0 1 |: ((sc,"0/c),"1 0]_1)+"1(1+10|in+/i)*"0 1]1 0 1
> >  NB. score before: 0..20, each move adds a number in range 1..10 to score
> >  |:CN {{x y}310$0}}"1 IN+10*SC
> > }}''
> >
> > So, basically, each row of this matrix represents a track position and
> > a score, and each column represents the next track position and score,
> > and the values are the number of transitions between that row and that
> > column. It's mostly zeros, but if we summarize the dice (how much they
> > add to the track position and the count for that change), the counts
> > we see here are the values which go into the non-zero parts of the
> > transition map:
> >
> >   (~.,.#/.~),1 2 3 +/1 2 3+/1 2 3
> > 3 1
> > 4 3
> > 5 6
> > 6 7
> > 7 6
> > 8 3
> > 9 1
> >
> > With that map from one collection of universes to the next, I could
> > write a step function representing a player taking their turn:
> >
> > NB. y is universe counts
> > NB. leading dimension of y represents current player
> > NB. scores over 20 end the game and get counted
> > NB. x is the player id for this move
> > adv=: {{
> >  next=. map +/ .*y
> >  wins=:((x{wins)+x:+/,210}. next) x} wins
> >  210{. next
> > }}
> >
> > And, my puzzle solution starts with a single universe (based on the
> > starting position and a score of zero), and runs until every universe
> > has won, then reports on the largest number of wins for any player:
> >
> > b21=:{{
> >  wins=: 0 0x
> >  uni=. 1 (<<:y)} 210 210$0
> >  while. 0 < >./,uni do.
> >    uni=. |: 1 adv |: 0 adv uni
> >  end.
> >> ./wins
> > }}
> >
> > With the example data:
> >
> >   b21 4 8
> > 444356092776315
> >
> > Possibly the only remaining tricky thing in b21 itself was that I'm
> > using position indices (0 .. 9) rather than position labels (1 .. 10)
> > to indicate the position of pawns on the circular track.
> >
> > Anyways, I hope this made sense.
> >
> > Thanks,
> >
> > --
> > Raul
> > ----------------------------------------------------------------------
> > 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

Reply via email to