É um jogo válido de Five Up (Dominó)?

8

Um conjunto de dominós consiste em blocos com dois números, de modo que todas as combinações de números inteiros de 0 a N sejam representadas. Os exemplos abaixo se referem a N = 6 por conveniência, mas N = 9 e N = 12 também são comuns. A orientação das telhas não importa (eles são normalmente impressas com pontos em vez de dígitos), então [1-6]e [6-1]se referem à mesma telha, de que há apenas uma em um conjunto.

A maioria dos jogos disputados com dominó envolve jogadores que se revezam adicionando dominó a uma linha daqueles já jogados na mesa, de modo que um dos números no novo dominó seja colocado adjacente ao mesmo número em uma extremidade da linha na mesa. Assim, você pode adicionar um [2-5]a qualquer extremidade de uma linha existente de [2-3][3-3][3-5], produzindo [5-2][2-3][3-3][3-5]ou [2-3][3-3][3-5][5-2].

Muitos desses jogos exigem "duplos", dominós com dois do mesmo número, para serem colocados perpendicularmente aos outros dominós conectados a eles. Além da pontuação com a qual não estamos preocupados aqui, isso não tem efeito, exceto quando ...

Muitos desses jogos permitem que a "linha" bifurque-se em algumas ou todas as duplas. Five Up é um jogo em que a linha pode se dividir em três novas linhas em cada dupla, para que todos os quatro lados de uma dupla possam ter um dominó correspondente.

Aqui está um exemplo de layout de dominó de um jogo "double 6" em um jogo de Five Up (onde A | B ou AB é um único dominó):

     4
     -
     0

3|0 0|0 0|2

     0
     -
     1

4|1 1|1 1|6
                3
     1          -
     -          6
     5
                6
6|5 5|5 5|0 0|6 - 6|2 2|1
                6
     5
     -          6
     4          -
                4

Sua tarefa é pegar uma lista de dominós na ordem em que foram adicionados à tabela e determinar se essa ordem representa ou não um jogo legal do Five Up.

Você pode escrever um programa inteiro que recebe a entrada do stdin ou uma função que recebe a entrada como um ou mais parâmetros.

A entrada canônica seria uma lista ou matriz de duas tuplas de números inteiros. Uma lista de listas, matriz de matrizes, vetor de tuplas etc. são todas formas válidas para receber entradas, como seria uma string que representa qualquer uma das anteriores ou várias strings. A entrada conterá apenas pares de números inteiros não negativos, dominós válidos.

A saída deve ser um valor verdadeiro ou falso, para jogos válidos e inválidos, respectivamente.

Seu código deve aceitar números de dominó arbitrariamente grandes, dentro dos recursos dos valores máximos inteiros do seu idioma.

Exemplos:

  • 0-6 é válido, assim como qualquer outro dominó
  • 0-6 6-0não é válido, existe apenas um 0-6dominó em um conjunto
  • 6-6 6-5 5-3 3-0 é válido, um arranjo linear simples
  • 6-6 6-5 3-0 5-3não é válido, não há 3ou 0em jogo para o terceiro dominó se conectar antes de 5-3ser jogado
  • 1-1 1-2 1-3 1-4 1-5 1-6não é válido, todas as quatro 1extremidades abertas são usadas, deixando nenhum lugar para conectar o1-6
  • 1-1 1-2 1-3 1-4 1-5 3-6 1-6 é válido, o 3-6 se conecta ao 1-3, e o 1-6 pode se conectar ao 3-6
  • 5-5 5-4 5-0 0-6 6-6 6-4 6-2 2-1 6-3 5-1 1-1 1-6 4-1 1-0 0-0 2-0 3-0 0-4 é válido, o exemplo ilustrado acima
  • 12-12 12-1 3-12 3-1 1-2 3-3 é válido, usa dominós maiores e tem um posicionamento ambíguo

