Determinar a pontuação e a validade do Scrabble de uma string

24

Sua tarefa é determinar se uma determinada sequência tem o tamanho adequado e pode ser representada com blocos Scrabble e, se houver, gerar a soma da pontuação de cada letra.

Se você não sabe jogar Scrabble:, você tem 100 peças com várias letras de A a Z impressas, além de dois curingas que podem representar qualquer letra. Cada letra tem um certo número de pontos e cada bloco (mas não necessariamente a palavra) pode ser usado apenas uma vez. Quando uma palavra é reproduzida, o valor do ponto de cada peça usada é somado, o que se torna a pontuação. Como há um número limitado de letras disponíveis, uma palavra só pode ter uma determinada letra quantas vezes essa letra tiver ladrilhos + quaisquer curingas não utilizados. O quadro Scrabble tem 15 × 15 células, portanto a palavra deve ter entre 2 e 15 caracteres.

Para obter uma lista da quantidade e pontuação de cada letra na versão em inglês, veja abaixo ou http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( arquivo morto ).

Pontos de quantidade de letra Pontos de quantidade de letra
------------------- -------------------
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 [selvagem] 2 0
N 6 1

Regras adicionais

  • O programa deve receber uma única sequência de entradas do STDIN ou similar.
  • A entrada sempre conterá apenas letras maiúsculas.
  • Se a string contiver mais cópias de uma letra do que caracteres curinga ou blocos não utilizados para essa letra OU o comprimento da string não estiver entre 2 e 15, inclusive, o programa deverá ser exibido Invalid.
  • Caso contrário, a pontuação deve ser somada com o uso dos dados do gráfico acima e da saída.
  • Não use curingas, a menos que seja necessário.
  • Não se preocupe com bônus como pontuação de palavras duplas ou se a string é uma palavra real.
  • O programa deve produzir o resultado através de STDOUT ou similar.
  • As brechas proibidas por padrão não são permitidas.
  • Não é permitido o uso de uma fonte externa, como um site, bem como de bibliotecas, APIs, funções ou similares que calculem pontuações do Scrabble ou quantidades adequadas.
  • Isso é , e o menor número de bytes vence.

Passo a passo

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 teste

Saída de entrada
------------------------
SCRABBLE 14
JAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ Inválido
KIXOKEJAJAX inválido
MISUNDERSTANDING Inválido
NinjaBearMonkey
fonte
5
Pode querer adicionar um caso de teste para uma palavra válida que usa wild cards (por exemplo JAZZ = 19, não 29.)
Alconja
2
Você sabe, esse desafio seria muito mais maligno se envolvesse um idioma cujas peças do Scrabble não possam ser representadas com um único caractere, como espanhol, basco, húngaro, tuvan ou galês.
user0721090601
As respostas são especificamente necessárias para gerar "Inválido" ou podemos escolher algum comportamento, desde que claramente não seja uma pontuação? Por exemplo -1?
Kamil Drakari
@KamilDrakari Deve dizer exatamente Invalid.
NinjaBearMonkey

Respostas:

15

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

Execute com perl -E.

Golfe:

$_=<>;@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 solução usa alguns caracteres não imprimíveis, portanto, um hexdump é fornecido abaixo:

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

Como alternativa, 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 + comentou:

# 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
fonte
11
você pode extrair pelo menos 20 bytes dessas matrizes com alguma manipulação criativa
Sparr
11
Gah, sempre um passo à minha frente. :) Tenha um voto positivo.
Alconja
Isso tem sido interessante, nossas pontuações foram tão próximas o tempo todo. +1.
Level River St
Isso funciona com -M5.010(penalidade de 0 porque especifica uma versão do idioma a ser usado) em vez de -e(penalidade de 1)? Você pode salvar um byte nos argumentos.
13

C, Rev. 2, 151 145 138

Inspirado no código de 159 bytes no comentário de @ bebe, eu adicionei outros 8 14 21 caracteres:

4 bytes salvos reorganizando o contador de comprimento i. Isso é inicializado como 1 (assumindo que o programa não requer argumentos) e multiplicado por 4 toda vez que uma carta é lida. Ele excede a zero quando o tamanho da palavra é maior que 15; portanto, para verificar se o tamanho da palavra está ruim, basta verificar se i<5(eu coloco i<9para que ainda seja inválido para palavras de uma letra se o usuário acidentalmente inicializar ipara 2, colocando um único argumento na linha de comando.)

4 bytes salvos alterando o teste de condição do loop para um simples &31. Isso requer que a palavra seja finalizada com um espaço (ASCII 32) ou um caractere nulo (ASCII 0.). Normalmente, a entrada do teclado é finalizada por uma nova linha (ASCII 10); portanto, o programa é um pouco inconveniente de usar, porque você deve digitar o espaço e pressione return também para fazer o computador ler o buffer. Para strings terminadas em nova linha, eu poderia igualar, mas não bater, da maneira que o bebe faz.

6 13 bytes salvos alterando a codificação para - (número de blocos de cada letra) - (pontuação para a letra 1) * 13 . Isso agora requer um intervalo de -4 para L, S, U a -118 para Q, Z. O motivo para usar números negativos é evitar o intervalo ASCII não imprimível de 0 a 31. Em vez disso, o intervalo usado é o complemento de dois dos números negativos 256-4 = 252 a 256-118 = 138. Esses são caracteres ASCII estendidos e imprimíveis. Há problemas com a cópia e colagem deles no Unicode (a maneira como ele simplifica o retorno ao ASCII depende da página de códigos instalada, o que pode levar a resultados imprevisíveis), por isso incluí os códigos ASCII corretos no comentário do programa.

A vantagem dessa codificação é a eliminação da variável, rjá que o número de blocos é sempre reduzido em 1 (como é armazenado como um número negativo) t[x]++. Além disso, o operador postfix significa que podemos executar esse incremento ao mesmo tempo que adicionando a pontuação 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 (ou 172 com opção de compilador)

Estou usando o GCC e, com a opção do compilador -std=c99, me permitirá entrar char t[]="...."na inicialização do forloop para economizar um ponto e vírgula adicional. Para facilitar a leitura, mostrei o programa sem essa alteração e com espaços em branco restantes.

#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);
}

O truque está na tabela de dados. Para cada letra, um código ASCII do formulário (pontuação total de blocos para essa letra) * 10 + (pontuação de um bloco-1) é armazenado na tabela t[]. No tempo de execução, essas pontuações totais são reduzidas à medida que as peças são usadas.

A pontuação total de todos os blocos de cada letra varia de 12 para E até 4 para L, S, U. Essa forma de codificação permite que apenas caracteres ASCII imprimíveis sejam usados ​​(ASCII 120, xpara E até ASCII 40, (para L, S, U). O uso do número de blocos requer um intervalo de 120 a 10, e é por isso que eu evitado.

Graças a uma #definemacro, um único símbolo Té usado no programa principal para recuperar o índice carta ido primeiro argumento de linha de comando, ASCII subtrair A= 65 a partir dele para dar um índice, e procurá-lo na tabela T: t[x[1][i]-65].

O forloop é usado mais como um whileloop: o loop termina quando um byte zero (terminador de string) é encontrado na string de entrada.

Se os blocos dessa letra não estiverem esgotados ( T/10é diferente de zero) s, a pontuação do bloco será incrementada T%10+1para manter uma pontuação total. Ao mesmo tempo, a pontuação do bloco é armazenada r, de modo que o valor no capaz representado por Tpossa ser diminuído por r*10para indicar que um bloco foi usado. Se os blocos estiverem esgotados, o contador curinga / em branco bserá incrementado.

A printfafirmação é bastante auto-explicativa. se o comprimento da palavra estiver fora dos limites ou a contagem de espaços em branco for muito alta, imprima; Invalidcaso contrário, imprima a pontuação s.

Level River St
fonte
Como agora é outro dia, você pode salvar um caractere substituindo r + = (r == 7) * 3 por r + = r-7? 0: 3. Além disso, você não precisa dos colchetes redondos T- = r * 9, s + = r.
Alchymist
@ Alchymist Obrigado pela dica sobre os colchetes, sempre esqueço que não há problemas com a precedência do operador entre ?e :. Seu outro ponto foi substituído, pois eu mudei completamente a codificação para que não haja necessidade de nenhum tratamento especial de Q e Z. Agora, baixe para 173/172 com sua ajuda.
Level River St
11
com getchar()o 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);}embora eu ainda não entenda o porquê char*foo=<string>. poderia salvar 2 caracteres.
bebe
11
@bebe char*foo="string"é uma string literal e seu conteúdo não pode ser modificado. Por outro lado, char foo[]="string"cria uma matriz de caracteres inicializados para string\0, que podem ser modificados.
precisa saber é o seguinte
@bebe legal, eu perdi a ideia de usar getchar().Eu usei suas melhorias no código (com meus nomes de variáveis ​​para consistência com o restante da minha resposta), além de uma melhoria na verificação da validade do comprimento da palavra e uma melhoria atrevida na condição do loop teste (eu tentei encurtar o seu, mas não poderia fazê-lo com a mesma funcionalidade.) Eu também tentei getche()e getch()mas meu compilador (gcc em cygwin) não ligá-los automaticamente.
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 - mudou a maneira como codifiquei as quantidades / pontuações para reduzir o tamanho e remover variáveis ​​não-ascii

