14
\$\begingroup\$

When I was a child I used to play a variation ofSnap to stake soccer trading cards.
"Game" is an overstatement because the only role of the players is to secretly prepare their starting piles. As the game starts there are no choices other than just perform the game algorithm.

Rules

There is no maximum number of players and they all start with a fixed number of cards.
Players in turn play the top card of their piles on a common pile (initially empty).

If the current player has no cards, the common pile bottom card will be played.

When a player happens to play an equal card to that on top of the common pile:

  • This player will take the common pile and append it face-down to his own pile. (Players' piles are face-down but the common pile is face-up, so the pair of equal cards should end up at the bottom)
  • Anyone with no cards is out of the game.
  • This player has to resume the game replenish the common pile with their top card as usual.

The game ends in one of three scenarios:

  • one player has all the cards (they win)
  • all the cards are in the common pile, the next player rotates it but doesn't form a pair (the common pile can't be taken)
  • one previous state of the game reoccurs (the game gets stuck in a loop)

Step by step game examples

1) Initial configuration: "abba abca"     p1      p2      common pile 1   abba    abca 2   bba     abca    a 3   bba     bca     aa 4           TAKES 5   bba     bcaaa 6   bba     caaa    b 7   ba      caaa    bb 8   TAKES 9   babb    caaa10   abb     caaa    b11   abb     aaa     bc12   bb      aaa     bca13   bb      aa      bcaa14           TAKES15   bb      aabcaa16   bb      abcaa   a17   b       abcaa   ab18   b       bcaa    aba19           bcaa    abab20           caa     ababb21   OUT     TAKES22           caaababb============ p2 wins ============2) Initial configuration: "abba acab"      p1      p2      common pile  1   abba    acab  2   bba     acab    a  3   bba     cab     aa  4           TAKES  5   bba     cabaa  6   bba     abaa    c  7   ba      abaa    cb  8   ba      baa     cba  9   a       baa     cbab 10   a       aa      cbabb 11           TAKES 12   a       aacbabb 13   a       acbabb  a 14           acbabb  aa 15   TAKES 16   aa      acbabb 17   a       acbabb  a 18   a       cbabb   aa 19           TAKES 20   a       cbabbaa 21   a       babbaa  c 22           babbaa  ca 23           abbaa   cab 24           abbaa   abc 25           bbaa    abca 26           bbaa    bcaa 27   TAKES 28   bcaa    bbaa 29   caa     bbaa    b 30   caa     baa     bb 31           TAKES 32   caa     baabb 33   caa     aabb    b 34   aa      aabb    bc 35   aa      abb     bca 36   a       abb     bcaa 37   TAKES 38   abcaa   abb 39   bcaa    abb     a 40   bcaa    bb      aa 41           TAKES 42   bcaa    bbaa 43   bcaa    baa     b 44   caa     baa     bb 45   TAKES 46   caabb   baa 47   aabb    baa     c 48   aabb    aa      cb 49   abb     aa      cba 50   abb     a       cbaa 51           TAKES 52   abb     acbaa 53   abb     cbaa    a 54   bb      cbaa    aa 55   TAKES 56   bbaa    cbaa 57   baa     cbaa    b 58   baa     baa     bc 59   aa      baa     bcb 60   aa      aa      bcbb 61           TAKES 62   aa      aabcbb 63   aa      abcbb   a 64   a       abcbb   aa 65   TAKES 66   aaa     abcbb 67   aa      abcbb   a 68   aa      bcbb    aa 69           TAKES 70   aa      bcbbaa 71   aa      cbbaa   b 72   a       cbbaa   ba 73   a       bbaa    bac 74           bbaa    baca 75           baa     bacab 76           baa     acabb 77   TAKES 78   acabb   baa 79   cabb    baa     a 80   cabb    aa      ab 81   abb     aa      abc 82   abb     a       abca 83   bb      a       abcaa 84   TAKES 85   bbabcaa a 86   babcaa  a       b 87   babcaa          ba 88   abcaa           bab 89   abcaa           abb 90           TAKES 91   abcaa   abb 92   abcaa   bb      a 93   bcaa    bb      aa 94   TAKES 95   bcaaaa  bb 96   caaaa   bb      b 97   caaaa   b       bb 98           TAKES 99   caaaa   bbb100   caaaa   bb      b101   aaaa    bb      bc102   aaaa    b       bcb103   aaa     b       bcba104   aaa             bcbab105   aa              bcbaba106   aa              cbabab107   a               cbababa108   a               bababac109                   bababaca110                   ababacab // common pile can't be taken============ p1, p2 in game ============3) Initial configuration: "bdad acbc abba"     p1          p2          p3          common pile 1   bdad        acbc        abba 2   dad         acbc        abba        b 3   dad         cbc         abba        ba 4   dad         cbc         bba         baa 5                           TAKES 6   dad         cbc         bbabaa 7   dad         cbc         babaa       b 8   ad          cbc         babaa       bd 9   ad          bc          babaa       bdc10   ad          bc          abaa        bdcb11   d           bc          abaa        bdcba12   d           c           abaa        bdcbab13   d           c           baa         bdcbaba14               c           baa         bdcbabad15                           baa         bdcbabadc16                           aa          bdcbabadcb17                           aa          dcbabadcbb18   TAKES       OUT19   dcbabadcbb              aa20   cbabadcbb               aa          d21   cbabadcbb               a           da22   babadcbb                a           dac23   babadcbb                            daca24   abadcbb                             dacab25   abadcbb                             acabd26   badcbb                              acabda27   badcbb                              cabdaa28                           TAKES29   badcbb                  cabdaa30   badcbb                  abdaa       c31   adcbb                   abdaa       cb32   adcbb                   bdaa        cba33   dcbb                    bdaa        cbaa34   TAKES35   dcbbcbaa                bdaa36   cbbcbaa                 bdaa        d37   cbbcbaa                 daa         db38   bbcbaa                  daa         dbc39   bbcbaa                  aa          dbcd40   bcbaa                   aa          dbcdb41   bcbaa                   a           dbcdba42   cbaa                    a           dbcdbab43   cbaa                                dbcdbaba44   baa                                 dbcdbabac45   baa                                 bcdbabacd46   aa                                  bcdbabacdb47   aa                                  cdbabacdbb48                           TAKES49   aa                      cdbabacdbb50   aa                      dbabacdbb   c51   a                       dbabacdbb   ca52   a                       babacdbb    cad53                           babacdbb    cada54                           abacdbb     cadab55                           abacdbb     adabc56                           bacdbb      adabca57                           bacdbb      dabcaa58   TAKES59   dabcaa                  bacdbb60   abcaa                   bacdbb      d61   abcaa                   acdbb       db62   bcaa                    acdbb       dba63   bcaa                    cdbb        dbaa64                           TAKES65   bcaa                    cdbbdbaa66   bcaa                    dbbdbaa     c67   caa                     dbbdbaa     cb68   caa                     bbdbaa      cbd69   aa                      bbdbaa      cbdc70   aa                      bdbaa       cbdcb71   a                       bdbaa       cbdcba72   a                       dbaa        cbdcbab73                           dbaa        cbdcbaba74                           baa         cbdcbabad75                           baa         bdcbabadc76                           aa          bdcbabadcb77                           aa          dcbabadcbb78   TAKES79   dcbabadcbb              aa                       // loop (line 19)============ p1, p3 in game ============

