Игра Сет Пазл

13

Может быть, вы знаете, что игра Set (замечательная игра для детей) - карточная игра с 81 карточкой, где на каждой карточке изображена фигура с 4 различными атрибутами (форма, число, цвет и заполнение). Каждый атрибут имеет 3 разных значения:

form: wave, oval, diamond
colour: red, purple, and green
number: 1, 2, 3
fill: none, dashed, opaque.

На столе лежат 12 карт, и теперь задача состоит в том, чтобы указать наборы. Набор состоит из трех карт, где каждое значение атрибута встречается 0, 1 или 3 раза. 2 карты с красными цифрами, или непрозрачные, или 1 номер не годятся. Смотрите предоставленную ссылку для более наглядного объяснения.

Я предполагаю код для карты, где все атрибуты закодированы так

"WP2N"

обозначает

2 Purple Waves with No fill

Вместе с, например, OR1NиDG3N

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

это набор (3 разных формы, 3 разных цвета, 3 разных номера, 1 заливка).

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

"OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR2D OG3O OR2D"

Решение должно указывать все возможные наборы в данной коллекции. Так

OR1N, WP2N, DG3N

должен быть частью решения вместе со всеми другими наборами.

доктор Джерри
источник
5
Звучит многообещающе, но, пожалуйста, уточните, какой тип входных данных нужно обрабатывать (стандартный, файл, параметр) и как будут выглядеть входные и выходные данные. Также предоставьте визуальное представление (снимок экрана или аналогичный) образца прогона.
manatwork
1
Я отказался от своего близкого голоса и проголосовал за это; это очень интересно! :)
Ручка двери
4
Какого черта ты имеешь в виду под игрой для детей?
Boothby
2
Waitaminute ... есть 4 разных 4-х буквы: N, D, S и O.
boothby
1
@boothby: я бы сказал обратное. Если алфавиты не перекрываются, для каждого набора кандидатов вы можете просто посчитать, сколько раз каждая буква или цифра отображаются: набор действителен тогда и только тогда, когда цифра или буква не появляются дважды.
Flodel

Ответы:

4

Рубин, 104 98 81 80 символов

$*.combination(3).map{|c|puts c*?,if(0..3).all?{|i|c.map{|x|x[i]}.uniq.size!=2}}

Пробный прогон (используя данные вашего примера):

c:\a\ruby>set.rb OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D
OR1N,WP2N,DG3N
WP2N,DR1D,OG3O
WP2N,DR1D,OG3O
DG3N,WG3S,OG3O

Он выводит WP2N,DR1D,OG3Oдважды, потому что у вас есть два DR1Ds в ваших данных выборки.

Объяснение:

$*.combination(3).map{|c|- каждая комбинация из 3 карт
puts c*?,if- вывести набор, если ...
(0..3).all?{|i|- если все числа от 0 до 3 (значения свойств в строке) вычисляются trueпри передаче в этот блок
c.map{|x|x[i]}- взять iиндекс th каждой строки
.uniq.size!=2}- если количество уникальных свойств (форма, цвет и т. д.) не равно 2 (т. е. 1 или 3)

Дверная ручка
источник
Предполагая, что этот вызов станет Codegolf, могу я предложить два улучшения: а) избавиться от endплюс несколько разрывов строк: преобразовать if ... puts ... endв puts ... if ...б) все могут занять блок, таким образом x.map{}.all?, равенx.all?{}
Говард
@ Как спасибо, я сделаю эти улучшения, когда доберусь до компьютера.
Ручка двери
@Howard Отредактировано, чтобы включить оба. Благодарность!
Ручка двери
Также удалите пробел после if.
Говард
Мне нравится рубиновое решение, короткое, сжатое и более или менее читаемое
доктор Джерри
5

Mathematica 93 92 93 82 76 73