Editar 2 - alterou as codificações de quantidade / pontuação para números inteiros em vez de cadeias

Edição 3 - mudou para %13(thanks @ edc65), inverteu a codificação, modificou os valores diretamente e algumas outras pequenas melhorias

Testado no console do Firefox.

Alconja
fonte
11
+1 muito inteligente. Sugestões: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2. por que não usar% 13
edc65
11
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 = este [c])% 13? - $: t + = l / 13 + 1 | 0; alerta (i <3 | i> 16 | $ <0? "Inválido": t)}
edc65 5/08/14
@ edc65 - Muito obrigado. Não tinha visto o primeiro truque, mas não o usei, pois estou modificando diretamente os valores agora (arquivando-o mentalmente para golfe futuro). %13é um golpe de gênio. Fiquei preso pensando que tinha que armazenar coisas em dígitos, mas a matemática não se importa com a diferença entre base10 e base13.
Alconja
Agradável! (Não funciona no console do Chrome, BTW:. SyntaxError: Unexpected token >)
DLosc 6/14
@DLosc - Sim, acho que o Firefox é o único navegador no momento que suporta todo o material do ECMAScript 6 (o Chrome não gosta da f=s=>{...}notação).
Alconja
5

Python 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])

Ungolfed:

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])

Edit: Obrigado a @BeetDemGuise por uma dica que me levou a muito mais do que uma redução de 1 caractere! Código original abaixo:

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
fonte
Sua bastante mínima, mas você pode salvar 1byte codificando a cadeia de pontuação em hex: int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise
4

93 - 210 bytes.

Mas não verifica o limite 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
fonte
4

C, 197

Assume que a string é fornecida como um argumento de linha de comando, por exemplo ./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 melindroso
fonte
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)

zarmazena palavra. Saídas como alerta.

Editar: aprimorado conforme as recomendações abaixo.

Matt
fonte
2
sé usado apenas uma vez, para que você não precise transformá-lo em uma variável; você pode remover essa declaração e substituir r+=s[x]por r+=-~"02210313074020029000033739"[x]. Além disso, você não precisa de parênteses (w>2|y<2|y>15)no alerta.
NinjaBearMonkey
4

Haskell - 538

Salve-o como scrabble.hs e compile-o usando

ghc --make scrabble && ./scrabble