N.B. game states are inviduated by piles configuration and current player. As you can see in example2) lines 28, 42 are not the same game state.

Input

A list of players' piles (top to bottom) as:

  • an array of strings["code", "golf", "fold"], or
  • a matrix of positive integers[[1,2,3,4],[5,2,6,7],[7,2,6,3]]

Players order is implied by piles order.

Output

A number indicating the player who wins or a list of numbers for the players who reach the end of the game.
You decide whether players are 0 or 1 indexed.

I/O Examples (1-indexed players):

"abca abba"      -> 1"abba abca"      -> 2"abba acab"      -> 1 2"bdad acbc abba" -> 1 3"fizz buzz"      -> 2"robinhooda ndlittlejo hnwalkingt hroughthef orestlaugh ingbackand forthatwha ttheothero nehastosay" -> 9
askedSep 4, 2021 at 18:16
Domenico's user avatar
\$\endgroup\$
11
  • 2
    \$\begingroup\$"If the current player has no cards they will rotate the common pile placing on top the card at the bottom." was not entirely clear to me until working through the second and third example games, perhaps a better wording would be "If the current player has no cards they will play the card from the bottom of the common pile"?\$\endgroup\$CommentedSep 5, 2021 at 13:22
  • 4
    \$\begingroup\$Although I have already completed the challenge, I faced some difficulties and misunderstandings along the way. To make the challenge clearer for future viewers, maybe change wordings to be more precise? For instance it was not entirely clear that the player who takes the pile gets another turn. Perhapsanyone with no cards is out of the game. The player who took the pile has to then replenish the pile with one card is better because I was not sure who "they" was.\$\endgroup\$CommentedSep 5, 2021 at 13:30
  • 1
    \$\begingroup\$@Domenico the edit is for inclusion, it's true that in my generation girls would have been de facto excluded from soccer card games or would have to argue to be let in (or because they weren't interested), but the world is a-changing!\$\endgroup\$CommentedSep 6, 2021 at 8:04
  • 1
    \$\begingroup\$@Kaddath Oh, I didn't realize it. I'm Italian and we always use implied subject, so I perceived those "he" as required transparent links to "the player", avoid of gender meanings. Also didn't know of singular they. Anyway just blindly change all the "he" into "they" can upset the sense, as it did. I'll rephrase the whole thing.\$\endgroup\$CommentedSep 6, 2021 at 12:29
  • 1
    \$\begingroup\$@Domenico Yes I didn't understand too the first time i read it in a question, I'm french and it would be weird for us to use plural for this\$\endgroup\$CommentedSep 6, 2021 at 12:51

