Déterminer le score et la validité du Scrabble d'une chaîne

24

Votre tâche consiste à déterminer si une chaîne donnée est de bonne longueur et peut être représentée avec des tuiles Scrabble et, si c'est le cas, à produire la somme du score de chaque lettre.

Si vous ne savez pas comment jouer au Scrabble :, vous avez 100 tuiles avec différentes lettres A – Z imprimées dessus, ainsi que deux jokers qui peuvent représenter n'importe quelle lettre. Chaque lettre a un certain nombre de points, et chaque tuile (mais pas nécessairement un mot) ne peut être utilisée qu'une seule fois. Lorsqu'un mot est joué, la valeur en points de chaque tuile utilisée est additionnée, ce qui devient le score. Comme il y a un nombre limité de lettres disponibles, un mot ne peut avoir qu'une certaine lettre autant de fois que cette lettre a de tuiles + tous les caractères génériques inutilisés. Le tableau Scrabble est de 15 × 15 cellules, donc le mot doit comprendre entre 2 et 15 caractères.

Pour une liste de la quantité et du score de chaque lettre dans la version anglaise, voir ci-dessous ou http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( archive ).

Lettre Qté Points Lettre Qté Points
------------------- -------------------
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 [sauvage] 2 0
N 6 1

Règles supplémentaires

  • Le programme doit prendre une seule chaîne d'entrée de STDIN ou similaire.
  • L'entrée ne contiendra toujours que des lettres majuscules.
  • Si la chaîne contient plus de copies d'une lettre qu'il n'y a de caractères génériques ou de tuiles inutilisés pour cette lettre OU que la longueur de la chaîne n'est pas comprise entre 2 et 15 inclus, le programme doit sortir Invalid.
  • Sinon, le score doit être additionné en utilisant les données du graphique ci-dessus et en sortie.
  • N'utilisez pas de caractères génériques, sauf si cela est nécessaire.
  • Ne vous inquiétez pas des bonus tels que les scores de double mot ou si la chaîne est un vrai mot.
  • Le programme doit sortir le résultat via STDOUT ou similaire.
  • Les failles interdites par défaut ne sont pas autorisées.
  • L'utilisation d'une source externe telle qu'un site Web, ainsi que toutes bibliothèques, API, fonctions ou similaires qui calculent les scores Scrabble ou les quantités appropriées ne sont pas autorisées.
  • Il s'agit de , donc le moins d'octets gagne.

Procédure pas à pas

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

Cas de test

Entrée sortie
------------------------
SCRABBLE 14
JAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ invalide
KIXOKEJAJAX non valide
MISUNDERSTANDING Invalid
NinjaBearMonkey
la source
5
Pourrait vouloir ajouter un cas de test pour un mot valide qui utilise des caractères génériques (par exemple. JAZZ = 19, pas 29)
Alconja
2
Vous savez, ce défi serait bien plus mal s'il impliquait une langue dont les tuiles Scrabble ne peuvent pas être représentées avec un seul caractère, comme l'espagnol, le basque, le hongrois, le tuvan ou le gallois.
user0721090601
Des réponses sont-elles spécifiquement requises pour afficher "Non valide", ou pouvons-nous choisir un comportement tant qu'il ne s'agit clairement pas d'un score? Par exemple -1,?
Kamil Drakari
@KamilDrakari Cela doit dire exactement Invalid.
NinjaBearMonkey

Réponses:

15

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

Exécutez avec perl -E.

Golfé:

$_=<>;@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

Cette solution utilise des caractères non imprimables, donc un vidage hexadécimal est fourni ci-dessous:

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

Alternativement, en utilisant 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

Non golfé + a commenté:

# 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
la source
1
vous pouvez extraire au moins 20 octets de ces tableaux avec une manipulation créative
Sparr
1
Gah, toujours une longueur d'avance sur moi. :) Ayez un vote positif.
Alconja
Cela a été intéressant, nos scores ont été si proches tout le long. +1.
Level River St
Est-ce que cela fonctionne avec -M5.010(pénalité de 0 car il spécifie une version de la langue à utiliser) plutôt que -e(pénalité de 1)? Vous pourrez peut-être enregistrer un octet dans les arguments.
13

C, Rév 2, 151 145 138

Inspiré par le code de 159 octets dans le commentaire de @ bebe, j'ai pressé encore 8 14 21 caractères:

4 octets enregistrés en réorganisant le compteur de longueur i. Celui-ci est initialisé à 1 (en supposant que le programme ne prend aucun argument) puis multiplié par 4 à chaque lecture d'une lettre. Il déborde à zéro lorsque la longueur du mot est supérieure à 15, donc pour vérifier si la longueur du mot est mauvaise, nous vérifions simplement si i<5(je mets i<9donc cela donnera toujours invalide pour les mots d'une lettre si l'utilisateur initialise accidentellement ià 2 en mettant un seul argument sur la ligne de commande.)

4 octets enregistrés en changeant le test de condition de boucle en simple &31. Cela nécessite que le mot se termine par un espace (ASCII 32) ou un caractère nul (ASCII 0.) Normalement, la saisie au clavier se termine par une nouvelle ligne (ASCII 10), donc le programme est un peu gênant à utiliser, car vous devez taper le espace, puis appuyez également sur Retour pour que l'ordinateur lise le tampon. Pour les chaînes terminées par une nouvelle ligne, je pourrais faire correspondre mais pas battre la façon dont bebe le fait.

6 13 octets enregistrés en changeant l'encodage en - (nombre de tuiles de chaque lettre) - (score pour cette lettre-1) * 13 . Cela nécessite désormais une plage de -4 pour L, S, U à -118 pour Q, Z. La raison d'utiliser des nombres négatifs est d'éviter la plage ASCII non imprimable de 0 à 31. Au lieu de cela, la plage utilisée est le complément à deux des nombres négatifs 256-4 = 252 à 256-118 = 138. Ce sont des caractères ASCII étendus imprimables. Il y a des problèmes avec les copier-coller en Unicode (la façon dont cela simplifie le retour en ASCII dépend de la page de codes installée, ce qui peut conduire à des résultats imprévisibles), j'ai donc inclus les bons codes ASCII dans le commentaire du programme.

L'avantage de ce codage est l'élimination de la variable rcar le nombre de tuiles est toujours réduit de 1 (car il est stocké comme un nombre négatif, nous le faisons t[x]++. De plus, l'opérateur postfix signifie que nous pouvons effectuer cet incrément en même temps que en ajoutant le score à 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 avec option de compilation)

J'utilise GCC, et avec l'option du compilateur, -std=c99cela me permettra de passer char t[]="...."à l'initialisation de la forboucle pour économiser un point-virgule supplémentaire. Pour plus de lisibilité, j'ai montré le programme sans ce changement, et avec des espaces laissés dedans.

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

L'astuce est dans le datatable. Pour chaque lettre, un code ASCII du formulaire (score total de tuiles pour cette lettre) * 10 + (score d'une tuile-1) est stocké dans le tableau t[]. Au moment de l'exécution, ces scores totaux sont réduits à mesure que les tuiles sont épuisées.

Le score total de toutes les tuiles pour chaque lettre varie de 12 pour E à 4 pour L, S, U. Cette forme d'encodage permet d'utiliser uniquement des caractères ASCII imprimables (ASCII 120, xpour E jusqu'à ASCII 40, (pour L, S, U.) L'utilisation du nombre de tuiles nécessiterait une plage de 120 à 10, c'est pourquoi je l'évité.

Merci à une #definemacro, un seul symbole Test utilisé dans le programme principal pour récupérer l'index de lettre idu premier argument de ligne de commande, soustrayez ASCII A= 65 de celui - ci pour donner un indice, et le chercher dans la table T: t[x[1][i]-65].

La forboucle est utilisée plus comme une whileboucle: la boucle se termine lorsqu'un zéro octet (terminateur de chaîne) est rencontré dans la chaîne d'entrée.

Si les tuiles de cette lettre ne sont pas épuisées ( T/10est non nulle) sest incrémentée par le score des tuiles T%10+1pour garder un score total. En même temps, le score de tuile est stocké dans r, de sorte que la valeur dans le représenté par Tpuisse être décrémentée par r*10pour indiquer qu'une tuile a été utilisée. Si les tuiles sont épuisées, le compteur générique / vierge best incrémenté.

La printfdéclaration est assez explicite. si la longueur de mot est hors limites ou si le nombre de blancs est trop élevé, imprimez Invalidsinon imprimez la partition s.

Level River St
la source
Comme c'est maintenant un autre jour, vous pouvez enregistrer un caractère en remplaçant r + = (r == 7) * 3 par r + = r-7? 0: 3. De plus, vous n'avez pas besoin des parenthèses autour de T- = r * 9, s + = r.
Alchymist
@Alchymist Merci pour l'astuce sur les crochets, j'oublie toujours qu'il n'y a aucun problème avec la priorité de l'opérateur entre ?et :. Votre autre point est dépassé, car j'ai complètement changé l'encodage, il n'est donc pas nécessaire de manipuler spécialement Q et Z. Maintenant, descendez à 173/172 avec votre aide.
Level River St
1
avec getchar()c'est 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);}bien que je ne comprenne toujours pas pourquoi les char*foo=<string>plantages. cela pourrait économiser 2 caractères.
bebe
1
@bebe char*foo="string"est un littéral de chaîne et son contenu ne peut pas être modifié. D'un autre côté, char foo[]="string"crée un tableau de caractères initialisé à string\0, qui peut ensuite être modifié.
es1024
@bebe cool, j'ai raté l'idée d'utiliser getchar().J'ai utilisé vos améliorations du code (avec mes noms de variables pour la cohérence avec le reste de ma réponse), plus une amélioration de la vérification de la validité de la longueur des mots et une amélioration effrontée de l'état de la boucle test (j'ai essayé de raccourcir le vôtre mais je n'ai pas pu le faire avec la même fonctionnalité.) J'ai également essayé getche()et getch()mais mon compilateur (gcc sur cygwin) ne les relierait pas automatiquement.
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)}