f={}⋃Select[StringSplit@#~Subsets~{3}, FreeQ[Tally/@(Characters@#^T),2]&]&

Логика

StringSplit@#~Subsets~{3}создает список из 3-х карточных подмножеств. Каждая тройка, такая как:

{{"D", "G", "3", "N"}, {"W", "G", "3", "S"}, {"O", "G", "3", "О"}}

или

массив 1

затем транспонируется,

массив 2

и Tally/@(Characters@#^T)подсчитывает количество различных элементов в каждом ряду.

{3,1,1,3}

3 соответствует «все разные»; 1 соответствует «все то же самое».

FreeQ[...,2]определяет, будут ли 2 карты одного типа или тройные. Если 2 не входит в число, то три карты являются «сетом», согласно правилам игры набора.


использование

f["OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"]

{{"DG3N", "WG3S", "OG3O"}, {"OR1N", "WP2N", "DG3N"}, {"WP2N", "DR1D", "OG3O"}}

DavidC
источник
Это может быть короче, если допускаются дубликаты. f=Select[StringSplit@#~Subsets~{3},FreeQ[Tally/@Thread@Characters@#,2]&]&Выходной будет{{"OR1N", "WP2N", "DG3N"}, {"WP2N","DR1D", "OG3O"}, {"WP2N", "DR1D", "OG3O"}, {"DG3N", "WG3S", "OG3O"}}
алефальфа
Очень умный способ проверить «все одинаково» или «все разные»!
DavidC
4

Mathematica 73

f = Select[StringSplit@#~Subsets~{3}, FreeQ[Tally /@ Thread@Characters@#, 2] &] &

использование

f["OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D"]

{{"OR1N", "WP2N", "DG3N"}, {"WP2N", "DR1D", "OG3O"}, {"WP2N", "DR1D", "OG3O"}, {"DG3N", "WG3S "," OG3O "}}

alephalpha
источник
4

Брахилог , 12 байт

ṇ₁⊇Ṫz{=|≠}ᵐz

Попробуйте онлайн!

Принимает ввод через входную переменную и генерирует вывод через выходную переменную.

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

                The output variable is
  ⊇             a subsequence
   Ṫ            of length 3
ṇ₁              of the input split on spaces,
    z      z    the columns of which
     {   }ᵐ     are all
       |        either
      =         the same element repeated,
        ≠       or entirely free of duplicates.
Несвязанная строка
источник
3

GolfScript, 53 символа

" "/:w,,{:a,{:^,{a^]{w=}%.0\zip{.&,2=|}/!{.p}*;}/}/}/

Вход должен быть предоставлен в STDIN, например, онлайн :

> OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR2D OG3O OR2D
["OR1N" "DG3N" "WP2N"]
["WP2N" "OG3O" "DR1D"]
["DG3N" "OG3O" "WG3S"]
["WR2D" "OR2D" "DR2D"]

Код комментария:

" "/:w          # split the input at spaces and assign it to variable w
,,              # create the array [0..n-1] (n being the length of w)
{:a,{:^,{       # three nested loops: a=0..n-1, ^=0..a-1, _=0..b-1 
                # (third loop has no variable assigned but just pushes on stack)
    a^]         # make an array [a,^,_] of the three loop variables
    {w=}%       # take the corresponding list items, i.e. [w[a],w[^],w[_]]
    .0\         # push zero, add duplicate of the the array
    zip         # zip transposes the array, thus [OR1N WP2N DG3N] -> [OWD RPG 123 NNN]
    {           # loop over those entries
      .&        # unique
      ,2=       # length equals 2?
      |         # "or" with top of stack (two zero pushed before)
    }/          # end of loop, on stack remains the results of the "or"s
    !{.p}*      # if no length of 2 is there, make a copy of the set and print it
    ;           # discard stack item
}/}/}/          # closing the three nested loops
Говард
источник
2
Я бы сказал, явный победитель для кода-гольфа. Hower совершенно нечитабельно ..
доктор Джерри
1
@drjerry По сравнению с другим кодом для гольфа это вполне читабельно. Например, он содержит только простые циклы и не содержит продвинутых трюков. Я добавлю объяснение кода позже.
Говард
0\zip{.&,2=|}/!можно сократить доzip{.&,}%2&!
Питер Тейлор
1

JavaScript 323 313

function a(b){d=h=[];c=e=f=0;for(i in b){for(j in b){for(k in b[i]){if(b[i][k]==b[j][k]){if(c+f<4)c++;else if(c==4){h+=b[j];if(h.length=3)return h}}else{for(l in d){for(m in d[l]){g=f;if(d[l][2]==i){if(d[l][3]==k)if(b[j][k]!=d[l][0]&&b[j][k]!=d[l][1])f++;}else{continue}}if(g==f)d[e++]=[b[i][k],b[j][k],j,k]}}}}}}

это функция, которая принимает массив объектов и возвращает массив объектов.

ДЕМО скрипка (с приборкой).

Математический чиллер
источник
Вам не нужно объявлять переменные ...
Doorknob
@ Doorknob Я забираю это, ты прав. изм. Благодарность!
Математический чиллер
1

APL (IBM), 76

⍉¨x/⍨{{⍵≡1⌽⍵}⍵=1⌽⍵}¨x←⊃¨(∘.,/3⍴⊂⍪¨(' '≠y)⊂y←⍞)⌷⍨¨z/⍨∧/¨2</¨z←,⍳3⍴12

У меня нет IBM APL, но я верю, что это сработает.

Пробный прогон (эмуляция IBM APL в Dyalog APL)

OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D
 OR1N  WP2N  WP2N  DG3N 
 WP2N  DR1D  DR1D  WG3S 
 DG3N  OG3O  OG3O  OG3O 
TwiNight
источник
В первый раз я вижу код apl спасибо!
Др Джерри
1

Мудрец, 71

Если Cэто строка, скажем "OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D", выполнить

[c for c in Subsets(C.split(),3)if{1,3}>={len(set(x))for x in zip(*c)}]

получить [{'DR1D', 'OG3O', 'WP2N'}, {'DR2D', 'WR2D', 'OR2D'}, {'WG3S', 'OG3O', 'DG3N'}, {'DG3N', 'WP2N', 'OR1N'}]

И вот совсем другой подход, использующий интерпретацию, в которой множество является проективной линией GF(3)^4:

[c for c in Subsets(C.split(),3)if sum(matrix(3,map('WODRPG123N'.find,''.join(c))))%3==0]

Я был немного раздражен тем, что Dего использовали дважды ... пока я не понял, как злоупотреблять этим. Но даже лучше, я тоже злоупотребляю этим findметодом. str.findвозвращает -1, если письмо не найдено. Поскольку -1 = 2 mod 3письмо Sобрабатывается надлежащим образом, потому что оно не встречается в 'WODRPG123N'.

Бутби
источник