Гра набір головоломки


13

Можливо, ви знаєте гру Set (чудова гра для дітей btw) карткова гра з 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
Звучить багатообіцяюче, але, будь ласка, уточніть більш точно, з яким типом вхідних даних потрібно обробляти (stdin, файл, параметр) та як будуть виглядати вхідні та вихідні дані. Надайте також візуальне зображення (скріншот або подібне) зразка запуску.
манатура

1
Я відмовився від свого близького голосування і підтримав це; це дуже цікаво! :)
Doorknob

4
Чорт ви маєте на увазі під "грою для дітей"?
кабінка

2
Waitaminute ... є 4 різні 4-й літери: N, D, S та O.
вінд

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двічі, оскільки DR1Dу ваших вибіркових даних є два s.

Пояснення:

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


Якщо припустити, що цей виклик стане кодогольфом, я можу запропонувати два вдосконалення: а) позбутися endплюс декілька розривів рядків: перетворити if ... puts ... endна puts ... if ...б) всі можуть взяти блок, таким чином x.map{}.all?, дорівнюєx.all?{}
Говард

@Як спасибі, я вдосконалю, коли доберуся до комп’ютера.
Дверна ручка

@Howard Edited, щоб включити обидва. Дякую!
Дверна ручка

Також видаліть пробіл після if.
Говард

Мені подобається рубінове рішення, коротке, лаконічне і більш-менш читабельне
dr jerry

5

Математика 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", "O"}}

або

масив 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"}}


Він може бути коротшим, якщо дозволено копії. f=Select[StringSplit@#~Subsets~{3},FreeQ[Tally/@Thread@Characters@#,2]&]&Вихід буде{{"OR1N", "WP2N", "DG3N"}, {"WP2N","DR1D", "OG3O"}, {"WP2N", "DR1D", "OG3O"}, {"DG3N", "WG3S", "OG3O"}}
алефальфа

Дуже розумний спосіб перевірити "все те саме" або "все різне"!
DavidC

4

Математика 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 "}}


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
Я б сказав очевидний переможець коду-гольфу. Хоувер абсолютно нечитабельний ..
dr jerry

1
@drjerry У порівнянні з іншими кодами golfscript він досить читабельний. Наприклад, він містить лише прості петлі та відсутність додаткових хитрощів. Пояснення коду я додам пізніше.
Говард

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

це функція, яка приймає масив об'єктів і повертає масив об'єктів.

Джерело DEMO (з прибиранням).


Вам не потрібно оголошувати змінні ...
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 

Перший раз, коли я бачу апл-коду дякую!
dr jerry

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'.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.