Modifier - a changé la façon dont j'ai codé les quantités / scores pour réduire la taille et supprimer les variables non ascii

Édition 2 - a changé les encodages quantité / score en entiers au lieu de chaînes

Édition 3 - basculé vers %13(merci @ edc65), inversé l'encodage, modifié directement les valeurs et quelques autres améliorations mineures

Testé dans la console Firefox.

Alconja
la source
1
+1 très intelligent. Suggestions: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2.pourquoi ne pas utiliser% 13
edc65
1
192 f = s => {pour (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; alert (i <3 | i> 16 | $ <0? "Invalid": t)}
edc65
@ edc65 - Merci des tas. Je n'avais pas vu ce premier truc, mais je n'ai pas fini par l'utiliser, car je modifie directement les valeurs maintenant (le classant mentalement pour le futur golf). %13est cependant un coup de génie. Je suis resté coincé en pensant que je devais stocker les choses en chiffres, mais les mathématiques ne se soucient pas de la différence entre base10 et base13.
Alconja
Agréable! (Ne fonctionne pas dans la console de Chrome, BTW SyntaxError: Unexpected token >
:.
@DLosc - Oui, je pense que Firefox est actuellement le seul navigateur qui prend en charge tous les éléments ECMAScript 6 (Chrome n'aime pas la f=s=>{...}notation).
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])

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

Edit: Merci à @BeetDemGuise pour un conseil qui m'a finalement conduit à bien plus qu'une réduction à 1 caractère! Code d'origine ci-dessous:

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
la source
C'est assez minime mais vous pouvez économiser 1 octet en encodant votre chaîne de scores en hexadécimal: int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise
4

BEFUNGE 93 - 210 octets.

Mais il ne vérifie pas la limite de 15 lettres.

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
la source
4

C, 197

Suppose que la chaîne est fournie comme argument de ligne de commande, par exemple ./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 délicat
la source
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)

zstocke le mot. Sorties comme alerte.

Modifier: amélioré selon les recommandations ci-dessous.

Mat
la source
2
sn'est utilisé qu'une seule fois, vous n'avez donc pas du tout besoin d'en faire une variable; vous pouvez supprimer cette déclaration et la remplacer r+=s[x]par r+=-~"02210313074020029000033739"[x]. De plus, vous n'avez pas besoin de parenthèses (w>2|y<2|y>15)dans l'alerte.
NinjaBearMonkey
4

Haskell - 538

Enregistrez-le sous scrabble.hs, puis compilez-le en utilisant

ghc --make scrabble && ./scrabble

