Determinar la puntuación y la validez de Scrabble de una cadena

24

Su tarea es determinar si una cadena dada tiene la longitud adecuada y se puede representar con mosaicos Scrabble y, de ser así, generar la suma de la puntuación de cada letra.

Si no sabes cómo jugar Scrabble: tienes 100 fichas con varias letras de la A a la Z impresas, así como dos comodines que pueden representar cualquier letra. Cada letra tiene un cierto número de puntos, y cada mosaico (pero no necesariamente una palabra) solo se puede usar una vez. Cuando se juega una palabra, se suma el valor en puntos de cada ficha utilizada, que se convierte en la puntuación. Como hay un número limitado de letras disponibles, una palabra solo puede tener una letra determinada tantas veces como esa letra tenga mosaicos + cualquier comodín no utilizado. El tablero de Scrabble tiene 15 × 15 celdas, por lo que la palabra debe tener entre 2 y 15 caracteres de longitud.

Para obtener una lista de la cantidad y el puntaje de cada letra en la versión en inglés, consulte a continuación o http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( archivo ).

Puntos de cantidad de letras Puntos de cantidad de letras
------------------- -------------------
A 9 1 O 8 1
B 2 3 P 2 3
C 2 3 Q 1 10
D 4 2 R 6 1
E 12 1 S 4 1
F 2 4 T 6 1
G 3 2 U 4 1
H 2 4 V 2 4
I 9 1 W 2 4
J 1 8 X 1 8
K 1 5 Y 2 4
L 4 1 Z 1 10
M 2 3 [salvaje] 2 0
N 6 1

Reglas adicionales

  • El programa tomará una sola cadena de entrada de STDIN o similar.
  • La entrada siempre contendrá solo letras mayúsculas.
  • Si la cadena contiene más copias de una letra que comodines o mosaicos no utilizados para esa letra O la longitud de la cadena no está comprendida entre 2 y 15 inclusive, el programa debería salir Invalid.
  • De lo contrario, el puntaje debe sumarse con el uso de datos del cuadro anterior y la salida.
  • No use comodines a menos que sea necesario.
  • No se preocupe por las bonificaciones, como las puntuaciones de palabras dobles o si la cadena es una palabra real.
  • El programa enviará el resultado a través de STDOUT o similar.
  • Las lagunas prohibidas por defecto no están permitidas.
  • No se permite el uso de una fuente externa como un sitio web, así como bibliotecas, API, funciones o similares que calculen los puntajes de Scrabble o las cantidades adecuadas.
  • Este es el , por lo que gana menos bytes.

Tutorial

Input: CODEGOLF
C -> 3, O -> 1, D -> 2, E -> 1, G -> 2, O -> 1, L -> 1, F -> 4
3 + 1 + 2 + 1 + 2 + 1 + 1 + 4 = 15
Output: 15

Casos de prueba

De entrada y salida
------------------------
SCRABBLE 14
JAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ Inválido
KIXOKEJAJAX inválido
ENTENDIMIENTO INCORRECTO
NinjaOsoMono
fuente
55
Es posible que desee agregar un caso de prueba para una palabra válida que utiliza comodines (por ejemplo, JAZZ = 19, no 29)
Alconja
2
Sabes, este desafío sería mucho más malvado si involucrara un idioma cuyas fichas de Scrabble no se puedan representar con un solo carácter, como español, vasco, húngaro, tuván o galés.
user0721090601
¿Se requieren respuestas específicas para generar "Inválido", o podemos elegir cualquier comportamiento siempre que claramente no sea un puntaje? Por ejemplo, -1?
Kamil Drakari
@KamilDrakari Debe decir exactamente Invalid.
NinjaBearMonkey

Respuestas:

15

Perl 5 228 205 186 184 178 177 153 150 149 142 137 135

Ejecutar con perl -E.

Golfizado:

$_=<>;@a=@b=map-ord,'            0 0@0 H        ``'=~/./g;say s!.!($a[$q=64-ord$&]+=8)<8?$-+=1-29/$b[$q]:++$j!ge~~[2..15]&&$j<3?$-:Invalid

Esta solución utiliza algunos caracteres no imprimibles, por lo que a continuación se proporciona un volcado hexagonal:

00000000: 245f 3d3c 3e3b 4061 3d40 623d 6d61 702d  $_=<>;@a=@b=map-
00000010: 6f72 642c 2703 0904 0909 2030 2030 030e  ord,'..... 0 0..
00000020: 4030 0e20 0704 4809 1809 601d 0e0e 6027  @0. ..H...`...`'
00000030: 3d7e 2f2e 2f67 3b73 6179 2073 212e 2128  =~/./g;say s!.!(
00000040: 2461 5b24 713d 3634 2d6f 7264 2426 5d2b  $a[$q=64-ord$&]+
00000050: 3d38 293c 383f 242d 2b3d 312d 3239 2f24  =8)<8?$-+=1-29/$
00000060: 625b 2471 5d3a 2b2b 246a 2167 657e 7e5b  b[$q]:++$j!ge~~[
00000070: 322e 2e31 355d 2626 246a 3c33 3f24 2d3a  2..15]&&$j<3?$-:
00000080: 496e 7661 6c69 64                        Invalid

Alternativamente, usando Ctrl + Key:

$_=<>;@a=@b=map-ord,'^C^I^D^I^I 0 0^C^N@0^N ^G^DH^I^X^I`^]^N^N`'=~/./g;print s!.!($a[$q=64-ord$&]+=8)<8?$-+=1-29/$b[$q]:++$j!ge~~[2..15]&&$j<3?$-:Invalid

Ungolfed + comentó:

# Read in input
$_=<>;
# @a and @b: represents approximately 8x the number of tiles (when rounded up). The 
#   non-multiple-of-8 values distinguish tiles that are given equally, but are worth
#  different values
@b=@a=map-ord,"...."~=/./g;
# above is equivalent to
# @a=@b=(-03,-09,-04,-09,-09,-32,-48,-32,-48,-03,-14,-64,-48,-14,-32,-07,-04,-72,-09,-24,-09,-96,-29,-14,-14,-96);
say
    # for each character
    s!.!
        # $q: A->-1, B->-2, etc.
        # decrement number of $q tiles, add points if needed, otherwise
        #    increment j, which counts number of wilds used
        # truncate(1-29/b[q]): decimal values were chosen specifically
        #    for this to return the point value. b[q] is the number of tiles
        #    of the qth letter after a originally given.
        #  $- contains the score, is initially zero (if in a one line program, 
        #   as the golfed version is), and is always an integer
        ($a[$q=64-ord$&]+=8)<8 ? $- += 1 - 29/$b[$q] : ++$j
    # s returns length, check if between 2 and 15
    !ge ~~ [2..15]
    # make sure less than 3 negative tiles (aka wilds) 
    && $j < 3 ?
        # print score
        $-
    # or invalid
    : Invalid
es1024
fuente
1
puede exprimir al menos 20 bytes de esas matrices con alguna manipulación creativa
Sparr
1
Gah, siempre un paso por delante de mí. :) Tener un voto a favor.
Alconja
Esto ha sido interesante, nuestros puntajes han estado muy cerca en todo momento. +1.
Level River St el
¿Funciona con -M5.010(penalización de 0 porque especifica una versión del lenguaje a usar) en lugar de -e(penalización de 1)? Es posible que pueda guardar un byte en los argumentos.
13

C, Rev 2, 151 145 138

Inspirado por el código de 159 bytes en el comentario de @bebe, exprimí otros 8 14 21 caracteres:

Se guardan 4 bytes al reorganizar el contador de longitud i. Esto se inicializa a 1 (suponiendo que el programa no tome argumentos) y luego se multiplica por 4 cada vez que se lee una carta. Se desborda a cero cuando la longitud de la palabra es mayor que 15, por lo que para verificar si la longitud de la palabra es incorrecta, simplemente verificamos si i<5(lo pongo, i<9por lo que aún dará validez para las palabras de una letra si el usuario accidentalmente inicia ia 2 poniendo un solo argumento en la línea de comando).

Se guardan 4 bytes cambiando la prueba de condición de bucle a simple &31. Esto requiere que la palabra se termine con un espacio (ASCII 32) o un carácter nulo (ASCII 0). Normalmente, la entrada del teclado se termina con una nueva línea (ASCII 10), por lo que el programa es un poco incómodo de usar, ya que debe escribir el luego presione la tecla de retorno para que la computadora lea el búfer. Para cadenas terminadas en nueva línea, podría coincidir pero no superar la forma en que lo hace.

6 13 bytes guardados cambiando la codificación a - (número de mosaicos de cada letra) - (puntaje para esa letra-1) * 13 . Esto ahora requiere un rango de -4 para L, S, U a -118 para Q, Z. La razón para usar números negativos es evitar el rango ASCII no imprimible de 0 a 31. En cambio, el rango utilizado es el complemento a dos de los números negativos 256-4 = 252 a 256-118 = 138. Estos son caracteres ASCII extendidos e imprimibles. Hay problemas al copiar y pegar estos en Unicode (la forma en que se simplifica de nuevo a ASCII depende de la página de códigos instalada, lo que puede conducir a resultados impredecibles), por lo que he incluido los códigos ASCII correctos en el comentario del programa.

