Anota una mano de corazones

22

Hearts es un juego de cartas con trucos para 4 jugadores. Cada truco lo realiza el jugador que jugó la carta más alta del palo principal. Al final de cada mano, los jugadores incurren en un puntaje de penalización dependiendo de las cartas de penalización que hayan tomado; la tarea es determinar los puntajes bajo las reglas de Microsoft Hearts .

Entrada

La entrada es 4 listas (o cadena delimitada, matriz, etc.) que muestran las tarjetas de penalización tomadas por cada uno de los 4 jugadores. Las tarjetas de penalización son

2♥, 3♥, 4♥, 5♥, 6♥, 7♥, 8♥, 9♥, 10♥, J♥, Q♥, K♥, A♥, Q♠

que representaremos como

2,  3,  4,   5,  6,  7,  8,  9,  10,  11, 12,  13,  1,  0

respectivamente.

Salida

La salida son los 4 puntos de penalización incurridos por los 4 jugadores (lista, cadena, matriz, etc.). La puntuación es la siguiente:

  • Cada corazón ( representado por enteros 1a 13inclusivos) incurre en 1 punto
  • La reina de espadas ( Q♠representada por 0) incurre en 13 puntos
  • Excepción: si un jugador ha tomado todas las cartas de penalización (llamadas tiro a la luna), incurre en 0 puntos, mientras que todos los demás jugadores incurren en 26 puntos.

Casos de prueba

[2, 8, 7, 1], [3, 4], [], [9, 5, 6, 0, 10, 11, 12, 13]     -->  4,  2,  0, 20
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [], [1]   --> 25,  0,  0,  1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0], [], [], [] -->  0, 26, 26, 26

El código más corto en bytes gana.

u54112
fuente

Respuestas:

3

CJam, 22 20 bytes

Gracias a jimmy23013 por guardar 2 bytes.

{{XD?}f%1fb_26&1bf^}

Un bloque (función) sin nombre, que toma una lista de 4 listas como entrada y devuelve la lista de puntuaciones.

Pruébalo en línea!

Explicación

{      e# For each card...
  XD?  e#   Choose 1 if it's positive and 13 if it's zero.
}f%
1fb    e# Sum each hand.
_26&   e# Get the set intersection of the scores with 26. This gives [26]
       e# if someone shot the moon, and [] otherwise.
1b     e# Treat as base-1 digits, which gives 26 if someone shot the moon
       e# and zero otherwise.
f^     e# XOR each result with this number. This swaps zeros and 26s when 
       e# someone shot the moon and does nothing otherwise.
Martin Ender
fuente
_26&1b. -2 bytes.
jimmy23013
@ jimmy23013 Ahhhh, 1b... yo estaba tratando de encontrar un camino corto a su vez [26]en 26y []en 0pero de alguna manera que no se me había ocurrido. Gracias :)
Martin Ender
8

R, 85 77 74 bytes

function(x,z=sapply(x,function(x)sum(x>0)+any(x<1)*13))abs(z-any(z>25)*26)

Función sin nombre que toma una lista R como entrada. Funciona contando el número de elementos >0y agrega 13 si algún elemento dentro de cada vector es <1( es decir, reina de espadas) y se almacena como z.

Si cualquier elemento en zes >25, de retorno 26-z, el retorno demás z.

Pruébalo en R-Fiddle

Billywob
fuente
1
Funcionaria 26-z?
u54112
@lastresort Sí, por supuesto. / facepalm
Billywob
4

C ++ 14, 158 bytes

Como Lambda sin nombre:

[](auto c){typename decltype(c)::value_type r;int b=0;for(auto d:c){int q=0;for(auto i:d)q+=i?1:13;r.push_back(q);b+=q==26;}if(b)for(int&x:r)x=26-x;return r;}

Requiere ay vector<vector<int>>devuelvevector<int>

Sin golf:

[](auto c){
 typename decltype(c)::value_type r;   //result vector
 int b=0;                              //flag if one has all cards
 for(auto d:c){                        //over all decks
  int q=0;                             //count points
  for(auto i:d) q+=i?1:13;             //+13 for queen, +1 else
  r.push_back(q);                      //add to result
  b+=q==26;                            //possibly activate flag
 }
 if(b) for(int&x:r) x=26-x;            //if flag is set, mirror the results
 return r;
}

Pocos casos de prueba para usted:

 auto r = std::vector<std::vector<int>>{{2,8,7,1},{3,4},{},{9,5,6,0,10,11,12,13}};
 auto s = std::vector<std::vector<int>>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0},{},{},{}};
 auto t = std::vector<std::vector<int>>{{},{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0},{},{1}};
Karl Napf
fuente
4

Python 2, 75 72 71 bytes

i=[len(a)+12*(0in a)for a in input()]
print[[x,26-x][26in i]for x in i]

Toma entrada como [2, 8, 7, 1], [3, 4], [], [9, 5, 6, 0, 10, 11, 12, 13]

TFeld
fuente
¿Podría guardar 3 caracteres usando 12 * [0in a] en lugar de [0,12] [0in a]?
Costantino
@Costantino, creo que te refieres 12*(0in a).
mbomb007
print[[x,26-x][26in i]for x in i]es un byte más corto.
Mathmandan
3

PHP, 113 bytes

function h($a){foreach($a as&$b)$b=count($b)+12*in_array(0,$b);if(max($a)>25)foreach($a as&$n)$n=26-$n;return$a;}

La función toma una matriz de matrices, devuelve una matriz de valores.


Maravíllate con el mapeo de otros arreglos en PHP: bucles con elementos referenciados. Mucho más corto que array_map.

Tito
fuente
3

Haskell, 62 59 56 bytes