Saisissez ensuite votre mot comme entrée et appuyez sur Entrée

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
la source
Vous pouvez supprimer beaucoup d'espaces et dans Haskell `['A', 'B', 'C'] ==" ABC ". Vous pouvez également utiliser un seul espace pour chaque niveau de retrait. Et vous pouvez utiliser des noms plus courts. Il y a beaucoup pour le golf.
Ray
@Ray Cela fait, je suis nouveau chez Haskell, existe-t-il un moyen de représenter les listes d'Ints de manière plus concise que [1,2,3]?
Tuomas Laakkonen
"ABCDEFG"peut être écrit comme ['A'..'G'], [1,2,3]peut être écrit comme[1..3]
Ray
Comment obtenez-vous votre nombre d'octets? wc me donne plus de 500 caractères pour votre code.
TheSpanishInquisition du
@TheSpanishInquisition Je viens de recevoir une mise à jour pour mon extension de décompte de mots st3, l'auteur a échangé les deux décomptes accidentellement, mis à 538
Tuomas Laakkonen
3

Python 2.7 - 263

Je ne pouvais pas me rapprocher de la réponse de DLosc , mais cela traite chaque lettre comme un `` sac '' dont vous tirez, jusqu'à ce qu'elle soit vide, puis vous tirez des blancs, et quand cela est vide, cela provoque des erreurs.

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"
Communauté
la source
1
C'est une approche soignée! Vous avez besoin raw_inputsi c'est Python2 (une chose que j'aime à propos de Python3). L'entrée est garantie en majuscules, donc supprimez .lower()et changez 97+ien 65+i. La saisie de moins de 2 caractères doit également être invalide. Vous pouvez augmenter l'erreur de division zéro sans ifdéclaration: divisez votre score total par (1<len(S)<16). Quelques autres ajustements, comme mettre le prints sur la même ligne que les en-têtes de bloc et supprimer l'espace avant, le "Invalid"ramènent à 250 par mon compte. :)
DLosc
2

Haskell, 290 283

Aussi loin que j'ai pu le faire pour l'instant:

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

Ce code respecte très strictement les règles, alors assurez-vous de ne lui transmettre aucun caractère supplémentaire (comme la fin de ligne). Utilisez comme ceci: echo -n "JAZZ" | runghc scrabble.hs.

Explication

Le motif (_:_:_)s'assure que seules les chaînes d'au moins deux caractères sont prises en compte, tout le reste résulte en "Invalid"(motif de secours _). La table des tuiles est codée comme 11*nTiles+valueconvertie en ASCII avec un décalage qui permet à la recherche modulo 11 de fonctionner, où les lettres AEIOsont dupliquées car elles se produisent plus de 6 fois chacune. Le pool de tuiles est ensuite créé en utilisant replicate, duquel les caractères du mot sont supprimés au fur et à mesure (différence de liste,\\). Le pool contient 98 tuiles, donc si la longueur totale du mot et la partie restante du pool est supérieure à 100, alors nous avons utilisé trop de caractères génériques. De plus, le mot moins les 15 premières lettres est ajouté trois fois au calcul de la longueur, donc tout mot de plus de 15 lettres semble utiliser automatiquement trois caractères génériques et n'est donc pas valide. Le score est fait sur le pool restant, qui comptait initialement 187 points, dont nous soustrayons simplement. Notez le f 61plutôt quef 65, 65 étant le numéro ASCII de 'A', en raison du doublon "AEIO"au début du pool. Le reste est juste passe-partout.

TheSpanishInquisition
la source
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)])

Mettons les bignums à utiliser: D (il ne gère pas les caractères génériques actuellement, j'ai complètement ignoré la lecture de cette règle, putain)

LemonBoy
la source
1

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

Je suppose que la sortie de "Invalid"est correcte, sinon je devrais faire ce $><<(-b<1&&w.size<16?s:'Invalid')qui la ferait monter à 198


Clojure - 325

Je n'ai pas fait de clojure depuis un moment donc je suis sûr qu'il existe plusieurs façons d'améliorer ma solution .ie les listes de quantité et de points

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

Certains ce qui n'a pas été joué au 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
la source
1

ES6: 184 (non strict)

west supposé contenir déjà le mot. rest la chaîne de sortie.

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"

Voici cela expliqué et un peu moins golfé:

// 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
la source
1

Fléchette - 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");}

Cela nécessite des bignums, donc il ne sera pas compilé en JavaScript.
Avec plus d'espace:

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
la source
0

PHP, 180 170 168 octets

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! battre JS!

panne

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

Je suis tellement content qu'aucun score de lettre ne soit supérieur à 10.

Titus
la source