Professor do MIT precisa de um AP!


14

O truque de mágica de 5 cartas envolve um mágico cujo assistente lhes dá 4 cartas mostradas e uma oculta, nesta ordem, e o mago deve adivinhar a que está oculta.

AVISO: Solução abaixo! Saia agora ou seja mimado com isso.


A solução

O truque aqui é que as cinco cartas são dadas em uma ordem específica !

c1,...,c5 são os 5 cartões na ordem especificada.

xn é o número do cartão decn em(ordem numérica).NO=[A, 2,3,4,5,6,7,8,9, T, J, Q, K]

uma+b , onde uma é um número do cartão e b é um número inteiro, é igual ao número do cartão b passos à direita de uma em NO , quebrando para o início, se necessário.

sn é o naipe decn emSO=[,,,] (ordem do naipe).

umab , ondeuma é um número do cartão eb é um terno, denota o cartão com o número do cartão deuma e ternob .

uma<b , ondea eb são os cartões, é verdadeiro seuma 's terno é para a esquerda deb ' s terno emSO , ou seus ternos são iguais euma 's número do cartão está à esquerda deb ' s número de cartão emNO .

uma>b , ondeuma eb são os cartões, é verdade seuma<b é falsa.

PEu(uma,b,c) , ondeuma ,b ec são os cartões, é o índice de permutação de esta distribuição deles, especificada pela tabela abaixo:
ComparaçãoPEu(uma,b,c)uma<b<c1uma<b>c>uma2uma>b<c>uma3uma<b>c<uma4uma>b<c<uma5uma>b>c6

A solução para o truque de mágica de 5 cartas é o problema é:

c5=(x1+PEu(c2,c3,c4))s1

O desafio

Por enquanto, tudo bem. No entanto, o cálculo especificado acima já é solicitado aqui . Em vez disso, seu desafio é, dadas as 5 cartas em nenhuma ordem específica, solicitá-las corretamente. Isso significa que os quatro primeiros cartões na saída representarão o quinto. Em outras palavras, seja o assistente. Requisitos:

  • s5=s1 .
  • x5=x1+PEu(c2,c3,c4) (isto é, este tem de ser possível).

Exemplo

Vamos considerar o conjunto 7H,2D,6D,5C,6C. Primeiro de tudo, pegamos os 25 pares:

7H,7H 7H,2D 7H,6D 7H,5C 7H,6C
2D,7H 2D,2D 2D,6D 2D,5C 2D,6C
6D,7H 6D,2D 6D,6D 6D,5C 6D,6C
5C,7H 5C,2D 5C,6D 5C,5C 5C,6C
6C,7H 6C,2D 6C,6D 6C,5C 6C,6C

Então, obviamente removemos os 5 pares que contêm a mesma carta duas vezes, eles não existem em um único baralho:

      7H,2D 7H,6D 7H,5C 7H,6C
2D,7H       2D,6D 2D,5C 2D,6C
6D,7H 6D,2D       6D,5C 6D,6C
5C,7H 5C,2D 5C,6D       5C,6C
6C,7H 6C,2D 6C,6D 6C,5C      

Posteriormente, uma vez que os naipes devem ser os mesmos, diferentes naipes em um par são proibidos:

                             
            2D, 6D            
      6D, 2D                  
                        5C, 6C
                  6C, 5C      

Finalmente, verificamos se é possível passar da primeira carta para a segunda adicionando no máximo 6 e removendo metade dos pares restantes:

                             
            2D, 6D            

                        5C, 6C
                             

Agora temos os pares válidos: 2D,6De 5C,6C. A primeira carta de cada par é a carta 1, enquanto a última é a carta 5.

Nós vamos 5C,6Caqui com facilidade. O conjunto inteiro está 7H,2D,6D,5C,6Cremovendo as duas cartas do par que escolhemos 7H,2D,6D. Esses cartões representarão 6 - 5 = 1, portanto, temos que solicitá-los como "min, médio, max". 7H > 2D < 6D < 7H, ou simplesmente 2D < 6D < 7H, agora temos2D,6D,7H .

O último passo é juntar tudo isso, então nosso resultado será 5C,2D,6D,7H,6C.

Esclarecimentos

  • Você pode usar em 10vez de T.
  • Você pode usar um de ♠♥♦♣, ♤♡♢♧ou em ♠♡♢♣vez de CDHS, respectivamente.
  • Este é o , o código mais curto vence.

Casos de teste

Você pode gerar uma ou mais das soluções válidas incluídas para cada caso de teste.

8S,TD,5C,QS,TS -> 8S,5C,QS,TD,TS
              ... 8S,TD,TS,5C,QS
              ... TS,5C,8S,TD,QS