OBSERVAÇÃO: A função necessária aqui não é uma verificação perfeita para jogos Five Up válidos. Estamos ignorando aqui as regras sobre qual dominó é jogado primeiro, o que exigiria mais informações sobre a variante do jogo e o número de jogadores e desqualificaria uma minoria significativa de insumos.

Sparr
fonte
Precisamos levar em conta as restrições geométricas no posicionamento, ou seja, a corrente de dominó colidindo contra si mesma?
Xnor
@ xnor você não. Esqueci de mencionar a convenção comum de que a "linha" pode se curvar arbitrariamente por conveniência em qualquer jogo de dominó. também boa para evitar arestas tabela :)
Sparr
Eu acho que pode ser possível produzir uma ordem patológica de jogo com um conjunto duplo de 12 dominós que não podem evitar a auto-interseção. Definitivamente, é possível com conjuntos maiores. Vamos apenas ignorar esses casos. Na pior das hipóteses, eles podem ser resolvidos dobrando a linha em 3D :)
Sparr
Na verdade, precisamos ser capazes de lidar com dominós com valores> 6? Nesse caso, você poderia deixar isso mais claro nas especificações e talvez adicionar um caso de teste. Caso contrário, porém, um bom desafio - +1 de mim.
Salsicha
@Shaggy adicionou um caso de teste para um dominó maior
Sparr

Respostas:

1

Haskell , 188 174 168 bytes

f(p:r)=[p]!r$p?p
(s!(p:r))o|b<-[p,reverse p]=or[(q:s)!r$q%o|q<-b,elem(q!!0)o,all(`notElem`s)b]
(s!_)o=1<3
p@[x,y]?r=[c|x==y,c<-p]++r
p@[x,y]%(a:r)|a/=x=a:p%r|z<-y:r=p?z

Experimente online! Exemplo de uso: f [[6,6],[6,5],[5,3],[3,0]]rendimentos True.

Ungolfed:

f :: [[Int]] -> Bool
f (p:r) = check [p] (double p p) r

check :: [[Int]] -> [Int] -> [[Int]] -> Bool
check seen open [] = True
check seen open ([x,y]:r) = 
	  notElem [x,y] seen
   && notElem [y,x] seen
   && (elem x open && check ([x,y]:seen) (update [x,y] open) r 
   ||  elem y open && check ([y,x]:seen) (update [y,x] open) r)

double :: [Int] -> [Int] -> [Int]
double [x,y] rest = 
    if x==y 
    then [x,y] ++ rest 
    else rest

update :: [Int] -> [Int] -> [Int]
update [x,y] (a:rest) = 
    if x==a 
    then double [x,y] (y:rest) 
    else a : update [x,y] rest

Experimente online!

Laikoni
fonte
0

R , 224 bytes

function(L,x=c(),y=c()){o=T
z=length
if(z(L)){p=sort(L[1:2])
w=rep(p,2-(p[2]>p[1]))
x=rbind(p,x)
if(z(y)){m=match(p,y,0)
v=which.max(m)
if(m[v]>0){y=y[-m[v]]
w=w[-v]}}
y=c(y,w)
L=L[-1:-2]
o=o&f(L,x,y)&!sum(duplicated(x))}
o}

Experimente online!

O código recebe as peças como uma lista ordenada e retorna VERDADEIRO ou FALSO de acordo com as especificações. A função varre recursivamente cada peça, adiciona a peça a um índice para verificar a ausência de duplicatas e acompanha os pontos de inserção disponíveis para verificar se a peça pode ser efetivamente adicionada à pilha. O manuseio das conexões das peças (por exemplo, conectar um 1-2 pelo 1 ou pelo 2) é feito de maneira gananciosa, portanto não é totalmente impossível que algumas configurações estranhas possam explodir.

NofP
fonte
infelizmente, a ganância não é boa o suficiente. considere que 6-6 6-3 6-2 2-3você precisa ser capaz de lidar com isso com 2-_ou com o 3-_próximo, porque ele 2-3poderia ter sido colocado em cada extremidade.
Sparr
Vou dar uma olhada.
NofP