f x|all(<26)x=x|0<1=map(26-)x
f.map(sum.map((13^).(0^)))

Uso:

> f.map(sum.map((13^).(0^))) $ [[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [], [1]]
[25,0,0,1]
Angs
fuente
Creo que puedes escribir fcomo f n=13^0^n.
xnor
@xnor Creo que tienes razón. Ahorra 3 bytes.
Angs
Creo que definirlo f x|all(<26)x=x|0<1=map(26-)xy usarlo en lugar de la función lambda ahorra algunos bytes.
Zgarb
@Zgarb tienes razón, diría que son otros 3 bytes.
Angs
2

05AB1E ,26 22 21 bytes

El espacio en blanco al final debe eliminarse de la entrada para que se interprete como una matriz. El final se inspiró en las otras respuestas al usar (26-x) cuando un jugador reunió todas las cartas de penalización.

vy0å12*yg+})D26©åi(®+

v                    For each array
 y                   Push array on the stack
  0å                 Generate a boolean array indicating whether the queen of spades is at the same index in the original array
    12*              Multiply by 12 the value of the queen of spades
       yg+           Add the length of the array; the queen of spades gets her last point from this part
          }          End for
           )         Push an array of all evaluated scores
            D26©å    1 if there is a 26, 0 otherwise
                 i   If there is a 26
                  (®+ Mirror the array: for each element yield 26-element
                      Implicit end if
                      Implicitly print the score array

Pruébalo en línea!

Todavía se ve bastante golfable, con constantes duplicadas y declaraciones condicionales.

Versión anterior, 26 bytes

(Un byte por cada punto en el valor de penalización máximo)

Decidí mantenerlo ya que su longitud se ajusta mejor a este desafío en mi opinión :).

vyD0å12*sg+})D26©QDOi_®*ë\

Pruébalo en línea!

Osable
fuente
2

Python 3, 101 bytes

def s(a):r=[sum([(1,13)[c==0]for c in h])for h in a];s=(r,[(26,0)[s==26]for s in r]);return s[26in r]

Código completo:

def score(hands):
    result = [sum([(1, 13)[card == 0] for card in hand]) for hand in hands]
    results = (result, [(26, 0)[score == 26] for score in result])
    return results[26 in result]
Jimmy Johnson
fuente
12*(c<1)+1es 2 bytes más corto que (1,13)[c==0]. 26*(s>25)es 3 bytes más corto que (26,0)[s==26].
Mego
2

JavaScript (ES6), 82 80 77 72 70 69 67 bytes

Guardado 2 bytes gracias a @Neil

f = 
s=>s.map(c=>c.map(t=>r+=t?1:13,r=0)|(b|=r>25,r),b=0).map(c=>b*26^c)

console.log(f.toString().length)
console.log(f([[2, 8, 7, 1], [3, 4], [], [9, 5, 6, 0, 10, 11, 12, 13]]));
console.log(f([[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [], [1] ]));
console.log(f([[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [1], [] ]));
console.log(f([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0], [], [], []]));
console.log(f([[],[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0], [], []]));

Descompostura

s=>s.map(                              // for each hand
 c=>c.map(                             // for each card
  t=>r+=t?1:13,                        // add value of card
 r=0)|(
  b=b|r>25,r                           // set flag if any hand scores 26 points
 ),
 b=0)
.map(c=>b?                             // for every card if a hand scored 26
  c?0:26                               // set every 0 hand to 26 and the 26 hand to 0
:c)                                    // otherwise do nothing
Lmis
fuente
c=>b*26^cahorra 2 bytes.
Neil
1

Pip , 28 bytes

27 bytes de código, +1 para -pbandera.

Y{$+1+12*!*a}M Va26Ny?26-yy

Toma información en la línea de comandos como una cadena que representa una lista anidada, como "[[2 8 7 1] [3 4] [] [9 5 6 0 10 11 12 13]]" (comillas no necesarias en TIO). Pruébalo en línea!

DLosc
fuente
1

Ruby, 59 bytes

->a{a.map{|h|a.max.size>13?h.min||26:h.size+12*h.count(0)}}

O alternativamente,

->a{a.map{|h|a.count([])>2?h.min||26:h.size+12*h.count(0)}}

Si solo una mano tiene cartas, queremos que las manos vacías obtengan un valor de 26, y la mano con cartas obtenga un valor de 0. Hago esto llamando mina las manos: esto devuelve niluna matriz vacía, y luego Lo pongo ||en 26. En otros casos, cuento el número de cartas en una mano y luego sumo 12 a la Reina de Picas.

Lee W
fuente
0

Scala, 93 bytes

a=>{val% =a.map(_.map{case 0=>13;case _=>1}sum)
if(%toSet 26)%map{case 0=>26;case _=>0}else%}

Uso:

val f:(Seq[Seq[Int]]=>Seq[Int])=...
f(Seq(Seq(2, 8, 7, 1), Seq(3, 4), Seq(), Seq(9, 5, 6, 0, 10, 11, 12, 13)))

Explicación:

a=>{           //define an anonymou function with a parameter a
  val% =         //define % as...
    a.map(         //map each element of a...
      _.map{         //to each of the card
        case 0=>13     //replaced with its value
        case _=>1
      }
      sum            //and the sum of the values
    )
  if(            //if
    %toSet 26      //one player has all cards
  )
    %map{          //return % with...
      case 0=>26     //each 0 replaced with 26
      case _=>0      //and everything else (aka the 26) replaced 0
    }
  else           //else
    %              //return %
}

Podría usar en %toSet 26lugar de % contains 26porque Setel applymétodo es containsy no get-at-index como Seqel de

corvus_192
fuente