La ventaja de esta codificación es la eliminación de la variable, rya que el número de mosaicos siempre se reduce en 1 (ya que se almacena como un número negativo, lo hacemos t[x]++. Además, el operador postfix significa que podemos realizar este incremento al mismo tiempo que agregando el puntaje a s.

//char t[]={32,247,228,228,239,244,215,240,215,247,164,203,252,228,250,248,228,138,250,252,250,252,215,215,164,215,138,0};
b,s;
main(i,x){
  for(char t[]=" ÷ääïô×ð×÷¤ËüäúøäŠúüúü×פ׊";x=getchar()&31;i*=4)
    t[x]%13?
      s-=t[x]++/13-1:
      b++;
  printf(i<9|b>2?"Invalid":"%d",s);
} 

C, 184 Rev 1 173 (o 172 con opción de compilador)

Estoy usando GCC, y con la opción del compilador -std=c99me permitirá pasar char t[]="...."a la inicialización del forbucle para guardar un punto y coma adicional. Para facilitar la lectura, he mostrado el programa sin este cambio y con espacios en blanco.

#define T t[x[1][i]-65]
i,b,s;
main(int r,char**x){
  char t[]="Z>>QxS=SZW6(><P>m<(<(SSWSm";
  for(;x[1][i];i++)
    T/10?
      s+=r=T%10+1,T-=r*10:
      b++;
  printf(i<2|i>15|b>2?"Invalid":"%d",s);
}

El truco está en la tabla de datos. Para cada letra, se almacena en la tabla un código ASCII del formulario (puntaje total de mosaicos para esa letra) * 10 + (puntaje de un mosaico-1)t[] . En tiempo de ejecución, estos puntajes totales se reducen a medida que se agotan las fichas.

El puntaje total de todas las fichas para cada letra varía de 12 para E a 4 para L, S, U. Esta forma de codificación solo permite el uso de caracteres ASCII imprimibles (ASCII 120, xpara E hasta ASCII 40, (para L, S, U). El uso del número de mosaicos necesitaría un rango de 120 a 10, por lo que I lo evité

Gracias a una #definemacro, un solo símbolo Tse utiliza en el programa principal para recuperar el índice carta idel primer argumento de línea de comandos, restar ASCII A= 65 de ella para dar un índice, y mirar hacia arriba en la tabla T: t[x[1][i]-65].

El forbucle se usa más como un whilebucle: el bucle termina cuando se encuentra un byte cero (terminador de cadena) en la cadena de entrada.

Si los mosaicos de esa letra no están agotados ( T/10es distinto de cero) sse incrementa la puntuación del mosaico T%10+1para mantener un puntaje total. Al mismo tiempo, el puntaje de mosaico se almacena r, de modo que el valor en la capacidad representada por Tse puede disminuir r*10para indicar que se ha utilizado un mosaico. Si las fichas están agotadas, el comodín / contador en blanco bse incrementa.

La printfafirmación es bastante autoexplicativa. Si la longitud de palabra está fuera de límites o el recuento en blanco es demasiado alta, imprimir Invalidotra manera imprimir la partitura s.

Level River St
fuente
Como ahora es otro día, puede guardar un personaje reemplazando r + = (r == 7) * 3 con r + = r-7? 0: 3. Además, no necesita los corchetes alrededor de T- = r * 9, s + = r.
Alchymist
@Alchymist Gracias por el consejo sobre los corchetes, siempre olvido que no hay problemas con la precedencia del operador entre ?y :. Su otro punto se reemplaza, ya que he cambiado completamente la codificación, por lo que no hay necesidad de ningún manejo especial de Q y Z. Ahora baje a 173/172 con su ayuda.
Level River St
1
con getchar()su 159: l,w,f;main(t,i){for(char b[]="Z>>QxS=SZW6(><P>m<(<(SSWSm";(i=getchar()-65)>=0;l++)b[i]/10?f+=t=b[i]%10+1,b[i]-=t*10:w++;printf(l<2|l>15|w>2?"Invalid":"%d",f);}aunque todavía no entiendo por qué se char*foo=<string>bloquea. Podría ahorrar 2 caracteres.
bebe
1
@bebe char*foo="string"es un literal de cadena y no se permite modificar su contenido. Por otro lado, char foo[]="string"crea una matriz de caracteres inicializados string\0, que luego pueden modificarse.
es1024
@bebe cool, perdí la idea de usar getchar().He usado tus mejoras en el código (con mis nombres de variables para mantener la coherencia con el resto de mi respuesta), además de una mejora en la verificación de validez de longitud de palabra y una mejora descarada en la condición del bucle prueba (intenté acortar la tuya pero no pude hacerlo con la misma funcionalidad). También lo intenté getche()y getch()mi compilador (gcc en cygwin) no los enlazó automáticamente.
Level River St
5

JavaScript (ES6) - 241 230 199 182

f=s=>{for(i=t=_=0,E=12,A=I=9,B=C=M=P=28,D=17,F=H=V=W=Y=41,G=16,J=X=92,K=53,L=S=U=4,N=R=T=6,O=8,Q=Z=118;c=s[i++];)this[c]%13<1?_++:t+=1+this[c]--/13|0;alert(i<3|i>16|_>2?"Invalid":t)}

Editar : cambió la forma en que codifiqué las cantidades / puntajes para reducir el tamaño y eliminar las variables que no son ascii

Edición 2 : cambió las codificaciones de cantidad / puntuación a enteros en lugar de cadenas

Edición 3 : cambió a %13(gracias @ edc65), invirtió la codificación, modificó los valores directamente y algunas otras mejoras menores

Probado en la consola de Firefox.

Alconja
fuente
1
+1 muy inteligente. Sugerencias: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2.por qué no usar% 13
edc65
1
192 f = s => {para (E = 12, A = I = 9, B = C = M = P = 28, D = 17, F = H = V = W = Y = 41, G = 16, J = X = 92, K = 53, L = S = U = 4, N = R = T = 6, O = 8, Q = Z = 118, $ = 2, t = i = 0; c = s [i ++ ];) (f [c] = - ~ f [c])> (l = this [c])% 13? - $: t + = l / 13 + 1 | 0; alerta (i <3 | i> 16 | $ <0? "Inválido": t)}
edc65
@ edc65 - Muchas gracias. No había visto ese primer truco, pero no terminé usándolo, ya que ahora estoy modificando los valores directamente (archivándolo mentalmente para el futuro golf). %13Sin embargo, es un golpe de genio. Me quedé atrapado pensando que tenía que almacenar cosas en dígitos, pero a las matemáticas no les importa la diferencia entre base10 y base13.
Alconja
¡Agradable! (No funciona en la consola de Chrome, por cierto:. SyntaxError: Unexpected token >)
DLosc
@DLosc - Sí, creo que Firefox es el único navegador en este momento que admite todas las cosas de ECMAScript 6 (a Chrome no le gusta la f=s=>{...}notación).
Alconja
5

Pitón 3, 217 201

b=2;i=s=0;w=input()
while i<26:n=w.count(chr(i+65));q=int('9224c232911426821646422121'[i],16);b-=max(0,n-q);s+=min(n,q)*int('1332142418513113a11114484a'[i],16);i+=1
print(["Invalid",s][-b<1<len(w)<16])

Sin golf:

b=2    # number of blanks available
i=s=0  # letter index 0..25, running score tally
w=input()

# Loop through each letter of the alphabet
while i<26:
    # Get number of occurrences in the word
    n=w.count(chr(i+65))
    # Get quantity of the letter from hex encoded string
    q=int('9224c232911426821646422121'[i],16)
    # Remove blanks for each occurrence over that letter's quantity
    b-=max(0,n-q)
    # Score the non-blank tiles, getting scores from hex-encoded string
    s+=min(n,q)*int('1332142418513113a11114484a'[i],16)
    # Increment
    i+=1

# If b > -1 and 1 < len(w) < 16, print the score; otherwise, print "Invalid"
print(["Invalid",s][-b<1<len(w)<16])

Editar: ¡ Gracias a @BeetDemGuise por un consejo que finalmente me llevó a mucho más que una reducción de 1 carácter! Código original a continuación:

q=[77-ord(x)for x in'DKKIAKJKDLLIKGEKLGIGIKKLKL'];b=2;s=0;w=input()
for c in set(w):n=w.count(c);o=ord(c)-65;b-=max(0,n-q[o]);s+=min(n,q[o])*(1+int('02210313074020029000033739'[o]))
print(["Invalid",s][-b<1<len(w)<16])
DLosc
fuente
Es bastante mínimo, pero puede ahorrar 1byte codificando su cadena de puntajes en hexadecimal: int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise
4

BEFUNGE 93 - 210 bytes.

Pero no verifica el límite de 15 letras.

v1332142418513113:11114484: >01g:"0"-!#v_1-01p1+\v
 9224<232911426821646422121v  "Invalid"<      vp0<
<vp00p10"20"p200p900
>>~:55+-!#v_"@"-::1g:"0"-! #^_1-\1p0g+"0"-02g+>02p
_v#:-1<    #p90+g90-"0"g1:<
     @.g20<        @,,,,,,,<
AndoDaan
fuente
4

C, 197

Asume que la cadena se proporciona como un argumento de línea de comando, por ej. ./scrabble STACKEXCHANGE

s;n;m=31;main(int c,char**v){char d[]="BIBBDLBCBIAADBFHBAFDFDBBABA@ACCBADBDAHEACAACJAAAADDHDJ";for(;c=*v[1]++&m;d[c]--,s+=d[c+27]&m)n+=1+m*(!(d[c]&m||d[c=0]&m));printf(n>1&&n<16?"%d":"Invalid",s);}
ossifrage aprensivo
fuente
4

JavaScript - 232 201

t=[9,2,2,4,12,2,3,2,9,1,1,4,2,6,8,2,1,6,4,6,4,2,2,1,2,1];w=r=0;for(i=y=z.length;i--;){x=z.charCodeAt(i)-65;if(!t[x])w++;else{t[x]--;r+=-~"02210313074020029000033739"[x]}}alert(w>2|y<2|y>15?"Invalid":r)

zalmacena la palabra Salidas como alerta.

Editar: mejorado según las recomendaciones a continuación.

Mate
fuente
2
ssolo se usa una vez, por lo que no es necesario que sea una variable; puedes eliminar esa declaración y reemplazarla r+=s[x]por r+=-~"02210313074020029000033739"[x]. Además, no necesita paréntesis (w>2|y<2|y>15)en la alerta.
NinjaBearMonkey
4

Haskell - 538

Guárdelo como scrabble.hs y luego compílelo usando

ghc --make scrabble && ./scrabble

Luego ingrese su palabra como entrada y presione enter

l=['A'..'Z']
sc=zip l [1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10]
vfs a y =snd $ filter (\x -> fst x == y) a !! 0
q = zip l [9,2,2,4,12,2,3,2,9,1,1,4,2,6,8,2,1,6,4,6,4,2,2,1,2,1]
i s =filter (\x -> (fst x) >=0) [(length [x | x <- s, x == a] - vfs q a,a) | a <- l]
main = do
 s <- getLine
 if length s <= 15 && length s > 2 && sum (map fst (i s)) <= 2 then
  putStrLn $ show (sum [vfs sc x| x <- s] - sum [(vfs sc (snd x)) * (fst x) | x <- (filter (\x -> fst x > 0) (i s))])
 else do
  putStrLn "Invalid"
Tuomas Laakkonen
fuente
Puede eliminar muchos espacios y en Haskell `['' A ',' B ',' C '] ==" ABC ". También puede usar solo un espacio para cada nivel de sangría. Y puedes usar nombres más cortos. Hay mucho para jugar al golf.
Ray
@Ray. He hecho eso, soy nuevo en Haskell, ¿hay alguna forma de representar listas de Ints de manera más concisa que [1,2,3]?
Tuomas Laakkonen
"ABCDEFG"puede ser escrito como ['A'..'G'], [1,2,3]puede ser escrito como[1..3]
Ray
¿Cómo obtienes tu conteo de bytes? wc me da más de 500 caracteres para tu código.
TheSpanishInquisition
@TheSpanishInquisition Acabo de recibir una actualización para mi extensión de conteo de palabras st3, el autor había intercambiado los dos conteos accidentalmente, editado a 538
Tuomas Laakkonen
3

Python 2.7 - 263

No pude acercarme a la respuesta de DLosc , pero esto trata cada letra como una 'bolsa' de la que sacas, hasta que está vacía, luego sacas espacios en blanco, y cuando está vacía, se produce un error.

S=input().lower()
X={chr(97+i):[int(y)+1]*(77-ord(x))for i,(x,y)in enumerate(zip('DKKIAKJKDLLIKGEKLGIGIKKLKL','02210313074020029000033739'))}
B=[0,0]
try:
 if len(S)>15:1/0
 print sum(map(lambda x:X[x].pop()if len(X[x])>0 else B.pop(),S))
except:
 print "invalid"
Comunidad
fuente
1
Este es un enfoque ordenado! Lo necesitas raw_inputsi es Python2 (una cosa que me gusta de Python3). La entrada está garantizada en mayúsculas, por lo tanto, elimine .lower()y cambie 97+ia 65+i. La entrada de menos de 2 caracteres también debe ser inválida. Puede aumentar el error de división cero sin una ifdeclaración: divida su puntaje total entre (1<len(S)<16). Un par de otros ajustes como poner la prints en la misma línea que los encabezados de bloque y eliminar el espacio antes "Invalid"lo reduce a 250 por mi cuenta. :)
DLosc
2

Haskell, 290 283

Tan lejos como pude hacerlo por ahora:

import Data.List
t="CdC8d::Od;D;d41N:dd:6dNdN;;4;6"
s w@(_:_:_)=let d=concat(zipWith(replicate.(`div`11).f 33)t("AEIO"++['A'..]))\\w;y=drop 15w in if length(d++w++y++y++y)>100 then s""else show$187-(sum$map((`mod`11).f 0.(t!!).f 61)d)
s _="Invalid"
f n=(-n+).fromEnum
main=interact s

Este código cumple estrictamente las reglas, así que asegúrese de no pasarle ningún carácter adicional (como el final de línea). Utilice la siguiente manera: echo -n "JAZZ" | runghc scrabble.hs.

Explicación

El patrón (_:_:_)asegura que solo se consideren cadenas de al menos dos caracteres, todo lo demás da como resultado "Invalid"(patrón de reserva _). La tabla de mosaicos se codifica como 11*nTiles+valueconvertida a ASCII con un desplazamiento que permite que funcione el módulo de búsqueda 11, donde las letras AEIOse duplican porque ocurren más de 6 veces cada una. El grupo de mosaicos se crea utilizando replicate, de donde se eliminan los caracteres de la palabra a medida que ocurren (diferencia de lista,\\) El grupo contiene 98 mosaicos, por lo que si la longitud total de la palabra y la parte restante del grupo es mayor que 100, entonces hemos usado demasiados comodines. Además, la palabra menos las primeras 15 letras se agrega tres veces al cálculo de longitud, por lo que cualquier palabra de más de 15 letras parece usar automáticamente tres comodines y, por lo tanto, no es válida. La puntuación se realiza en el grupo restante, que inicialmente tenía 187 puntos, de los que simplemente restamos. Tenga en cuenta que en f 61lugar de f 65, 65 es el número ASCII de 'A', debido al duplicado "AEIO"al comienzo del grupo. El resto es solo repetitivo.

La Inquisición Española
fuente
1

Python3 - 197

s,i,c,r=input(),0x1a24182424416141611a2381612341151891243224c142232391,[],[]; p=len(s)
for w in s:e=8*ord(w)-520;c+=[s.count(w)<=i>>e+4&15];r+=[i>>e&15]
print(['Invalid',sum(r)][all([p>2,p<15]+c)])

Pongamos los bignums en uso: D (actualmente no maneja comodines, he omitido leer esa regla por completo, maldición)

LemonBoy
fuente
1

Rubí - 195

b=2
i=s=0
w=$*[0]
(?A..?Z).map{|l|n=w.count(l);q='9224c232911426821646422121'[i].to_i(16);b-=[0,n-q].max;s+=[n,q].min*'1332142418513113a11114484a'[i].to_i(16);i+=1}
p(-b<1&&w.size<16?s:'Invalid')

Supongo que la salida de "Invalid"está bien, si no, tendría que hacer lo $><<(-b<1&&w.size<16?s:'Invalid')que lo elevaría a 198


Clojure - 325

No he hecho clojure en un tiempo, así que estoy seguro de que hay varias formas de mejorar mi solución. Por ejemplo, las listas de cantidad y puntos

(let[w(first *command-line-args*)o(map #(count(filter #{%}(seq w)))(map char(range 65 91)))i(apply +(filter neg?(map #(- % %2)'(9 2 2 4 12 2 3 2 9 1 1 4 2 6 8 2 1 6 4 6 4 2 2 1 2 1) o)))](println(if(or(> -2 i)(not(<= 2(count w)15)))"Invalid"(apply +(map #(* % %2)o'(1 3 3 2 1 4 2 4 1 8 5 1 3 1 1 3 10 1 1 1 1 4 4 8 4 10))))))

Algo de lo que no es golf

(let [word    (first *command-line-args*)
      letters (map char(range 65 91))
      occ     (map #(count (filter #{%} (seq word))) letters)
      invalid (apply + (filter neg? (map #(- % %2)
                '(9 2 2 4 12 2 3 2 9 1 1 4 2 6 8 2 1 6 4 6 4 2 2 1 2 1)
                occ)))
      score   (apply + (map #(* % %2) occ '(1 3 3 2 1 4 2 4 1 8 5 1 3 1 1 3 10 1 1 1 1 4 4 8 4 10)))]
    (println
      (if (or (> -2 invalid)
              (not (<= 2 (count word) 15)))
        "Invalid"
        score)))
Ebtoulson
fuente
1

ES6: 184 (no estricto)

wse supone que ya contiene la palabra. res la cadena de salida.

i=0,o=[..."291232342c124322491181541236181231a61416141242418241a"].map(c=>parseInt(c,16)),r=!w[16]&&w[2]&&[...w].every(c=>o[c=c.charCodeAt()*2-129]-->0?i+=o[c+1]:o[0]--)?i+"":"Invalid"

Aquí está explicado y un poco menos golfizado:

// The sum.
i = 0,

// The data for the letters. It's encoded similar to the Ruby version, with
// the first being the wildcard holder. The rest hold in hex form the
// following: first = quantity left, second = value.
// The .map(c => parseInt(c, 16) simply parses all the hex characters.
o = [..."291232342c124322491181541236181231a61416141242418241a"]
  .map(c => parseInt(c, 16)),

// The result, `r`.
r = !w[16] || // If there is a 16th character in the word or no 2nd character,
    w[2] &&   // then the next section isn't evaluated. It immediately equates
              // to true, thus returning "Invalid".
   [...w] // Convert the string into an array of characters (ES6 equivalent to
          // `.split('')`
    .every(c => // This loop terminates when the callback returns a falsy
                // value.
      // Gets the ASCII value, subtracts 65, doubles it (the lookup table is
      // in pairs within one array), and decrements the counter at that entry.
      // The lookup table also doubles as a data holder.
      o[c = c.charCodeAt() * 2 - 129]--
        > 0 ?  // Test if there is something to take away. This must return
               // false at 0 and -1 so wildcards can be taken.
        i += o[c+1] : // If there was something to take away, then add the
                      // letter value to the sum.
        o[0]--) // Otherwise, take a wildcard. If this is already at 0, then
                // it returns falsy.
      ? "Invalid" : i + "" // This is where the text is returned.
Isiah Meadows
fuente
1

Dart - 201

main(a,{x:0xa14281424214161416a132181632145181194223421c24323219,i,r:0,m,s:2}){if((m=a[0].length)>1&&m<16)for(i in a[s=0].codeUnits)x>>(m=i*8-520)&15>0?r+=(x-=1<<m)>>m+4&15:++s;print(s<2?r:"Invalid");}

Esto requiere bignums, por lo que no se compilará en JavaScript.
Con más espacios en blanco:

main(a,{x:0xa14281424214161416a132181632145181194223421c24323219,i,r:0,m,s:3}){
  if((m=a[0].length)>1&&m<16)
    for(i in a[s=0].codeUnits)
      x>>(m=i*8-520)&15>0
      ? r+=(x-=1<<m)>>m+4&15
      : ++s;
  print(s<3?r:"Invalid");
}
lrn
fuente
0

PHP, 180 170 168 bytes

for($q=str_split(KDKKIAKJKDLLIKGEKLGIGIKKLKL);$o=31&ord($argv[1][$i++]);)$s+=$q[$o]++>L?$q[0]++>L?$f=1:0:X02210313074020029000033739[$o]+1;echo$f|$i<3|$i>16?Invalid:$s;

¡Hurra! venciendo a JS!

Descompostura

for(
    $q=str_split(KDKKIAKJKDLLIKGEKLGIGIKKLKL);  // init quantities: L=1,A=12
    $o=31&ord($argv[1][$i++]);                  // loop through characters: map to [1..26]
)
    $s+=                                          // increase score by ...
        $q[$o]++>L?                                 // old quantity below 1?
        $q[0]++>L?$f=1                              // no more wildcards? set error flag
        :0                                          // wildcard: 0 points
        :X02210313074020029000033739[$o]+1;         // else: letter score
echo$f|$i<3|$i>16?Invalid:$s;                   // output

Estoy muy contento de que no haya una puntuación de letra mayor a 10.

Titus
fuente