# Play flip--flop

Flip flop is a memory / arithmetic game that I played in high school. Some number of players stand in a circle. The players take turns. On the nth turn, the current player checks:

1. What is the largest power of 7 dividing n?
2. How many instances of the digit 7 does the decimal representation of n contain?
3. What is the largest power of 8 dividing n?
4. How many instances of the digit 8 does the decimal representation of n contain?

Let FLIPS(n) be the sum of the power of 7 dividing n and the number of 7's n contains. For example, FLIPS(7)=2 (divisible by 7 once, contains one 7), FLIPS(14) = 1 (divisible by 7 once, contains zero 7's), FLIPS(17)=1 (not divisible by 7, contains one 7).

Let FLOPS(n) be the sum of the power of 8 dividing n and the number of 8's n contains.

On a player's turn, if FLIPS(n)=FLOPS(n)=0 they say n. Otherwise, they first say "flip" FLIPS(n) times and then say "flop" FLOPS(n) times.

If FLIPS(n) is odd, the direction of play swaps (from counterclockwise to clockwise or from clockwise to counterclockwise). The next FLOPS(n) players in the new play order are skipped.

Write a program that takes a pair of integers (num_players, turns) and plays Flipflop with a group of num_players players for turns turns. Output should be a list of the current_player on the nth turn. The players are numbered 1 through num_players. The player to the left of player 1 is player num_players. (If it's more convenient to label the players 0 to num_players - 1, that is fine too.) Play begins with player 1 in counterclockwise order.

## Example:

I'll give an example with 5 players. For the first 6 turns nothing interesting happens:

1. Player 1 says "1" (CCW)
2. Player 2 says "2" (CCW)

...

1. Player 5 says "5" (CCW)
2. Player 1 says "6" (CCW)
3. Player 2 says "flipflip" (still CCW FLIPS(7)=2 is even)
4. Player 3 says "flopflop" (CCW, skip players 4 and 5)
5. Player 1 says "9" (CCW)

...

1. Player 1 says "flip" (now CW play order)
2. Player 5 says "15" (CW)
3. Player 4 says "flop" (CW)
4. Player 2 says "flip" (now CCW)
5. Player 3 says "flop" (CCW)
6. Player 5 says "19" (CCW)

The 70's and 80's have a lot of activity. When trying to actually play this game, it is hard to remember where in this 20 digit sequence you are (though 700 / 800 is much worse).

1. Player 4 says "69" (CW)
2. Player 3 says "flipflip" (still CW)
3. Player 2 says "flip" (CCW)
4. Player 3 says "flipflop" (CW)
5. Player 1 says "flip" (CCW)
6. Player 2 says "flip" (CW)
7. Player 1 says "flip" (CCW)
8. Player 2 says "flip" (CW)
9. Player 1 says "flipflipflip"(CCW)
10. Player 2 says "flipflop" (CW)
11. Player 5 says "flip" (CCW)
12. Player 1 says "flopflop" (CCW)
13. Player 4 says "flop" (CCW)
14. Player 1 says "flop" (CCW)
15. Player 3 says "flop" (CCW)
16. Player 5 says "flipflop" (CW)
17. Player 3 says "flop" (CW)
18. Player 1 says "flop" (CW)
19. Player 4 says "flipflop" (CCW)
20. Player 1 says "flopflopflop"(CCW)
21. Player 5 says "flop" (CCW)
22. Player 2 says "90" (CCW)

## Scoring

This is code golf, so shortest answer in bytes wins.

## Test Cases:

[2,100] => {1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,1,2,2,1,2,1,1,2,1,2,2,1,2,1,2,1,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,2,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,1,2,2,1}
[3,100] => {1,2,3,1,2,3,1,2,2,3,1,2,3,1,3,2,3,1,3,1,2,1,3,2,3,2,1,2,3,2,1,3,1,3,2,3,1,3,1,3,1,3,1,2,3,1,2,1,1,3,2,1,3,2,1,3,2,1,2,1,3,2,1,2,2,3,1,3,1,3,2,3,1,2,1,2,1,2,3,1,1,3,2,1,2,3,1,3,1,3,1,3,2,1,3,2,3,1,3,1}
[4,100] => {1,2,3,4,1,2,3,4,3,4,1,2,3,4,3,2,4,1,3,4,1,4,3,2,4,3,2,3,1,4,3,2,4,3,2,3,4,3,1,4,2,1,2,3,4,1,2,1,2,1,4,3,2,1,4,3,1,4,2,1,4,3,2,3,2,3,4,3,1,4,3,4,2,3,2,3,2,3,1,2,1,3,1,3,1,3,1,3,3,1,2,1,4,3,2,1,3,4,2,3}
[5,100] => {1,2,3,4,5,1,2,3,1,2,3,4,5,1,5,4,2,3,5,1,2,1,5,4,2,1,5,1,4,3,2,1,4,3,2,3,4,3,1,5,3,2,3,4,5,1,2,1,3,2,1,5,4,3,2,1,3,2,5,4,3,2,1,2,5,1,2,1,4,3,2,3,1,2,1,2,1,2,5,1,4,1,3,5,3,1,4,1,5,2,3,2,1,5,4,3,1,2,4,5}
[6,100] => {1,2,3,4,5,6,1,2,5,6,1,2,3,4,3,2,6,1,3,4,5,4,3,2,6,5,4,5,3,2,1,6,4,3,2,3,4,3,1,6,4,3,4,5,6,1,2,1,4,3,2,1,6,5,4,3,5,4,2,1,6,5,4,5,2,3,4,3,1,6,5,6,4,5,4,5,4,5,3,4,1,3,5,1,5,3,1,3,1,3,4,3,2,1,6,5,3,4,6,1}
[7,100] => {1,2,3,4,5,6,7,1,4,5,6,7,1,2,1,7,5,6,1,2,3,2,1,7,5,4,3,4,2,1,7,6,4,3,2,3,4,3,1,7,5,4,5,6,7,1,2,1,5,4,3,2,1,7,6,5,7,6,4,3,2,1,7,1,4,5,6,5,3,2,1,2,7,1,7,1,7,1,6,7,3,5,7,2,7,5,3,5,2,4,5,4,3,2,1,7,5,6,1,2}


## A picture

I had 100 players play the game for $$\200^2\$$ steps, made it into a 200 by 200 square and colored the squares by hue. Made with Mathematica.

• @Arnauld I will add largest e.g., "What is the largest power of p dividing n?" but 1 is p^0, so that would be the zeroth power.
– Hood
Dec 20, 2019 at 22:25

# Jelly, 35 22 bytes

Dċ¥+ọɗþ7,8Ä-*Ɗ‘ƭ€P1;Ä%


Try it online!

A dyadic link that takes the number of turns as the left argument and number of players as the right. Players and numbered from 0 to number of players - 1 and play starts with player 1. Currently returns the start player and the current player after each turn (so 101 players in total); this could easily be changed to omit the final one at the cost of a byte.

As a bonus, here's a version that prints the player and what they say.

## Explanation

     ɗþ7,8              | Outer table using the following as a dyad and [7,8] as the rught argument (and 1..number of turbs as left argument)
¥                     | - Following as a dyad
D                       |   - Convert to decimal digits
ċ                      |   - Count (right argument)
ọ                   |   - Order (power of right argument that exactly divides left argument)
ƭ€         | Alternate between the following:
Ɗ            | - For first list (flips), following as a monad:
Ä               |   - Cumulative sum
-*             |   - -1 to the power of this
‘           | - For second list (flops) add 1
P      | Product (flips × flops)
1;    | Prepend 1
Ä   | Cumulative sum
%  | Modulo number of players


# Python 2, 143 bytes

def f(P,m):r=[];p=0;d=i=1;exec"r+=[p%P];d*=g(i,7)%2*2-1;p+=d*g(i,8);i+=1;"*m;return r
g=lambda n,b,k=1:n%b**k<1and g(n,b,k+1)orn.count(b)+k


Try it online!

Input in P number of players, m rounds. Output is 0 indexed.

The function g(n,b) returns flips(n)+1 or flops(n)+1 with b=7,8, respectively. That +1 saves a byte or three...

# JavaScript (ES6),  121 117  115 bytes

Takes input as (players)(turns). The output is 0-indexed.

P=>T=>(F=p=>++t>T?[]:[p%P,...F(p+(g=(x,n=t)=>n%x?(t+g).split(x).length:1+g(x,n/x))(8)*(d*=g(7)&1||-1)+P)])(t=0,d=1)


Try it online! (raw output)

Try it online! (post-processing for 1-indexed output)

### Commented

P => T => (                   // P = number of players, T = number of turns
F = p =>                    // F = recursive function taking the current player ID p
++t > T ?                 // increment the turn ID; if it's greater than T:
[]                      //   stop recursion
:                         // else:
[                       //   update the output array:
p % P,                //     append the current player ID
...F(                 //     append the result of a recursive call:
p + (               //       update p ...
g = (x,           //         g is a helper function taking x = 7 or 8
n = t) => //         and a counter n initialized to t
n % x ?         //         if x is not a divisor of n:
(t + g)       //           coerce t to a string
.split(x)     //           and count the number of occurrences of x
.length       //           plus 1
:               //         else:
1 +           //           increment the result
g(x, n / x)   //           recursive call with n / x
)(8) * (            //       invoke g(8) = FLOPS(t) + 1
d *= g(7) & 1     //         leave d unchanged if g(7) = FLIPS(t) + 1 is odd
|| -1        //         otherwise, update d to -d
) + P               //       make sure that p remains positive
)                     //     end of recursive call
]                       //   end of output update
)(t = 0, d = 1)               // initial call to F with p = t = 0 and d = 1


# Charcoal, 64 bytes

Ｎθ≔⁰ε≔¹δＦＮ«⟦Ｉ﹪εθ⟧≦⊕ιＦ⁺№Ｉι7№Ｅ↨ι⁷﹪ιＸ⁷⊕λ⁰≦±δ≧⁺×δ⊕⁺№Ｉι8№Ｅ↨ι⁸﹪ιＸ⁸⊕λ⁰ε


Try it online! Link is to verbose version of code. Players are 0-indexed. Explanation:

Ｎθ


Input the number of players.

≔⁰ε


Set the current player to player 0.

≔¹δ


Set the initial direction of play.

ＦＮ«


Loop for the given number of turns.

⟦Ｉ﹪εθ⟧


Output the current player.

≦⊕ι


1-index the current turn.

Ｆ⁺№Ｉι7№Ｅ↨ι⁷﹪ιＸ⁷⊕λ⁰


Count the number of flips.

≦±δ


Reverse the direction of play for each flip.

≧⁺×δ⊕⁺№Ｉι8№Ｅ↨ι⁸﹪ιＸ⁸⊕λ⁰ε


Calculate the next player to play.

Bonus 91-byte version outputs what each player says too:

Ｎθ≔⁰ε≔¹δＦＮ«≦⊕ι≔⁺№Ｉι7№Ｅ↨ι⁷﹪ιＸ⁷⊕λ⁰η≔⁺№Ｉι8№Ｅ↨ι⁸﹪ιＸ⁸⊕λ⁰ζ⟦⪫⟦⊕﹪εθ∨⁺×flipη×flopζι⟧:⟧≧×Ｘ±¹ηδ≧⁺×δ⊕ζε


Try it online! Link is to verbose version of code.

# Vyxal, 26 bytes

ƛ78fMƛ÷₍ǑO∑;;∩÷›u„¦e*¦Ȯ%0p


Try it Online!

Pretty much a port of Nick Kennedy's Jelly answer. First argument turns-1, second argument num_players, players are zero-indexed.

## How?

                           #                 e.g. stack (top ->)
ƛ78fMƛ÷₍ǑO∑;;∩÷›u„¦e*¦Ȯ%0p #                      100
ƛ                          # for i = 1..turns     77
78f                       #   push, split        77 [7,8]
M                      #   pair               [77,7] [77,8]
ƛ                     #   for [i,7] [i,8]    [77,7]
÷                    #     split            77 7
₍                   #     parallel apply
Ǒ                  #       multiplicity   1
O                 #       count          2
#     end              [1,2]
∑                #     sum              3
;               #   end                [3,0]
;              # end                  [[0,0],[0,0],[0,0],...]
∩             # transpose            [[0,0,0,...],[0,0,0,...]]
÷            # split                [0,0,0,...] [0,0,0,...]
›           # increment            [0,0,0,...] [1,1,1,...]
u          # push -1              [0,0,0,...] [1,1,1,...] -1
„         # rotate left          [1,1,1,...] -1 [0,0,0,...]
¦        # prefix sum           [1,1,1,...] -1 [0,0,0,...]
e       # exponent             [1,1,1,...] [1,1,1,...]
*      # multiply             [1,1,1,...]
¦     # prefix sum           [1,2,3,...]
Ȯ    # over                 [1,2,3,...] 3
%   # modulo               [1,2,0,...]
0p # prepend 0            [0,1,2,...]