Juego de Puzzle Set

13

Puede que conozcas el juego de Set (un juego maravilloso para niños, por cierto), un juego de cartas con 81 cartas, donde cada carta tiene una figura con 4 atributos diferentes (forma, número, color y relleno). Cada atributo tiene 3 valores diferentes:

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

Se ponen 12 cartas abiertas sobre la mesa y ahora el desafío es indicar conjuntos. Un conjunto consta de tres cartas donde cada valor de atributo ocurre 0, 1 o 3 veces. Tener 2 tarjetas con figuras rojas, u opacas, o 1 número no es bueno. Vea el enlace provisto para una explicación más visual.

Sí imagino un código para una tarjeta donde todos los atributos están codificados

"WP2N"

representa

2 Purple Waves with No fill

Junto con por ejemplo OR1NyDG3N

y ingrese la descripción de la imagen aquí

es un conjunto (3 formas diferentes, 3 colores diferentes, 3 números diferentes, 1 relleno).

La entrada es una cadena delimitada por espacios de códigos únicos (elegidos aleatoriamente entre 81 códigos posibles) que representan tarjetas.

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

La solución debe indicar todos los conjuntos posibles dentro de la colección dada. Entonces

OR1N, WP2N, DG3N

debe ser parte de la solución junto con todos los demás conjuntos.

Dr. Jerry
fuente
55
Suena prometedor, pero especifique con mayor precisión qué tipo de datos de entrada deben manejarse (stdin, archivo, parámetro) y cómo se verán los datos de entrada y salida. También proporcione una representación visual (captura de pantalla o similar) de una ejecución de muestra.
manatwork
1
He retractado mi voto cercano y he votado a favor; ¡es muy interesante! :)
Pomo de la puerta
44
¿A qué te refieres con "juego para niños"?
stand el
2
Waitaminute ... hay 4 letras 4 diferentes: N, D, S y O.
stand el
1
@boothby: hubiera dicho lo contrario. Si los alfabetos no se superponen, para cada conjunto de candidatos, puede contar cuántas veces aparece cada letra o número: el conjunto es válido si y solo si ningún número o letra aparece dos veces.
Flodel

Respuestas:

4

Ruby, 104 98 81 80 caracteres

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

Ejecución de muestra (utilizando sus datos de ejemplo):

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

Produce WP2N,DR1D,OG3Odos veces porque tiene dos DR1Ds en sus datos de muestra.

Explicación:

$*.combination(3).map{|c|- cada combinación de 3 cartas
puts c*?,if- genera el conjunto, si ...
(0..3).all?{|i|- si todos los números del 0 al 3 (las indecesiones de las propiedades en la cadena) se evalúan truecuando se pasan a este bloque
c.map{|x|x[i]}- toma el iíndice th de cada cadena
.uniq.size!=2}- si la cantidad de propiedades únicas (forma, color, etc.) no es 2 (entonces, 1 o 3)

Pomo de la puerta
fuente
Suponiendo que este desafío se convertirá en codegolf, ¿puedo proponer dos mejoras: a) deshacerse de endmás varios saltos de línea: transformar if ... puts ... enden puts ... if ...b) todos pueden tomar un bloqueo, por lo tanto x.map{}.all?es igual ax.all?{}
Howard
@How Gracias, haré esas mejoras cuando llegue a una computadora.
Pomo de la puerta
@Howard Editado para incluir ambos. ¡Gracias!
Pomo de la puerta
También quite el espacio después if.
Howard
Me gusta la solución de rubí, corta, concisa y más o menos legible
dr jerry
5

Mathematica 93 92 93 82 76 73

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

La lógica

StringSplit@#~Subsets~{3}produce una lista de subconjuntos de 3 cartas. Cada triple como:

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

o

matriz 1

luego se transpone,

matriz 2

y Tally/@(Characters@#^T)cuenta el número de elementos distintos en cada fila.

{3,1,1,3}

3 corresponde a "todos diferentes"; 1 corresponde a "todos iguales".

FreeQ[...,2]determina si 2 cartas del mismo tipo o en el triple. Si 2 no está entre los tantos, entonces las tres cartas son un "conjunto", de acuerdo con las reglas del Juego de conjunto.


Uso

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

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

DavidC
fuente
Puede ser más corto si se permiten duplicados. f=Select[StringSplit@#~Subsets~{3},FreeQ[Tally/@Thread@Characters@#,2]&]&La salida será{{"OR1N", "WP2N", "DG3N"}, {"WP2N","DR1D", "OG3O"}, {"WP2N", "DR1D", "OG3O"}, {"DG3N", "WG3S", "OG3O"}}
alephalpha
¡Una forma muy inteligente de verificar "todos iguales" o "todos diferentes"!
DavidC
4

Mathematica 73

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

Uso

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
fuente
4

Brachylog , 12 bytes

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

Pruébalo en línea!

Toma la entrada a través de la variable de entrada y genera la salida a través de la variable de salida.

Segundo caso de prueba tomado de un duplicado recientemente cerrado en su codificación, ya que a esta solución realmente no le importa lo que realmente signifique algo.

                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.
Cadena no relacionada
fuente
3

GolfScript, 53 caracteres

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

La entrada se debe proporcionar en STDIN, ejemplo en línea :

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

Código comentado:

" "/: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
Howard
fuente
2
Yo diría que es un claro ganador para un código de golf. Hower totalmente ilegible ..
dr jerry
1
@drjerry En comparación con otros códigos de golfscript, es bastante legible. Por ejemplo, contiene solo bucles simples y ningún truco avanzado. Agregaré una explicación del código más tarde.
Howard
0\zip{.&,2=|}/!se puede acortar azip{.&,}%2&!
Peter Taylor
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]}}}}}}

es una función que toma una matriz de objetos y devuelve una matriz de objetos.

Violín DEMO (con ordenado).

Enfriador de matemáticas
fuente
No tiene que declarar variables ...
Pomo de la puerta
@ Pomo de la puerta, lo retiro, tienes razón. editado ¡Gracias!
Math chiller
1

APL (IBM), 76

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

No tengo IBM APL, pero creo que esto funcionará.

Ejecución de muestra (Emulación de IBM APL en 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
fuente
Primera vez que veo el código apl gracias!
Dr. Jerry
1

Sabio, 71

Si Ces una cadena, por ejemplo "OR1N WP2N DG3N DR1D WG3S WG1N WR2D WP3N DR2O DR1D OG3O OR2D", ejecutar

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

Llegar [{'DR1D', 'OG3O', 'WP2N'}, {'DR2D', 'WR2D', 'OR2D'}, {'WG3S', 'OG3O', 'DG3N'}, {'DG3N', 'WP2N', 'OR1N'}]

Y aquí hay un enfoque muy diferente usando la interpretación de que un Set es una línea proyectiva en GF(3)^4:

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

Estaba un poco molesto porque Dlo usé dos veces ... hasta que descubrí cómo abusar de eso. Pero aún mejor, también abuso del findmétodo. str.finddevuelve -1 si no se encuentra una letra. Desde entonces -1 = 2 mod 3, la carta Sse maneja adecuadamente porque no aparece en 'WODRPG123N'.

boothby
fuente