The game of Sevens! Who said what?

14

0

The game of Sevens is played as follows: n players sit in a circle, and start counting up from 1, passing to the left (or from player A to player B).

When a number p that has a 7 in it OR is divisible by 7 is reached, then the player who spoke the number p-1, after the next player says p, must say p+1 and the order of people speaking reverses. For example, if player B speaks 6, player C says 7, B says 8, and player A says 9.

Note: For those who want to play in real life, if a person forgets a number (or in the version where sevens are not said, accidentally says a seven), they are eliminated from the circle, but we will omit this detail from this challenge.

The challenge itself is to print which numbers each player should say in a perfect game of Sevens up to an input m for an input n players.

As an example, where five people, A, B, C, D, and E, are to play till they reach 30. They play in this manner

A: 1 6 8 13    15 19       23    30
B: 2 7*  12    16 18       24
C: 3     11    17*         25
D: 4     10          21*   26 28*
E: 5      9 14*      20 22 27*29

where sevens are marked with *. Note that at 27 and 28, we're reversing twice, and play continues "as normal" from D to E.

Please note that the output does not have to be in the above format. I simply printed it that way for some clarity.

Rules

  • The input is two integers in any order, m representing the last number to say, n representing the number of players.

  • The output can be several arrays or several strings, one for each player. If you use strings, you do not have to use separators (though, if you could add some in your code tests, we would appreciate the readability). If you can actually print them in a circle somehow, that is acceptable as well, and it would be pretty cool too.

  • The output does not have to designate which players are which (it's fairly obvious that the first player is the one who says 1), though if the output isn't sorted for whatever reason, you should make clear which player is speaking which set of numbers. Omitting players who do not say anything is also allowed if you make it clear which players are speaking. I will add some more examples of possible outputs below.

  • This is code golf, so the smallest number of bytes wins.

As always, if the problem is unclear, please let me know. Good luck and good golfing!

Examples

>>> sevens_string(30, 5, " ")
'1 6 8 13 15 19 23 30'
'2 7 12 16 18 24'
'3 11 17 25'
'4 10 21 26 28'
'5 9 14 20 22 27 29'
>>> sevens_string(42, 5)
'16813151923303539'
'27121618243140'
'31117253241'
'410212628333742'
'591420222729343638'
>>> sevens_array(20, 3)
[1, 4, 7, 10, 13, 15, 19]
[2, 5, 9, 12, 16, 18]
[3, 6, 8, 11, 14, 17, 20]
>>> sevens_array(18, 10)
[1, 13, 15]
[2, 12, 16, 18]
[3, 11, 17]
[4, 10]
[5, 9]
[6, 8]
[7]
[]
[]
[14]

Sherlock9

Posted 2015-12-07T10:28:48.157

Reputation: 11 664

I think a more useful output for purposes of visualizing the game play would be a list of players in order of play. (E.g. with 4 players and a max of 15, that'd be 1 2 3 4 1 2 3 2 1 4 3 2 1 4 1.) I'm not saying that's better or worse in terms of he challenge: just that it'd be more useful in the real world. – msh210 – 2016-05-22T06:50:46.320

Can we display the result as a matrix and pad with zeroes? – Dennis – 2016-05-22T07:16:22.090

@Dennis Empty arrays should be kept. The result may be a zero-padded matrix. – Sherlock9 – 2016-05-23T04:41:29.920

Answers

2

Pyth, 38 bytes

Jm[)EA,01VQa@JZ=hG=+Z=W|}\7`G!%G7H_H;J

Try it online. Test suite.

Basically a port of my Python answer; there's probably a better way. Takes as input the number to count up to n and the number of players p on separate lines, outputs the result as a two-dimensional array.

PurkkaKoodari

Posted 2015-12-07T10:28:48.157

Reputation: 16 699

3

Haskell, 151 bytes

s n|elem '7'(show n)||mod n 7==0=(0-)|0<1=id
a=scanl1(+)$map($1)$scanl(.)id$map s[1..]
f m n=mapM_ print[[x+1|x<-[0..m-1],mod(a!!x-1)n==i]|i<-[0..n-1]]
*Main> f 30 5
[1,6,8,13,15,19,23,30]
[2,7,12,16,18,24]
[3,11,17,25]
[4,10,21,26,28]
[5,9,14,20,22,27,29]

Damien

Posted 2015-12-07T10:28:48.157

Reputation: 2 407

2How about mod n 7<1 instead of mod n 7==0 and s<$>[1..] instead of map s[1..]? Also, why not print[] instead of mapM_ print[]? – Michael Klein – 2016-05-22T01:09:33.610

2

Python 3, 155 bytes

from turtle import*
def f(m,n,i=0,r=20,d=360):
 k=n
 while i<m:i+=1;fd(r);write(i);bk(r);e='7'[:i%7]in str(i);d*=1-2*e;k=~-e*(1-k)%n;r+=(k<1)*15;rt(d/n)

Uses turtle graphics to print in a circle such that numbers spoken by the same player are on the same radius. The radius of the circle is increased when the direction is reversed, or when the sequence wraps around the circle, so previous numbers aren't overwritten.

Sample output for f(22,6)

enter image description here

RootTwo

Posted 2015-12-07T10:28:48.157

Reputation: 1 749

Ooh, this is clever and pretty. +1 :D – Sherlock9 – 2016-05-29T11:12:18.043

1

Python 2, 103 102 101 bytes

def S(n,p):
 P=0;D=N=1;O=['']*p
 while n:O[P%p]+=`N`;D*=1-2*(N%7<1or'7'in`N`);N+=1;P+=D;n-=1
 print O

Defines a function S(n,p) that takes the number to count to n and the number of players p and prints the result as an array of strings.

>>> S(42,5)
['16813151923303539', '27121618243140', '31117253241', '410212628333742','591420222729343638']

PurkkaKoodari

Posted 2015-12-07T10:28:48.157

Reputation: 16 699

1

Python 2, 91 90 87 bytes

def f(m,n):a=d=i=0;r=[()]*n;exec"i+=1;r[a%n]+=i,;d^='7'[:i%7]in`i`;a+=1-2*d;"*m;print r

Prints a list of tuples. Test it on Ideone.

Dennis

Posted 2015-12-07T10:28:48.157

Reputation: 196 637

1

Jelly, 27 25 bytes (non-competing)

D;Æf7e
R’Ç€^\ḤC+\_'R}⁹ḍT€

Try it online! or verify all test cases.

Dennis

Posted 2015-12-07T10:28:48.157

Reputation: 196 637

why is this not-competing – Bálint – 2016-05-22T06:42:10.423

Because the challenge is from December 2015 and predates the creation of Jelly. – Dennis – 2016-05-22T06:43:26.590

Oh, thanks for clarification! – Bálint – 2016-05-22T07:40:44.120

Is that an official rule? I never check the question date against programming language invention date. – Thomas Weller – 2016-05-22T18:19:09.903

@ThomasWell Can I ever answer with a language invented after the challenge was posted?

– Dennis – 2016-05-22T18:55:07.093

Thanks for the link. I guess I'll rely on the moderation - that someone will leave a comment or delete the answer. – Thomas Weller – 2016-05-24T19:19:30.337

1

Dyalog APL, 50 47 35 bytes

{,⌸⍵|+\0,¯1*+\{0=7|⍵×~7∊⍎¨⍕⍵}¨⍳⍺-1}

This displays the numbers each player said as a table, where the first column enumerates the players. Rows are padded with 0s to the same length, and rows without numbers are omitted.

Verification

      f ← {,⌸⍵|+\0,¯1*+\{0=7|⍵×~7∊⍎¨⍕⍵}¨⍳⍺-1}
      30 f 5
0 1  6  8 13 15 19 23 30
1 2  7 12 16 18 24  0  0
2 3 11 17 25  0  0  0  0
3 4 10 21 26 28  0  0  0
4 5  9 14 20 22 27 29  0
      42 f 5
0 1  6  8 13 15 19 23 30 35 39
1 2  7 12 16 18 24 31 40  0  0
2 3 11 17 25 32 41  0  0  0  0
3 4 10 21 26 28 33 37 42  0  0
4 5  9 14 20 22 27 29 34 36 38
      20 f 3
0 1 4 7 10 13 15 19
1 2 5 9 12 16 18  0
2 3 6 8 11 14 17 20
      14 f 10
0  1 13
1  2 12
2  3 11
3  4 10
4  5  9
5  6  8
6  7  0
9 14  0

Note that, in the last example, 7 and 8 are omitted since those players haven't said anything yet.

Dennis

Posted 2015-12-07T10:28:48.157

Reputation: 196 637

1

Ruby, 81

->n,m{g=[""]*n
k=j=0
i=1
m.times{g[j%n]+=w="#{k+=1}"
j+=i=k%7<1||w[/7/]?-i :i}
g}

Pretty straightforward implementation. Returns an ugly glommed string (you can add a space to make it "#{k+=1} " for... well, a spaced string). I wonder if there's a more mathematical algorithm out there.

Not that Charles

Posted 2015-12-07T10:28:48.157

Reputation: 1 905

1

Factor 172

I managed to do it longer than Haskell, and as readable as APL! Do I get a cookie?

[| l! n! | 1 0 0 :> ( p! x! z! ) n iota [ 1vector ] map <circular> n! l iota [ 1 + z! z 7 mod 0 = 55 z 10 >base in? or -1 and 1 or p * p! z x n nth push x p + x! ] each n ]

It's a quotation (anonymous function) that outputs a circular sequence of vectors. Each vector starts with the number of player, and then the numbers that correspond to that player.

30 5 [| l! n! | 1 0 0 :> ( p! x! z! ) n iota [ 1vector ] map <circular> n! l iota [ 1 + z! z 7 mod 0 = 55 z 10 >base in? or -1 and 1 or p * p! z x n nth push x p + x! ] each n ] call

Outputs:
T{ circular
    { seq
        {
            V{ 0 1 6 8 13 15 19 23 30 }
            V{ 1 2 7 12 16 18 24 }
            V{ 2 3 11 17 25 }
            V{ 3 4 10 21 26 28 }
            V{ 4 5 9 14 20 22 27 29 }
        }      ^ Note: first val is player number starting at 0
    }
}

I started with this:

: game-of-7 ( last-num num-players -- {players:={numbers}} )
  1 1 set ! increment
  0 2 set ! current-index
  iota [ drop V{ } clone ] map <circular>
  swap iota
  [ 1 + ! iotas go 0 to n-1
    dup [ 7 mod 0 = ] [ 10 >base 55 swap in? ] bi or
    [ 1 get -1 * 1 set ] when
    over 2 get swap nth push
    2 get 1 get + 2 set
  ] each ;

which is not good factor code, but a lot more clear (yes, I'm using numbers as variable names there, don't look at me like that!).

fede s.

Posted 2015-12-07T10:28:48.157

Reputation: 945

"Do I get a cookie?" Yes, you do. – Leaky Nun – 2016-05-27T14:45:09.020

Wow, that was unexpected! Ty, @LeakyNun :D – fede s. – 2016-05-27T17:41:52.233

Wow, I love this! Curse you for using numbers as identifiers! – cat – 2016-06-22T12:12:37.457

1@cat i actually like it in a perverse way :P But locals solve the length issue of SYMBOL: a lot better: one letter names, and getting rid of set and get! – fede s. – 2016-06-23T18:41:13.183

0

JavaScript (ES6) 100

Returning result as a string array, no separators

(m,n)=>(d=>{for(r=[],p=i=0;i++<m;d=i%7&&!~(i+'').search(7)?d:n-d,p=(p+d)%n)r[p]=(r[p]||'')+i})(1)||r

Or more readable, for 3 bytes more, returning result as an array of arrays

(m,n)=>(d=>{for(r=[],p=i=0;i++<m;d=i%7&&!~(i+'').search(7)?d:n-d,p=(p+d)%n)r[p]=[...r[p]||[],i]})(1)||r

Test Using the new wonderful console feature of the Stack Snippets

S=(m,n)=>(d=>{for(r=[],p=i=0;i++<m;d=i%7&&!~(i+'').search(7)?d:n-d,p=(p+d)%n)r[p]=(r[p]||'')+i})(1)||r

A=(m,n)=>(d=>{for(r=[],p=i=0;i++<m;d=i%7&&!~(i+'').search(7)?d:n-d,p=(p+d)%n)r[p]=[...r[p]||[],i]})(1)||r

console.log(S(42,5))
console.log(A(20,3))

edc65

Posted 2015-12-07T10:28:48.157

Reputation: 31 086

0

J, 63 60 59 58 56 bytes

4 :'>:@I.(i.y)=/y|+/\0,_1^+/\(7 e."1 q:,.10#.inv])}.i.x'

Verification

   f =: 4 :'>:@I.(i.y)=/y|+/\0,_1^+/\(7 e."1 q:,.10#.inv])}.i.x'
   30 f 5
1  6  8 13 15 19 23 30
2  7 12 16 18 24  0  0
3 11 17 25  0  0  0  0
4 10 21 26 28  0  0  0
5  9 14 20 22 27 29  0
   42 f 5
1  6  8 13 15 19 23 30 35 39
2  7 12 16 18 24 31 40  0  0
3 11 17 25 32 41  0  0  0  0
4 10 21 26 28 33 37 42  0  0
5  9 14 20 22 27 29 34 36 38
   20 f 3
1 4 7 10 13 15 19
2 5 9 12 16 18  0
3 6 8 11 14 17 20
   14 f 10
 1 13
 2 12
 3 11
 4 10
 5  9
 6  8
 7  0
 0  0
 0  0
14  0

Dennis

Posted 2015-12-07T10:28:48.157

Reputation: 196 637