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

Reply via email to