文字列のスクラブルスコアと有効性を決定する


24

あなたの仕事は、与えられた文字列が適切な長さであり、スクラブルタイルで表現できるかどうかを判断し、そうであれば、各文字のスコアの合計を出力することです。

Scrabble:のプレイ方法がわからない場合は、A〜Zのさまざまな文字が印刷された100個のタイルと、任意の文字を表す2つのワイルドカードがあります。各文字には一定数のポイントがあり、各タイル(必ずしも単語ではない)は1回しか使用できません。単語が再生されると、使用される各タイルのポイント値が合計され、それがスコアになります。限られた数の文字が利用可能であるため、単語に特定の文字を含めることができるのは、その文字にタイル+未使用のワイルドカードが含まれている場合だけです。スクラブルボードは15×15セルなので、単語は2〜15文字でなければなりません。

英語版での各文字の量とスコアのリストについては、下記を参照してくださいまたはhttp://boardgames.about.com/od/scrabble/a/tile_distribute.htmアーカイブ)。

手紙の数量ポイント手紙の数量ポイント
------------------- -------------------
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 [ワイルド] 2 0
N 6 1

さらなるルール

  • プログラムは、STDINなどから単一の入力文字列を取得します。
  • 入力には常に大文字のみが含まれます。
  • 文字列にその文字の未使用のワイルドカードまたはタイルよりも多くの文字のコピーが含まれている場合、または文字列の長さが2〜15の範囲にない場合、プログラムはを出力しますInvalid
  • それ以外の場合は、上記のチャートのデータを使用してスコアを加算し、出力する必要があります。
  • 必要でない限り、ワイルドカードを使用しないでください。
  • ダブルワードスコアなどのボーナスや、文字列が実際の単語であるかどうかは心配しないでください。
  • プログラムは、STDOUTなどを介して結果を出力します。
  • デフォルトで禁止されている抜け穴は許可されていません。
  • Webサイトなどの外部ソース、およびスクラブルスコアまたは適切な数量を計算するライブラリ、API、関数などを使用することは許可されません。
  • これはなので、バイト数が最も少なくなります。

ウォークスルー

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

テストケース

入出力
------------------------
スクラブル14
ジャズ19
スタックエクスチェンジ32
XYWFHQYVZVJKHFW 81
PIZZAZZが無効です
KIXOKEJAJAX無効
誤解無効

5
ワイルドカードを使用する有効な単語のテストケースを追加したい場合があります(たとえば、29ではなくJAZZ = 19)
Alconja 14

2
ご存知のように、スペイン語、バスク語、ハンガリー語、トゥヴァン語、ウェールズ語など、スクラブルタイルを単一の文字で表すことができない言語を使用する場合、この課題は非常に邪魔になります。
user0721090601 14

「無効」を出力するための回答は特に必要ですか、それとも明らかにスコアでない限り、任意の動作を選択できますか?たとえば、-1
カミルドラカリ

@KamilDrakari正確に言う必要がありますInvalid
NinjaBearMonkey

回答:


15

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

perl -Eで実行します。

ゴルフ:

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

このソリューションでは印刷できない文字を使用するため、以下に16進ダンプが提供されています。

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

または、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

1
いくつかの創造的な操作でそれらの配列から少なくとも20バイトを絞ることができます
Sparr 14

1
ああ、いつも私の一歩先を行く。:)賛成票を持っています。
アルコンハ14

これは面白かったし、スコアはずっと近かった。+1。
レベルリバーセント

これ-M5.010は、-e(ペナルティ1)ではなく(使用する言語のバージョンを指定するため、ペナルティ0で)動作しますか?引数に1バイトを保存できる場合があります。

13

C、Rev 2、151 145 138

@bebeのコメントの159バイトのコードに触発されて、私はさらに8 14 21文字を絞り出しました。

長さカウンタを再配置することで4バイトが節約されましたi。これは1に初期化され(プログラムが引数を取らないと仮定)、文字が読み取られるたびに4倍されます。単語の長さが15を超えるとゼロにオーバーフローするため、単語の長さが悪いかどうかを確認するために、単純に次のことを確認しますi<5i<9ユーザーが誤っiてコマンドラインの単一の引数。)

ループ条件のテストを単純な&31。これには、単語をスペース(ASCII 32)またはヌル文字(ASCII 0)で終了する必要があります。通常、キーボード入力は改行(ASCII 10)で終了するため、プログラムを使用するのは少し不便です。スペースを押してからReturnキーを押して、コンピューターにバッファーを読み取らせます。改行で終わる文字列の場合、一致することはできますが、bebeの方法に勝ちません。

