Tentukan skor dan validitas Scrabble string

24

Tugas Anda adalah menentukan apakah string yang diberikan memiliki panjang yang sesuai dan dapat diwakili dengan ubin Scrabble dan, jika demikian, output jumlah skor setiap huruf.

Jika Anda tidak tahu cara bermain Scrabble :, Anda memiliki 100 ubin dengan berbagai huruf A – Z yang tercetak di atasnya, serta dua wildcard yang dapat mewakili huruf apa pun. Setiap huruf memiliki jumlah poin tertentu, dan setiap ubin (tetapi tidak harus kata) hanya dapat digunakan satu kali. Ketika sebuah kata dimainkan, nilai poin dari setiap ubin yang digunakan ditambahkan, yang menjadi skor. Karena jumlah surat yang tersedia terbatas, sebuah kata hanya dapat memiliki huruf tertentu sebanyak surat itu memiliki ubin + setiap wildcard yang tidak digunakan. Papan Scrabble berukuran 15 × 15 sel, jadi kata itu harus antara 2 dan 15 karakter.

Untuk daftar jumlah dan skor setiap huruf dalam versi bahasa Inggris, lihat di bawah atau http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( arsip ).

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 [liar] 2 0
N 6 1

Aturan lebih lanjut

  • Program harus mengambil satu string input dari STDIN atau sejenisnya.
  • Masukan akan selalu hanya berisi huruf besar.
  • Jika string berisi lebih banyak salinan surat daripada ada wildcard atau ubin yang tidak digunakan untuk surat itu ATAU panjang string tidak antara 2 dan 15 inklusif, program harus menampilkan Invalid.
  • Jika tidak, skor harus ditambahkan dengan menggunakan data dari bagan di atas dan output.
  • Jangan gunakan wildcard kecuali jika diperlukan.
  • Jangan khawatir tentang bonus seperti skor kata ganda atau apakah string itu kata yang nyata.
  • Program harus menampilkan hasilnya melalui STDOUT atau sejenisnya.
  • Celah yang dilarang secara default tidak diizinkan.
  • Menggunakan sumber eksternal seperti situs web, serta perpustakaan, API, fungsi, atau sejenisnya apa pun yang menghitung skor Scrabble atau jumlah yang tepat tidak diizinkan.
  • Ini adalah , byte paling sedikit menang.

Panduan

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
------------------------
GELOMBANG 14
JAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ Tidak Valid
KIXOKEJAJAX Tidak Valid
MISUNDERSTANDING Tidak Valid
NinjaBearMonkey
sumber
5
Mungkin ingin menambahkan kasus uji untuk kata yang valid yang menggunakan kartu liar (mis. JAZZ = 19, bukan 29)
Alconja
2
Anda tahu, tantangan ini akan jauh lebih jahat jika melibatkan bahasa yang ubin Scrabble tidak dapat diwakili dengan satu karakter, seperti Spanyol, Basque, Hongaria, Tuvan atau Welsh.
user0721090601
Apakah jawaban yang diperlukan secara khusus untuk menghasilkan "Tidak Valid", atau bolehkah kita memilih perilaku apa pun asalkan itu jelas bukan skor? Misalnya -1,?
Kamil Drakari
@ KamilDrakari Ini harus mengatakan dengan tepat Invalid.
NinjaBearMonkey

Jawaban:

15

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

Jalankan dengan 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

Solusi ini menggunakan beberapa karakter yang tidak dapat dicetak, jadi hexdump disediakan di bawah ini:

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

Atau, gunakan 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 + berkomentar:

# 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
sumber
1
Anda dapat memeras setidaknya 20 byte dari array tersebut dengan beberapa manipulasi kreatif
Sparr
1
Gah, selalu selangkah di depanku. :) Punya upvote.
Alconja
Ini menarik, skor kami sangat dekat. +1.
Level River St
Apakah ini berfungsi dengan -M5.010(penalti 0 karena ini menentukan versi bahasa yang akan digunakan) daripada -e(penalti 1)? Anda mungkin bisa menyimpan byte dalam argumen.
13

C, Why 2, 151 145 138

Terinspirasi oleh kode 159-byte dalam komentar @ bebe, saya memeras 8 14 21 karakter lainnya:

