5
\$\begingroup\$

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.

Task

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.

Hue map of flip flop

\$\endgroup\$
  • \$\begingroup\$ @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. \$\endgroup\$ – Hood Dec 20 '19 at 22:25
3
\$\begingroup\$

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)
   +                    | - Add to
    ọ                   |   - 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
\$\endgroup\$
2
\$\begingroup\$

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)or`n`.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...

\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 64 bytes

Nθ≔⁰ε≔¹δFN«⟦I﹪εθ⟧≦⊕ιF⁺№Iι7№E↨ι⁷﹪ιX⁷⊕λ⁰≦±δ≧⁺×δ⊕⁺№Iι8№E↨ι⁸﹪ιX⁸⊕λ⁰ε

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

Nθ

Input the number of players.

≔⁰ε

Set the current player to player 0.

≔¹δ

Set the initial direction of play.

FN«

Loop for the given number of turns.

⟦I﹪εθ⟧

Output the current player.

≦⊕ι

1-index the current turn.

F⁺№Iι7№E↨ι⁷﹪ιX⁷⊕λ⁰

Count the number of flips.

≦±δ

Reverse the direction of play for each flip.

≧⁺×δ⊕⁺№Iι8№E↨ι⁸﹪ιX⁸⊕λ⁰ε

Calculate the next player to play.

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

Nθ≔⁰ε≔¹δFN«≦⊕ι≔⁺№Iι7№E↨ι⁷﹪ιX⁷⊕λ⁰η≔⁺№Iι8№E↨ι⁸﹪ιX⁸⊕λ⁰ζ⟦⪫⟦⊕﹪εθ∨⁺×flipη×flopζι⟧:⟧≧×X±¹ηδ≧⁺×δ⊕ζε

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.