Em seguida, digite sua palavra como entrada e pressione 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
fonte
Você pode remover muitos espaços e em Haskell `['A', 'B', 'C'] ==" ABC ". Além disso, você pode usar apenas um espaço para cada nível de recuo. E você pode usar nomes mais curtos. Há muito para jogar golfe.
Ray
@ Ray Fiz isso, eu sou novo em Haskell, existe uma maneira de representar listas de Ints de forma mais concisa do que [1,2,3]?
Tuomas Laakkonen
"ABCDEFG"pode ser escrito como ['A'..'G'], [1,2,3]pode ser escrita como[1..3]
Ray
Como você obtém sua contagem de bytes? wc me fornece mais de 500 caracteres para o seu código.
TheSpanishInquisition
@TheSpanishInquisition Acabei de receber uma atualização para a minha extensão de contagem de palavras st3, o autor trocou as duas contagens acidentalmente, editado para 538
Tuomas Laakkonen
3

Python 2.7 - 263

Eu não consegui chegar nem perto da resposta do DLosc , mas isso trata cada letra como uma 'sacola' da qual você puxa, até ficar vazia, depois você puxa espaços em branco e, quando está vazia, ela erra.

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"
Comunidade
fonte
11
Esta é uma abordagem elegante! Você precisa raw_inputse é Python2 (uma coisa que eu gosto no Python3). A entrada é garantida em maiúsculas, portanto remova .lower()e mude 97+ipara 65+i. A entrada com menos de 2 caracteres também precisa ser inválida. Você pode aumentar o erro de divisão zero sem uma ifdeclaração: divida sua pontuação total por (1<len(S)<16). Alguns outros ajustes, como colocar os prints na mesma linha que os cabeçalhos dos blocos e excluir o espaço antes "Invalid", o reduzem a 250 pela minha contagem. :)
DLosc 6/08/14
2

Haskell, 290 283

O mais longe que pude fazer por enquanto:

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

Esse código cumpre as regras de maneira muito estrita; portanto, não passe caracteres extras (como final de linha). Use assim: echo -n "JAZZ" | runghc scrabble.hs.

Explicação

O padrão (_:_:_)garante que apenas cadeias de caracteres de pelo menos dois caracteres sejam consideradas; tudo o resto resulta em "Invalid"(padrão de fallback _). A tabela de blocos é codificada como 11*nTiles+valueconvertida em ASCII com um deslocamento que permite que o módulo de pesquisa 11 funcione, onde as letras AEIOsão duplicadas porque ocorrem mais de 6 vezes cada. O pool de blocos é criado usando replicate, do qual os caracteres da palavra são removidos à medida que ocorrem (diferença de lista,\\ ). O pool contém 98 blocos, portanto, se o comprimento total da palavra e a parte restante do pool for maior que 100, usamos muitos curingas. Além disso, a palavra menos as 15 primeiras letras é adicionada três vezes ao cálculo do comprimento, para que qualquer palavra com mais de 15 letras pareça usar automaticamente três caracteres curinga e, portanto, é inválida. A pontuação é feita no pool restante, que inicialmente tinha 187 pontos, dos quais simplesmente subtraímos. Observe o em f 61vez def 65, 65 sendo o número ASCII de 'A', por causa da duplicata "AEIO"no início do pool. O resto é apenas clichê.

TheSpanishInquisition
fonte
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)])

Vamos colocar os bignums em uso: D (atualmente não lida com curingas, eu pulei a leitura dessa regra completamente, caramba)

LemonBoy
fonte
1

Ruby - 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')

Estou assumindo que a saída de "Invalid"está bem, se não, eu precisaria fazer o $><<(-b<1&&w.size<16?s:'Invalid')que aumentaria até 198


Clojure - 325

Não faço clojure há algum tempo, então tenho certeza de que existem várias maneiras de melhorar minha solução. Nas listas de qty e pts

(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))))))

Alguns que Un-golfed

(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
fonte
1

ES6: 184 (não estrito)

wpresume-se que já contenha a palavra ré a sequência de saída.

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"

Aqui está explicado e um pouco menos jogado:

// 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
fonte
1

Dardo - 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");}

Isso requer bignums, portanto não será compilado para JavaScript.
Com mais espaço em branco:

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
fonte
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;

Yay! batendo JS!

demolir

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

Estou tão feliz que não há uma pontuação maior que 10.

Titus
fonte