4 byte disimpan dengan mengatur ulang penghitung panjang i. Ini diinisialisasi ke 1 (dengan asumsi program tidak mengambil argumen) kemudian dikalikan dengan 4 setiap kali surat dibaca. Itu meluap ke nol ketika panjang kata lebih besar dari 15, jadi untuk memeriksa apakah panjang kata itu buruk, kita cukup memeriksa apakah i<5(saya taruh i<9jadi itu akan tetap memberikan kata-kata satu huruf yang tidak valid jika pengguna secara tidak sengaja memulai pembicaraan ike 2 dengan meletakkan satu argumen di baris perintah.)

4 byte disimpan dengan mengubah tes kondisi loop menjadi sederhana &31. Ini mengharuskan kata diakhiri dengan spasi (ASCII 32) atau karakter nol (ASCII 0.) Biasanya input keyboard diakhiri oleh baris baru (ASCII 10) sehingga program agak tidak nyaman untuk digunakan, karena Anda harus mengetikkan spasi kemudian tekan kembali juga untuk membuat komputer membaca buffer. Untuk string yang diakhiri baris baru, saya dapat mencocokkan tetapi tidak mengalahkan cara bebe melakukannya.

6 13 byte disimpan dengan mengubah encoding ke - (jumlah ubin dari setiap huruf) - (skor untuk huruf-1) * 13 . Sekarang ini membutuhkan rentang dari -4 untuk L, S, U hingga -118 untuk Q, Z. Alasan menggunakan angka negatif adalah untuk menghindari rentang ASCII yang tidak dapat dicetak 0 hingga 31. Alih-alih rentang yang digunakan adalah komplemen dua angka negatif 256-4 = 252 hingga 256-118 = 138. Ini adalah karakter ASCII yang dapat dicetak dan diperluas. Ada masalah dengan menyalin dan menempel ini di Unicode (cara menyederhanakan kembali ke ASCII tergantung pada halaman kode yang diinstal yang dapat menyebabkan hasil yang tidak terduga) jadi saya telah memasukkan kode ASCII yang benar dalam komentar program.

Keuntungan dari pengkodean ini adalah penghapusan variabel rkarena jumlah ubin selalu dikurangi dengan 1 (karena disimpan sebagai angka negatif, kita lakukan t[x]++. Selain itu, operator postfix berarti kita dapat melakukan kenaikan ini pada saat yang sama dengan menambahkan skor ke 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 (atau 172 dengan opsi kompiler)

Saya menggunakan GCC, dan dengan opsi kompiler -std=c99itu akan memungkinkan saya untuk pindah char t[]="...."ke inisialisasi forloop untuk menghemat satu titik koma tambahan. Untuk keterbacaan, saya telah menunjukkan program tanpa perubahan ini, dan dengan spasi tersisa.

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

Caranya ada di datatable. Untuk setiap huruf kode ASCII dari formulir (skor total ubin untuk huruf itu) * 10 + (skor satu ubin-1) disimpan dalam tabel t[]. Saat runtime, skor total ini dikurangi karena ubin digunakan.

Skor total semua ubin untuk setiap huruf berkisar dari 12 untuk E hingga 4 untuk L, S, U. Bentuk pengodean ini memungkinkan hanya karakter ASCII yang dapat dicetak untuk digunakan (ASCII 120, xuntuk E turun ke ASCII 40, (untuk L, S, U.) Menggunakan jumlah ubin akan membutuhkan kisaran dari 120 hingga 10, itulah sebabnya saya menghindarinya.

Berkat #definemakro, satu simbol Tyang digunakan dalam program utama untuk mengambil indeks surat idari argumen pertama commandline, ASCII kurangi A= 65 dari itu untuk memberikan indeks, dan mencarinya di meja T: t[x[1][i]-65].

The forloop digunakan lebih seperti whilelingkaran: loop berakhir ketika nol byte (string terminator) ditemui dalam string masukan.

Jika ubin surat itu tidak habis ( T/10bukan nol) sditambahkan oleh skor ubin T%10+1untuk menjaga skor total. Pada saat yang sama skor petak disimpan r, sehingga nilai dalam dapat diwakili oleh Tdapat dikurangi dengan r*10untuk menunjukkan bahwa satu petak telah digunakan. Jika ubin habis, penghitung wildcard / blank bbertambah.

The printfPernyataan ini cukup jelas. jika panjang kata di luar batas atau jumlah kosong terlalu tinggi, cetak Invalidjika tidak cetak skor s.

Level River St
sumber
Karena sekarang adalah hari lain, Anda dapat menyimpan satu karakter dengan mengganti r + = (r == 7) * 3 dengan r + = r-7? 0: 3. Anda juga tidak memerlukan kurung bulat T- = r * 9, s + = r.
Alchymist
@Alymymist Terima kasih atas tipnya tentang kurung, saya selalu lupa tidak ada masalah dengan prioritas operator antara ?dan :. Poin Anda yang lain digantikan, karena saya telah sepenuhnya mengubah pengkodean sehingga tidak perlu untuk penanganan khusus dari Q dan Z. Sekarang ke 173/172 dengan bantuan Anda.
Level River St
1
dengan getchar()159 ini: 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);}meskipun saya masih belum mengerti mengapa char*foo=<string>crash. itu bisa menghemat 2 karakter.
bebe
1
@bebe char*foo="string"adalah string literal, dan kontennya tidak diizinkan untuk dimodifikasi. Di sisi lain, char foo[]="string"membuat array karakter yang diinisialisasi string\0, yang kemudian dapat dimodifikasi.
es1024
@ Bebe keren, saya melewatkan ide menggunakan getchar().Saya telah menggunakan perbaikan Anda untuk kode (dengan nama variabel saya untuk konsistensi dengan sisa jawaban saya), ditambah perbaikan untuk pemeriksaan validitas kata-panjang, dan perbaikan kurang ajar untuk kondisi loop test (Saya mencoba memperpendek milik Anda tetapi tidak dapat melakukannya dengan fungsi yang sama.) Saya juga mencoba getche()dan getch()tetapi kompiler saya (gcc di cygwin) tidak akan menautkannya secara otomatis.
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)}