6エンコードを-(各文字のタイル数)-(その文字のスコア-1)* 13に変更することにより、13バイトが節約されました。これには、L、S、Uの場合は-4からQ、Zの場合は-118までの範囲が必要です。負の数を使用する理由は、印刷できないASCIIの範囲0〜31を避けるためです。代わりに、使用される範囲は、負の数256-4 = 252〜256-118 = 138の2の補数です。これらは、印刷可能な拡張ASCII文字です。これらをUnicodeでコピーして貼り付けるには問題があります(ASCIIに簡単に戻す方法は、インストールされているコードページによって異なり、予測できない結果が生じる可能性があります)。したがって、プログラムのコメントに正しいASCIIコードを含めました。

このエンコードの利点はr、タイルの数が常に1減るので変数が削除されることです(負の数として格納されるため、そうしますt[x]++。さらに、後置演算子は、この増分を同時に実行できることを意味します。にスコアを追加し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(またはコンパイラオプション付き172)

GCCを使用していますが、コンパイラオプション-std=c99を使用するchar t[]="...."と、forループの初期化に移行して、セミコロンを1つ追加保存できます。読みやすくするために、この変更をせずに、空白を残してプログラムを示しました。

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

秘trickはデータテーブルにあります。各文字について、フォームのASCIIコード(その文字のタイルの合計スコア)* 10 +(1タイルのスコア-1)がテーブルに保存されますt[]。実行時に、これらの合計スコアはタイルが使い果たされるにつれて減少します。

各文字のすべてのタイルの合計スコアは、Eの12からL、S、Uの4までの範囲です。この形式のエンコードでは、印刷可能なASCII文字のみを使用できます(xEの場合はASCII 120、(Lの場合はASCII 40、L、S、Uの場合)。タイルのを使用するには120から10の範囲が必要です。それを避けた。

#defineマクロのおかげTで、メインプログラムで単一のシンボルが使用され、i最初のコマンドライン引数から文字インデックスが取得され、そこからASCII A= 65が減算されてインデックスが得られ、テーブルT:で検索されますt[x[1][i]-65]

forループは、よりように使用されるwhileループ終了ゼロバイト(文字列終端)が入力文字列に遭遇する:ループ。

その文字のタイルが使い果たされていない場合(T/10ゼロ以外)sT%10+1、合計スコアを保持するためにタイルスコアによってインクリメントされます。同時に、タイルスコアはに格納されるrため、で表されるの値は、1つのタイルが使用さTr*10たことを示すために減少できます。タイルが使い果たされると、ワイルドカード/ブランクカウンターbが増加します。

このprintf説明はかなり自明です。語長が範囲外であるか、空白カウントが高すぎるInvalid場合は、スコアを印刷しsます。


現在は別の日なので、r + =(r == 7)* 3をr + = r-7?0:3に置き換えることで1文字を保存できます。また、T- = r * 9、s + = rを丸括弧で囲む必要もありません。
アルキミスト14

ブラケットについての先端のための@Alchymistおかげで、私はいつもの間に演算子の優先順位では問題ありません忘れて?とは:。エンコードを完全に変更したため、QとZを特別に処理する必要がないので、もう1つのポイントが優先されます。
レベルリバーセント14

1
getchar():それは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);}、私はまだ、なぜ得ることはありませんが、char*foo=<string>クラッシュを。2文字節約できます。
ベベ14

1
@bebe char*foo="string"は文字列リテラルであり、その内容は変更できません。一方、にchar foo[]="string"初期化されたcharsの配列を作成し、string\0それを変更できます。
es1024 14

@bebe cool、私はgetchar().あなたのコードの改善(残りの答えとの一貫性のために変数名を使用)に加えて、語長の妥当性チェックの改善、ループ条件の生意気な改善を使用したというアイデアを逃しましたテスト(私はあなたを短縮しようとしたが、同じ機能を持つように行うことができませんでした。)私も試したgetche()し、getch()私のコンパイラ(cygwinの上でgccは)自動的にリンクしないでしょう。
レベルリバーセント14

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

編集 -サイズを減らして非ASCII変数を削除するために数量/スコアをエンコードする方法を変更しました

編集2-数量/スコアエンコーディングを文字列ではなく整数に変更

編集3 - %13(@ edc65に感謝)に切り替え、エンコードを反転し、値を直接変更し、その他いくつかのマイナーな改善

Firefoxコンソールでテスト済み。


1
+1とても賢い。提案:1 .- f[c]=1+f[c]||1> f[c]=-~f[c]、2。%13を使用しない
理由

1
192 f = s => {for(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-ありがとう。その最初のトリックは見ませんでしたが、現在値を直接変更しているため(将来のゴルフのためにメンタルにファイリングするため)、結局使用しませんでした。%13しかし、天才のストロークです。私は物を数字で保存しなければならないと思って立ち往生しましたが、数学はbase10とbase13の違いを気にしません。
アルコンハ14

いいね!(Chromeのコンソールでは動作しません、ところで:SyntaxError: Unexpected token >
DLosc 14

@DLosc-ええ、FirefoxはECMAScript 6のすべてをサポートしている現時点で唯一のブラウザだと思います(Chromeはf=s=>{...}表記が気に入らない)。
アルコンハ14

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

ゴルフをしていない:

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

編集: @BeetDemGuiseのおかげで、最終的に1文字以上の削減につながりました。以下の元のコード:

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

非常に最小限ですが、スコア文字列を16進数でエンコードすることで1バイトを節約できます:int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise 14

4

BEFUNGE 93-210バイト。

ただし、15文字の制限はチェックしません。

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<        @,,,,,,,<

4

C、197

文字列がコマンドライン引数として提供されると仮定します、例えば ./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);}

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)