3 Answers3

6
\$\begingroup\$

JavaScript (Node.js),483 426 bytes

-57 bytes thanks to @emanresu A

Takes a list of strings as input and indexes from 0.

Try it online!

a=>{a=a.map(p=>[...p]);e=[];t=[];o=[];i=0;g=a.length;m=n=>(n%g+g)%g;r=_=>[...a.keys()].filter(x=>!d(x));d=x=>o.includes(x);q=_=>JSON.stringify([o,i,a,e]);for(;;){if(!d(i)&&(l=e.length==e.unshift(a[i].shift(t.push(q()))||e.pop())&&!a.filter(p=>p[0])[0],(e[0]==e[1]&&e[1]&&(i=m(i-1,a[i].push(...e.reverse())),e=[],o.push(...a.flatMap((p,j)=>p[0]||d(j)?e:j))+1==g)||l)))return l?r():r()[0];if(t.includes(q(i=m(i+1))))return r()}}

Unminified

(a) => {    a = a.map((p) => [...p]);    e = [];    t = [];    o = [];    i = 0;    g = a.length;    m = (n) => ((n % g) + g) % g;    r = (_) => [...a.keys()].filter((x) => !d(x));    d = (x) => o.includes(x);    q = (_) => JSON.stringify([o, i, a, e]);    for (;;) {        if (            !d(i) &&            ((l = e.length == e.unshift(a[i].shift(t.push(q())) || e.pop()) && !a.filter((p) => p[0])[0]),            (e[0] == e[1] && e[1] && ((i = m(i - 1, a[i].push(...e.reverse()))), (e = []), o.push(...a.flatMap((p, j) => (p[0] || d(j) ? e : j))) + 1 == g)) || l)        )            return l ? r() : r()[0];        if (t.includes(q((i = m(i + 1))))) return r();    }};
answeredSep 4, 2021 at 20:27
Joyal Mathew's user avatar
\$\endgroup\$
1
4
\$\begingroup\$

Python 3.8 (pre-release), 378 bytes