Sunting - mengubah cara saya menyandikan jumlah / skor untuk mengurangi ukuran dan menghapus variabel non-ascii

Sunting 2 - mengubah pengkodean kuantitas / skor menjadi bilangan bulat, bukan string

Sunting 3 - beralih ke %13(terima kasih @ edc65), membalikkan penyandian, mengubah nilai secara langsung, dan beberapa perbaikan kecil lainnya

Diuji di konsol Firefox.

Alconja
sumber
1
+1 sangat pintar. Saran: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2.mengapa tidak menggunakan% 13
edc65
1
192 f = s => {untuk (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; lansiran (i <3 | i> 16 | $ <0? "Tidak valid": t)}
edc65
@ edc65 - Terima kasih banyak. Belum pernah melihat trik pertama itu, tetapi akhirnya tidak menggunakannya karena saya langsung memodifikasi nilai sekarang (secara mental menyimpannya untuk golf masa depan). %13adalah jenius sekalipun. Saya terjebak berpikir saya harus menyimpan barang-barang dalam angka, tetapi matematika tidak peduli tentang perbedaan antara base10 dan base13.
Alconja
Bagus! (Tidak berfungsi di konsol Chrome, BTW:. SyntaxError: Unexpected token >)
DLosc
@Dosc - Ya, saya pikir Firefox adalah satu-satunya browser saat ini yang mendukung semua hal ECMAScript 6 (Chrome tidak suka f=s=>{...}notasi).
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])

Tidak Disatukan:

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

Sunting: Berkat @BeetDemGuise untuk tip yang akhirnya membuat saya lebih dari sekadar pengurangan 1 karakter! Kode asli di bawah ini:

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
sumber
Cukup minim tetapi Anda dapat menyimpan 1byte dengan menyandikan string skor Anda dalam hex: int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise
4

BEFUNGE 93 - 210 bytes.

Tapi itu tidak memeriksa batas 15 huruf.

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
sumber
4

C, 197

Mengasumsikan string diberikan sebagai argumen baris perintah, misalnya ./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);}
osifrque melengking
sumber
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)

zmenyimpan kata. Keluaran sebagai peringatan.

Sunting: ditingkatkan sesuai rekomendasi di bawah ini.

Mat
sumber
2
shanya digunakan sekali, jadi Anda tidak perlu menjadikannya variabel sama sekali; Anda dapat menghapus deklarasi itu dan menggantinya r+=s[x]dengan r+=-~"02210313074020029000033739"[x]. Selain itu, Anda tidak perlu tanda kurung (w>2|y<2|y>15)di peringatan.
NinjaBearMonkey
4

Haskell - 538

Simpan sebagai scrabble.hs dan kemudian kompilasi menggunakan

ghc --make scrabble && ./scrabble

