[Question]
  [
Your task is to determine if a given string is of proper length and can be represented with Scrabble tiles and, if so, output the sum of each letter's score.
If you don't know how to play Scrabble:, you have 100 tiles with various letters A–Z printed on them, as well as two wildcards that can represent any letter. Each letter has a certain number of points, and each tile (but not necessarily word) can only be used once. When a word is played, the point value of each tile used is added up, which becomes the score. As there are a limited number of letters available, a word can only have a certain letter as many times as that letter has tiles + any unused wildcards. The Scrabble board is 15×15 cells, so the word must be between 2 and 15 characters long.
For a list of the quantity and score of each letter in the English version, see below or <http://boardgames.about.com/od/scrabble/a/tile_distribute.htm> ([archive](http://web.archive.org/web/20140412222004/http://boardgames.about.com/od/scrabble/a/tile_distribute.htm)).
```
Letter  Qty  Points        Letter  Qty  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             [wild]  2    0
N       6    1
```
## Further rules
* The program shall take a single string of input from STDIN or the like.
* The input will always contain only uppercase letters.
* If the string contains more copies of a letter than there are unused wildcards or tiles for that letter OR the string's length is not between 2 and 15 inclusive, the program should output `Invalid`.
* Otherwise, the score should be added up with using data from the chart above and output.
* Do not use wildcards unless necessary.
* Do not worry about bonuses such as double word scores or whether the string is a real word.
* The program shall output the result through STDOUT or the like.
* [Loopholes that are forbidden by default](https://codegolf.meta.stackexchange.com/q/1061/29750) are not allowed.
* Using an external source such as a website, as well as any libraries, APIs, functions, or the like that calculate Scrabble scores or proper quantities are not alllowed.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so fewest bytes wins.
## Walkthrough
```
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
```
## Testcases
```
Input             Output
------------------------
SCRABBLE          14
JAZZ              19
STACKEXCHANGE     32
XYWFHQYVZVJKHFW   81
PIZZAZZ           Invalid
KIXOKEJAJAX       Invalid
MISUNDERSTANDING  Invalid
```
  
[Answer]
# Perl 5 ~~228 205 186 184 178 177 153 150 149 142 137~~ 135
Run with perl -E.
Golfed:
```
$_=<>;@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
```
This solution uses some non-printable characters, so a hexdump is provided below:
```
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
```
Alternatively, using 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+commented:
```
# 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
```
[Answer]
# C, Rev 2, ~~151 145~~ 138
Inspired by the 159-byte code in @bebe's comment, I squeezed another ~~8 14~~ 21 characters out:
4 bytes saved by rearranging the length counter `i`. This is initialised to 1 (assuming the program takes no arguments) then multiplied by 4 every time a letter is read. It overflows to zero when the word length is greater than 15, so to check if the word length is bad, we simply check if `i<5` (I put `i<9` so it will still give invalid for one-letter words if the user accidentally intialises `i` to 2 by putting a single argument on the command line.)
4 bytes saved by changing the loop condition test to a simple `&31`. This requires that the word is terminated with a space (ASCII 32) or a null character (ASCII 0.) Normally keyboard input is terminated by a newline (ASCII 10) so the program's a bit inconvenient to use, because you have to type the space then press return as well to get the computer to read the buffer. For newline-terminated strings, I could match but not beat the way bebe does it. 
 ~~6~~ 13 bytes saved by changing the encoding to **-(number of tiles of each letter)-(score for that letter-1)\*13**. This now requires a range from -4 for L,S,U to -118 for Q,Z. The reason for using negative numbers is to avoid the unprintable ASCII range 0 to 31. Instead the range used is the two's complement of the negative numbers 256-4=252 to 256-118=138. These are printable, extended ASCII characters. There are issues with copying and pasting these in Unicode (the way it simplifies back to ASCII depends on the code page installed which can lead to unpredictable results) so I have included the correct ASCII codes in the program comment. 
The advantage of this encoding is the elimination of the variable `r` as the number of tiles is always reduced by 1 (as it is stored as a negative number, we do `t[x]++`. Additionally, the postfix operator means we can perform this increment at the same time as adding the score to `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 (or 172 with compiler option)
I'm using GCC, and with the compiler option `-std=c99` it will allow me to move `char t[]="...."` into the initialization of the `for` loop for a saving of one additional semicolon. For readability, I have shown the program without this change, and with whitespace left in.
```
#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);
}
```
The trick is in the datatable. For each letter an ASCII code of the form **(total score of tiles for that letter)\*10+(score of one tile-1)** is stored in the table `t[]`. At runtime, these total scores are reduced as tiles are used up.
The total score of all the tiles for each letter ranges from 12 for E down to 4 for L,S,U. This form of encoding enables only printable ASCII characters to be used (ASCII 120,`x` for E down to ASCII 40,`(` for L,S,U.) Using the *number* of tiles would need a range from 120 down to 10, which is why I avoided it. 
Thanks to a `#define` macro, a single symbol `T` is used in the main program to retrieve the letter index `i`from the first commandline argument, subtract ASCII `A`=65 from it to give an index ,and look it up in the table T: `t[x[1][i]-65]`.
The `for` loop is used more like a `while` loop: the loop ends when a zero byte (string terminator) is encountered in the input string. 
If the tiles of that letter are not exhausted (`T/10` is nonzero) `s` is incremented by the tile score `T%10+1` to keep a total score. At the same time the tile score is stored in `r`, so that the value in the able represented by `T` can be decremented by `r*10` to indicate that one tile has been used. If the tiles are exhausted, the wildcard/blank counter `b` is incremented.
The `printf` statement is fairly self-explanatory. if the wordlength is out of bounds or the blank count is too high, print `Invalid` otherwise print the score `s`.
[Answer]
# 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)}
```
*Edit* - changed the way I encoded the quantities/scores to reduce size and remove non-ascii variables
*Edit 2* - changed the quantity/score encodings to integers instead of strings
*Edit 3* - switched to `%13` (thanks @edc65), inverted the encoding, modified the values directly, and a few other minor improvements
Tested in Firefox console.
[Answer]
# 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:** Thanks to @BeetDemGuise for a tip that ultimately led me to much more than a 1-character reduction! Original code below:
```
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])
```
[Answer]
# BEFUNGE 93 - 210 bytes.
But it doesn't check the 15 letter limit.
```
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<        @,,,,,,,<
                  
```
[Answer]
# C, 197
Assumes the string is provided as a command line argument, e.g. `./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);}
```
[Answer]
# 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)
```
`z` stores word. Outputs as alert.
*Edit:* improved as per recommendations below.
[Answer]
# Haskell - 538
Save it as scrabble.hs and then compile it using
```
ghc --make scrabble && ./scrabble
```
Then enter your word as input and press 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"
```
[Answer]
# Python 2.7 - 263
I couldn't come anywhere close to [DLosc's answer](https://codegolf.stackexchange.com/a/35792/8777), but this treats each letter as a 'bag' that you pull from, until its empty, then you pull blanks, and when that is empty it errors.
```
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"
```
[Answer]
# Haskell, ~~290~~ 283
As far down as I could make it for now:
```
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
```
This code abides by the rules very strictly, so make sure you don't pass it any extra characters (such as end-of-line). Use like this: `echo -n "JAZZ" | runghc scrabble.hs`.
## Explanation
The pattern `(_:_:_)` makes sure that only strings of at least two characters are considered, everything else results in `"Invalid"` (fallback pattern `_`). The table of tiles is encoded as `11*nTiles+value` converted to ASCII with an offset that allows the lookup modulo 11 to work, where the letters `AEIO` are duplicated because they occur more than 6 times each. The pool of tiles is then created using `replicate`, from which the characters in the word are removed as they occur (list difference, `\\`). The pool contains 98 tiles, so if the total length of the word and the remaining part of the pool is larger then 100, then we have used too many wildcards. Also, the word minus the first 15 letters is added three times to the length computation so any word longer than 15 letters automatically appears to use up three wildcards and therefore is invalid. Scoring is done on the remaining pool, which initially had 187 points, which we simply subtract from. Note the `f 61` rather than `f 65`, 65 being the ASCII number of `'A'`, because of the duplicate `"AEIO"` at the beginning of the pool. The rest is just boilerplate.
[Answer]
## 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)])
```
Let's put the bignums to use :D
(It doesn't handle wildcards currently, I've skipped reading that rule entirely, damn)
[Answer]
# 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')
```
I'm assuming the output of `"Invalid"` is fine, if not I would need to do `$><<(-b<1&&w.size<16?s:'Invalid')` which would bump it up to 198
  
# Clojure - 325
I haven't done clojure in a while so I'm sure there are several ways to improve my solution .ie the qty and pts lists
```
(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))))))
```
Some what 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)))
```
[Answer]
# ES6: 184 (non-strict)
`w` is assumed to already contain the word. `r` is the output string.
```
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"
```
Here's it explained and a little less golfed:
```
// 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.
```
[Answer]
## 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");}
```
This requires bignums, so it won't compile to JavaScript.  
With more whitespace:
```
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");
}
```
[Answer]
# 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! beating JS!
**breakdown**
```
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
```
I´m so glad there is no letter score larger than 10.
]