Игра Семерок! Кто что сказал?


14

Игра Семерок ведется следующим образом: nигроки садятся в круг и начинают считать с 1, переходя влево (или от игрока Aк игроку B).

Когда достигается число, в pкотором есть 7ИЛИ, делимое на 7, то игрок, который произнес число p-1, после того, как следующий игрок сказал p, должен сказать, p+1и порядок говорящих меняется на обратный. Например, если игрок Bговорит 6, игрок Cговорит 7, Bговорит 8, и игрок Aговорит 9.

Примечание: Для тех, кто хочет играть в реальной жизни, если человек забывает число (или в версии, где sevensне сказано, случайно говорит а seven), они исключаются из круга, но мы опускаем эту деталь из этого вызова.

Сама задача состоит в том, чтобы напечатать, какие числа должен сказать каждый игрок в идеальной игре Семерок, вплоть до входных данных mдля входных nигроков.

В качестве примера, где пять человек, A, B, C, D, и E, призваны играть , пока они не достигают 30. Они играют таким образом

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

где sevensотмечены *. Обратите внимание, что при 27и 28мы дважды меняем направление, и игра продолжается «как обычно» с Dдо E.

Обратите внимание, что вывод не обязательно должен быть в вышеуказанном формате. Я просто напечатал это таким образом для некоторой ясности.

правила

  • Входные данные - это два целых числа в любом порядке, mпредставляющие последнее число, nобозначающее количество игроков.

  • Выходными данными могут быть несколько массивов или несколько строк, по одной для каждого игрока. Если вы используете строки, вам не нужно использовать разделители (хотя, если бы вы могли добавить некоторые из них в свои тесты кода, мы были бы признательны за удобочитаемость). Если вы можете как-то распечатать их по кругу, это тоже приемлемо, и это было бы довольно круто.

  • Выходные данные не должны указывать, какие игроки являются какими (довольно очевидно, что первый игрок - тот, кто говорит 1), хотя, если выходные данные не отсортированы по какой-либо причине, вы должны уточнить, какой игрок говорит, какой набор чисел , Пропускать игроков, которые ничего не говорят, также разрешается, если вы укажете, кто из игроков говорит. Я добавлю еще несколько примеров возможных результатов ниже.

  • Это код гольф, поэтому выигрывает наименьшее количество байтов.

Как всегда, если проблема неясна, пожалуйста, дайте мне знать. Удачи и хорошего гольфа!

Примеры

>>> 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]

Я думаю, что более полезным выводом для визуализации игрового процесса будет список игроков по порядку игры. (Например, с 4 игроками и максимум 15, это было бы 1 2 3 4 1 2 3 2 1 4 3 2 1 4 1.) Я не говорю, что это лучше или хуже с точки зрения его задачи: просто это было бы более полезно в реальном мире.
msh210

Можем ли мы отобразить результат в виде матрицы и заполнить нулями?
Деннис

@ Денис Пустые массивы должны быть сохранены. Результатом может быть заполненная нулями матрица.
Sherlock9

Ответы:


2

Pyth, 38 байт

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

Попробуйте онлайн. Тестирование.

В основном порт моего Python ответа; вероятно, есть лучший способ. Принимает в качестве входных данных число для подсчета nи количество игроков pв отдельных строках, выводит результат в виде двумерного массива.


3

Haskell, 151 байт

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]

2
Как насчет mod n 7<1вместо mod n 7==0и s<$>[1..]вместо map s[1..]? Кроме того, почему бы не print[]вместо mapM_ print[]?
Майкл Кляйн

2

Python 3, 155 байт

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)

Использует графику черепахи для печати по кругу, так что числа, на которых говорит один и тот же игрок, находятся на одном и том же радиусе. Радиус круга увеличивается, когда направление меняется на обратное, или когда последовательность оборачивается вокруг круга, поэтому предыдущие числа не перезаписываются.

Пример вывода для f(22,6)

введите описание изображения здесь


Ох, это умно и красиво. +1: D
Шерлок9

1

Python 2, 103 102 101 байт

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

Определяет функцию, S(n,p)которая принимает число для подсчета nи количество игроков pи печатает результат в виде массива строк.

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

1

Python 2, 91 90 87 байт

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

Распечатывает список кортежей. Проверьте это на Ideone .


1

Желе , 27 25 байт (не конкурирует)

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

Попробуйте онлайн! или проверьте все контрольные примеры .


почему это не конкурирует
Балинт

Потому что задача с декабря 2015 года и предшествует созданию желе.
Деннис

О, спасибо за разъяснение!
Балинт

Это официальное правило? Я никогда не сравниваю дату вопроса с датой изобретения языка программирования.
Томас Веллер


1

Dyalog APL, 50 47 35 байт

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

Это отображает числа, которые каждый игрок сказал в виде таблицы, где первый столбец перечисляет игроков. Строки дополняются от 0 до одинаковой длины, а строки без номеров опускаются.

верификация

      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

Обратите внимание, что в последнем примере 7 и 8 опущены, так как эти игроки еще ничего не сказали.


1

Руби, 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}

Довольно простая реализация. Возвращает уродливую блестящую строку (вы можете добавить пробел, чтобы сделать это "#{k+=1} "для ... ну, разнесенной строки). Интересно, есть ли более математический алгоритм?


1

фактор 172

Мне удалось сделать это дольше, чем на Haskell, и так же читабельно, как APL! Я получу печенье?

[| 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 ]

Это цитата (анонимная функция), которая выводит круговую последовательность векторов. Каждый вектор начинается с номера игрока, а затем с номеров, соответствующих этому игроку.

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
    }
}

Я начал с этого:

: 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 ;

это не очень хороший факторный код, но гораздо более понятный (да, я использую числа в качестве имен переменных, не смотрите на меня так!).


"Я получаю печенье?" Да, вы делаете.
Утренняя монахиня

Вау, это было неожиданно! Ты, @LeakyNun: D
fede s.

Вау, я люблю это! Проклинаю вас за использование чисел в качестве идентификаторов!
кот

1
@ Cat мне действительно нравится это извращенным способом: P Но местные жители решают проблему длины SYMBOL:намного лучше: имена из одной буквы, и избавление от setи get!
Федерация с.

0

JavaScript (ES6) 100

Возвращение результата в виде строкового массива без разделителей

(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

Или более читабельно, на 3 байта больше, возвращая результат в виде массива массивов

(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

Тест Используя новую замечательную консольную особенность фрагментов стека

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))


0

J 63 60 59 58 56 байт

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

верификация

   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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.