Kemudian masukkan kata Anda sebagai input dan tekan 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
sumber
Anda dapat menghapus banyak spasi dan di Haskell `['A', 'B', 'C'] ==" ABC ". Anda juga dapat menggunakan hanya satu ruang untuk setiap tingkat indentasi. Dan Anda dapat menggunakan nama yang lebih pendek. Ada banyak golf.
Ray
@ Ray Sudah melakukan itu, saya baru di Haskell, adakah cara untuk merepresentasikan daftar Ints dengan lebih ringkas daripada [1,2,3]?
Tuomas Laakkonen
"ABCDEFG"dapat ditulis sebagai ['A'..'G'], [1,2,3]dapat ditulis sebagai[1..3]
Ray
Bagaimana Anda mendapatkan jumlah byte Anda? wc memberi saya lebih dari 500 karakter untuk kode Anda.
TheSpanishInquisition
@TheSpanishInquisition Baru saja mendapat pembaruan untuk ekstensi jumlah kata st3 saya, penulis telah menukar dua hitungan secara tidak sengaja, diedit ke 538
Tuomas Laakkonen
3

Python 2.7 - 263

Saya tidak bisa mendekati jawaban DLosc , tetapi ini memperlakukan setiap huruf sebagai 'tas' yang Anda tarik, sampai kosong, lalu Anda tarik kosong, dan ketika itu kosong kesalahannya.

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"
Komunitas
sumber
1
Ini pendekatan yang rapi! Anda perlu raw_inputjika itu Python2 (satu hal yang saya sukai tentang Python3). Input dijamin huruf besar, jadi hapus .lower()dan ubah 97+imenjadi 65+i. Masukan kurang dari 2 karakter juga harus tidak valid. Anda dapat meningkatkan kesalahan pembagian nol tanpa ifpernyataan: bagi skor total Anda dengan (1<len(S)<16). Beberapa tweak lain seperti meletakkan prints pada baris yang sama dengan header blok dan menghapus ruang sebelum "Invalid"membawanya ke 250 menurut hitungan saya. :)
DLosc
2

Haskell, 290 283

Sejauh yang saya bisa lakukan untuk saat ini:

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

Kode ini mematuhi aturan dengan sangat ketat, jadi pastikan Anda tidak memberikan karakter tambahan (seperti end-of-line). Gunakan seperti ini: echo -n "JAZZ" | runghc scrabble.hs.

Penjelasan

Pola (_:_:_)memastikan bahwa hanya string setidaknya dua karakter dipertimbangkan, semuanya menghasilkan "Invalid"(pola mundur _). Tabel ubin dikodekan sebagai 11*nTiles+valuedikonversi ke ASCII dengan offset yang memungkinkan modulo 11 lookup bekerja, di mana huruf AEIO- huruf diduplikasi karena mereka terjadi lebih dari 6 kali masing-masing. Kumpulan ubin kemudian dibuat menggunakan replicate, dari mana karakter dalam kata tersebut dihapus saat terjadi (daftar perbedaan,\\). Kolam berisi 98 ubin, jadi jika panjang total kata dan bagian yang tersisa dari kolam lebih besar dari 100, maka kami telah menggunakan terlalu banyak wildcard. Juga, kata minus 15 huruf pertama ditambahkan tiga kali ke dalam perhitungan panjang sehingga kata yang lebih dari 15 huruf secara otomatis tampaknya menggunakan tiga wildcard dan karenanya tidak valid. Penilaian dilakukan pada kelompok yang tersisa, yang awalnya memiliki 187 poin, yang kami kurangi. Perhatikan bahwa f 61alih - alihf 65, 65 menjadi nomor ASCII 'A', karena duplikat "AEIO"di awal kolam. Sisanya hanya boilerplate.

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

Mari kita gunakan bignum untuk digunakan: D (Ini tidak menangani wildcard saat ini, saya telah melewatkan membaca aturan itu sepenuhnya, sialan)

LemonBoy
sumber
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')

Saya mengasumsikan output "Invalid"baik-baik saja, jika tidak saya perlu melakukan $><<(-b<1&&w.size<16?s:'Invalid')yang akan menabraknya hingga 198


Clojure - 325

Saya belum melakukan clojure dalam beberapa saat jadi saya yakin ada beberapa cara untuk meningkatkan solusi saya. Yaitu daftar qty dan 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))))))

Beberapa yang tidak 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
sumber
1

ES6: 184 (tidak ketat)

wDiasumsikan sudah mengandung kata. radalah string output.

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"

Ini dijelaskan dan sedikit kurang 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
sumber
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");}

Ini membutuhkan bignum, sehingga tidak dapat dikompilasi dengan JavaScript.
Dengan lebih banyak ruang putih:

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

PHP, 180 170 168 byte

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

kerusakan

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

Saya sangat senang tidak ada skor surat lebih besar dari 10.

Titus
sumber