JD,KH,4S,9D,8S -> 9D,KH,8S,4S,JD
              ... 4S,JD,KH,9D,8S

4H,4D,TH,KH,2C -> 4H,KH,4D,2C,TH
              ... TH,4D,2C,4H,KH
              ... KH,4D,TH,2C,4H

3S,KS,8S,KH,9H -> 9H,8S,KS,3S,KH
              ... 3S,KS,9H,KH,8S
              ... 8S,3S,9H,KH,KS
              ... KS,KH,9H,8S,3S

KH,TS,3C,7H,JD -> 7H,TS,JD,3C,KH

4C,KC,TD,JD,QS -> KC,JD,QS,TD,4C
              ... TD,4C,KC,QS,JD

AC,5H,8D,6D,8S -> 6D,AC,8S,5H,8D

AS,TC,3S,2H,9C -> 9C,2H,AS,3S,TC
              ... AS,9C,2H,TC,3S

4C,JS,AS,8H,JC -> JC,JS,AS,8H,4C
              ... JS,JC,4C,8H,AS

4H,QS,TH,QC,AC -> QC,4H,QS,TH,AC
              ... 4H,QS,QC,AC,TH

Pode ser mais fácil visualizar as permutações adicionando uma coluna Exemplo .
Arnauld


Quão branda é a entrada? As tuplas do número do cartão e da casa, em vez das cadeias de comprimento 2, são aceitáveis?
Οurous 07/11

@ Οurous Isso não está especificado no desafio; desde que seja razoável (no seu caso, isso pareça razoável o suficiente), é permitido.
Erik the Outgolfer

Respostas:


3

Node.js. , 190 186 180 bytes

f=(a,p,g=c=>"A23456789TJQK".search(c[0])+10,[A,B,C,D,E]=a.sort(_=>p>>i++&1,i=0))=>A[k=1]!=E[1]|[B,C,D].sort((a,b)=>k=k*2|a[1]+g(a)>b[1]+g(b))|(k^4)%6+1-(g(E)-g(A)+13)%13?f(a,-~p):a

Experimente online!

Quão?

Identificando e comparando os números dos cartões

A função auxiliar g retorna um índice que representa o número de um determinado cartão.

g = c => "A23456789TJQK".search(c[0]) + 10

Adicionamos 10 para forçar dois dígitos para todas as entradas, para que esses índices possam ser classificados com segurança em ordem lexicográfica. Portanto, um ás é 10 e um rei é 22 .

Dado 2 cartões uma e b no "NS"formato, podemos compará-los por naipe primeiro e segundo número com:

a[1] + g(a) > b[1] + g(b)

Gerando as permutações da entrada

120umapUMABCDE

[A, B, C, D, E] = a.sort(_ => p >> i++ & 1, i = 0)

699

Testando os fatos

O primeiro teste óbvio é garantir que a primeira e a última cartas sejam do mesmo naipe. Rejeitamos a permutação se não forem iguais.

A[k = 1] != E[1] // we also initialize k, which is used right after that

Testando a distância

Calculamos a distância entre o primeiro número do cartão e o último número do cartão com:

(g(E) - g(A) + 13) % 13

BCD

Este teste depende da maneira como o sort()algoritmo do Node.js está funcionando.

sort()[UMA,B,C]

  1. UMAB
  2. UMAC
  3. BC

Vamos considerar o seguinte código:

[1, 2, 3].sort((a, b) => k = k * 2 | (a > b), k = 1)

UMA<B1<2UMA<C1<3B<C2<3k23k=8

Agora, se fizermos:

[3, 2, 1].sort((a, b) => k = k * 2 | (a > b), k = 1)

k=15

Cada permutação gera uma máscara de bits única, que é mapeada para uma distância única:

 A, B, C | A>B | A>C | B>C | k  | distance
---------+-----+-----+-----+----+----------
 1, 2, 3 |  0  |  0  |  0  |  8 |    1
 1, 3, 2 |  0  |  0  |  1  |  9 |    2
 2, 1, 3 |  1  |  0  |  0  | 12 |    3
 2, 3, 1 |  0  |  1  |  1  | 11 |    4
 3, 1, 2 |  1  |  1  |  0  | 14 |    5
 3, 2, 1 |  1  |  1  |  1  | 15 |    6

k

d=((kxor4)mod6)+1

  k | xor 4 | mod 6 | +1
----+-------+-------+----
  8 |   12  |   0   |  1
  9 |   13  |   1   |  2
 12 |    8  |   2   |  3
 11 |   15  |   3   |  4
 14 |   10  |   4   |  5
 15 |   11  |   5   |  6