def f(s,p='',G=[],V=sorted,E=enumerate): O=V(p.join(s)) while 1:  for i,S in E(s):   if S:p+=S[0];s[i]=S[1:]   elif""==S:p=p[1:]+p[0]   if s[i]!=0<1<len(p)!=p[-2]==p[-1]:s[i]+=p;s=[P or 0for P in s];p=s[i][0];s[i]=s[i][1:]   C=s+[p,i]   if any(a and O==V(a)for a in s)or(O==V(p)*all(a!=b for a,b in zip(p,p[1:]+p[0])))or C in G:return[i for i,S in E(s)if S!=0]   G+=[C]

Try it online!

Wow, was this a pain to write.

Takes in a list of strings, outputs a list of 0-indexed numbers. My code can be slightly changed to output a single value if a single player wins, but I see no rule preventing me from outputting as my code does.

Explanation

Stores game states inG. Astate here is the list of strings followed by the pile and the number indicating whose turn it is (evidently, whose turn it is does make a difference). If the current state has been seen before, we break by setting T to 1. (breaks from the inner loop then from the outer loop)

For each iteration, if S is truthy (current string) we append its first letter to the pile and remove it froms[i]. IfS is empty string, we rotate the pile.

A zero indicates that the player is out; we ignore such cases. If the last two characters ofp are the same, we append the entire pile to the end ofs[i] and reset it, before resuming the game in the same iteration.

The two other checks for the endgame are:

  • if any of the sorted strings ins match the sortedO, or
  • if the sorted pile equals sortedO and there are no neighboring pairs in the pile (end and beginning count as a pair).

To get the list of "in" players, we simply output all indices corresponding to a nonzero entry ins.

Any tips for shortening the code will be greatly appreciated. Thanks to @ovs for-28 -35 bytes!

answeredSep 5, 2021 at 12:01
ophact's user avatar
\$\endgroup\$
5
  • \$\begingroup\$If you move the return statement whereT=1;break currently is, you don't need any breaks orT, which saves a few bytes. Andchained comparisons can probably save a few bytes as well\$\endgroup\$CommentedSep 5, 2021 at 12:40
  • \$\begingroup\$@ovs thanks for the first tip! Not sure where I could use the chained comparisons though.\$\endgroup\$CommentedSep 5, 2021 at 13:05
  • \$\begingroup\$s[i]!=0and len(p)>1and p[-2]==p[-1] ->s[i]!=0<1<len(p)!=p[-2]==p[-1]. And in the lastif you might be able to replaceO==sorted(p)and all(...) with(O==sorted(p)*all(...).\$\endgroup\$CommentedSep 5, 2021 at 13:10
  • \$\begingroup\$I'm glad you liked it, is this one of your first challenges? Anyway, yes, a state of the game includes the current player, as you can se in the example 2) lines 28, 42 have the same piles configuration but the game doesn't end up in a loop. Unfortunately in that example the outcome is the same as would be in a simulation that wrongly detects a loop. If you want you can help me find a test case that differentiates it\$\endgroup\$CommentedSep 5, 2021 at 15:58
  • \$\begingroup\$@Domenico You can just write a comment next to it saying "was seen before, but different player's turn" or something similar.\$\endgroup\$CommentedSep 5, 2021 at 16:04
3
\$\begingroup\$

Perl 5, 209 bytes

sub{(@p,$i,$_,%s,@o)=pop=~/\w+/g;while((@w=grep$p[$_-1],1..@p)>1||y///c and!$s{$i,@p,@o}++){if(!$o[$i]&&($p[$i]=~s,.,,||s,.,,)&&($_.=$&)=~s/.*(.)\1$//){$p[$i].=$&;$p[$_]or$o[$_]=1for 0..$#p;next}$i=++$i%@p}@w}

Try it online!

answeredSep 7, 2021 at 0:51
Kjetil S's user avatar
\$\endgroup\$

Your Answer

More generally…

  • …Please make sure to answer the question and provide sufficient detail.

  • …Avoid asking for help, clarification or responding to other answers (use comments instead).

Draft saved
Draft discarded

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.