z単語を保存します。アラートとして出力します。

編集:以下の推奨事項に従って改善されました。


2
sは一度しか使用されないため、変数にする必要はまったくありません。あなたはその宣言を取り外して交換することができますr+=s[x]r+=-~"02210313074020029000033739"[x]。また、(w>2|y<2|y>15)アラートで括弧を使用する必要はありません。
NinjaBearMonkey 14

4

ハスケル-538

scrabble.hsとして保存し、次に使用してコンパイルします

ghc --make scrabble && ./scrabble

次に、単語を入力して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"

多くのスペースを削除できます。Haskellでは、[['A'、 'B'、 'C​​'] == "ABC"です。また、各レベルのインデントに使用できるスペースは1つだけです。また、短い名前を使用できます。ゴルフにはたくさんあります。
レイ14

@Rayそれを行った、私はHaskellに初めて、Intsのリストを[1,2,3]よりも簡潔に表現する方法はありますか?
のTuomas Laakkonen

"ABCDEFG"と書くことができます['A'..'G'][1,2,3]と書くことができます[1..3]
レイ14

バイトカウントはどのように取得しますか?wcを使用すると、500文字以上のコードを取得できます。
TheSpanishInquisition 14

@TheSpanishInquisitionだけでは、著者は、誤って2つのカウントを入れ替え538に編集されていた私のST3ワードカウント拡張のアップデートを得た
のTuomas Laakkonen

3

Python 2.7-263

私はDLoscの答えに近いところに来ることができませんでしたが、これは各文字を「バッグ」として扱い、空になるまで空白を引き出し、空になるとエラーになります。

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"

1
これはきちんとしたアプローチです!raw_inputPython2(Python3で気に入っていることの1つ)であれば必要です。入力は大文字であることが保証されているため、削除.lower()してに変更97+i65+iます。2文字未満の入力も無効にする必要があります。ifステートメントなしでゼロ除算エラーを発生させることができます:合計スコアをで割ります(1<len(S)<16)printブロックヘッダーと同じ行にsを配置し、スペースを削除"Invalid"してからカウントで250に減らすなど、いくつかの調整があります。:)
DLosc 14

2

ハスケル、290 283

今のところできる限り:

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

このコードは規則を非常に厳守しているので、余分な文字(行末など)を渡さないようにしてください。次のように使用しますecho -n "JAZZ" | runghc scrabble.hs

説明

このパターン(_:_:_)は、少なくとも2文字の文字列のみが考慮されるようにし、それ以外はすべて"Invalid"(フォールバックパターン_)になります。タイルのテーブルは11*nTiles+value、11を法とするルックアップが機能するオフセットを使用してASCIIに変換されるようにエンコードされます。文字AEIOはそれぞれ6回以上出現するため複製されます。次にreplicate、を使用してタイルのプールが作成され、そこから単語の文字が削除されます(リストの違い、\\)。プールには98個のタイルが含まれているため、単語とプールの残りの部分の合計の長さが100より大きい場合、ワイルドカードが多すぎます。また、単語から最初の15文字を引いたものが長さの計算に3回追加されるため、15文字を超える単語は自動的に3つのワイルドカードを使用するように見えるため、無効になります。得点は残りのプールで行われます。最初は187ポイントでしたが、そこから単純に差し引きます。プールの先頭に重複があるため、65はASCII番号ではf 61なくに注意してください。残りは単なる定型です。f 65'A'"AEIO"


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

bignumを使用してみましょう:D(現在はワイルドカードを処理していません。このルールを完全に読み飛ばしました。


1

ルビー-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')

の出力"Invalid"は正常であると仮定していますが、そうでない場合は$><<(-b<1&&w.size<16?s:'Invalid')198まで上げる必要があります


クロージュア-325

私はしばらくの間clojureをやったことがないので、私のソリューションを改善するいくつかの方法があると確信しています.ie qtyと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))))))

ゴルフをしていないもの

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

1

ES6:184(非厳密)

w単語が既に含まれていると想定されます。r出力文字列です。

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"

以下に説明しますが、ゴルフは少し少なくなります。

// 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.

1

ダーツ-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");}

これにはbignumが必要なので、JavaScriptにコンパイルされません。
空白を増やす:

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

0

PHP、180 170 168バイト

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;

わーい!JSを破って!

壊す

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

文字スコアが10を超えていないことがとてもうれしいです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.