Juntando tudo, temos o seguinte teste:

[B, C, D]
.sort((a, b) =>
  k = k * 2 | a[1] + g(a) > b[1] + g(b)
)
| (k ^ 4) % 6 + 1
- (g(E) - g(A) + 13) % 13

1

Python 3 , 260 248 232 bytes

N="A23456789TJQK".find
D=lambda x,y="KC":(N(y[0])+~N(x[0]))%13+15*abs(ord(x[1])-ord(y[1]))
def f(l):a,e,b,c,d=[[x,y]+sorted({*l}-{x,y},key=D)for x in l for y in l if D(x,y)<6][0];print(a,*map(eval,"bbccddcdbdbcdcdbcb"[D(a,e)::6]),e)

Experimente online!

-12 bytes graças a Eric, o Outgolfer
-14 bytes, removendo a compreensão da lista


0

Limpar \ limpo , 225 220 209 bytes

import StdEnv,Data.List
n=['A23456789TJQK':n]

filter(\[[x,s],b,c,d,e]#[p,q,r:_]=map snd(sort(zip2[(elemIndices a n,b)\\[a,b]<-[b,c,d]][1..]))
=[snd(span((<>)x)n)!!(p+if(p>q)0if(q<r)(q+r)q),s]==e)o permutations

Experimente online!

Como uma função composta,, :: [[Char]] -> [[Char]]com alguns ajudantes.

Expandido:

n = ['A23456789TJQK': n] // infinitely repeating card number list

filter (...) o permutations // filter the permutations of the argument by ...
  \[[x, s], b, c, d, e] // deconstruct each permutation via pattern matching
    #[p, q, r: _] = ... // define p, q, r as ...
      map snd (...) // the second component of every element in ...
      sort (...) // the sorted list of ...
      zip2 ... [1..] // pairs of ... and the numbers 1, 2, 3, ..
      [... \\ [a, b] <- [b, c, d]] // ... for every pair of number a and house b in [b, c, d]
      (elemIndices a n, b) // pair of the value of that card number and the house
    = ... == e // check ... for equality against the last card
      [..., s] // ..., paired with house s
      snd (span ((<>) x) n) !! (...) // the card number ... places from x
      p + ... // this is kinda obvious
      if(p > q) 0 ... // if p is greater than q, zero, else ...
      if(q < r) (q + r) q // if q is less than r, q + r, else q

0

Rubi , 175 bytes

->a{g=->j{j.tr('ATJQKCHS','1:;<=)_z').sum}
e=b=a.sort_by{|i|g[i]}
4.times{|i|(d=g[b[i+1]]-g[b[i]])<13&&(a=b[i,2];e=d)}
[a[e/7],*(b-a).permutation.to_a[e<7?e-1:12-e],a[e/7-1]]}

Experimente online!

Uma função lambda tomando uma matriz de cartões como seqüências de caracteres

Comentado

->a{g=->j{j.tr('ATJQKCHS','1:;<=)_z').sum}
#helper function converts card to integer, ATJQK to 1:;<= and CHS to )_z then sum ascii values 

e=b=a.sort_by{|i|g[i]}  
#sort according to g. we declare 2 variables here in order to avoid undefined variable error at pre-interpretation check stage.

4.times{|i|(d=g[b[i+1]]-g[b[i]])<13&&(a=b[i,2];e=d)}
#compare each pair of values. if in same suit, store the pair of cards to a
#and the value difference to e. Loop exits with the last suitable pair stored

[a[e/7],*(b-a).permutation.to_a[e<7?e-1:12-e],a[e/7-1]]}
#return array containing the two cards of the same suit in the correct order
#with the correct permutation of the remaining cards (b-a) in the middle

0

Geléia , 41 bytes

ØD;“TJQK”¤io2)1¦€µUḊỤ3R¤œ¿+""Om4%13E
Œ!ÇƇ

Um link monádico que aceita uma lista de listas de caracteres retornando uma lista de todos os arranjos válidos no mesmo formato.

Experimente online! (o rodapé formata o resultado como uma grade para evitar a impressão de esmagamento implícita conforme executada pelo código do Link quando executado como um programa completo)

Ou veja uma suíte de testes .

Tenho uma suspeita furtiva de que outra abordagem será muito mais concisa. Vou ter que revisitar esse desafio mais tarde!

... hmm, eu tive outro puxão e consegui outro 41 byter ( teste ):

O¹*@<74$?€€29%⁽:0%⁴UµṪ_Ḣ%13Ḍ⁼Ụ3R¤œ¿Ɗ
Œ!ÇƇ
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.