Bir dizenin Scrabble skorunu ve geçerliliğini belirleme


24

Göreviniz verilen bir dizginin uygun uzunlukta olup olmadığını ve Scrabble döşemeleriyle gösterilip gösterilemeyeceğini belirlemektir ve öyleyse her harfin puanının toplamını verir.

Scrabble oynamayı bilmiyorsanız, üzerlerinde çeşitli A – Z harfleri bulunan 100 taş ve herhangi bir harfi temsil edebilecek iki joker karakteriniz var. Her harfin belirli sayıda noktası vardır ve her bir döşeme (ancak kelimeyi gerektirmeyen) yalnızca bir kez kullanılabilir. Bir kelime çalındığında, kullanılan her döşemenin puan değeri toplanır ve bu puan olur. Sınırlı sayıda harf olduğundan, bir kelimenin yalnızca o harfin karoları + kullanılmayan joker karakterleri olduğu kadar belirli bir harfi olabilir. Scrabble tahtası 15 x 15 hücre, bu nedenle kelime 2 ila 15 karakter uzunluğunda olmalıdır.

İngilizce versiyondaki her bir mektubun miktarı ve puanının bir listesi için aşağıya veya http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( arşiv ) sayfasına bakınız.

Harf Adet Puan Harf Adet Puan
------------------- ---------------------
A 9 1 0 8 1
B 2 3 P 2 3
C2 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 10
M 2 3 [vahşi] 2 0
N 6 1

Ek kurallar

  • Program, STDIN veya benzerlerinden tek bir giriş dizisi alacaktır.
  • Giriş her zaman yalnızca büyük harflerden oluşacaktır.
  • Dize, bir harfin kullanılmayan joker karakterler veya döşemelerden daha fazla kopyasını içeriyorsa VEYA, dizenin uzunluğu 2 ile 15 arasında değilse, programın çıkması gerekir Invalid.
  • Aksi takdirde, yukarıdaki tablodaki veriler ve çıktılar kullanılarak skor eklenmelidir.
  • Gerekmedikçe joker karakterler kullanmayın.
  • İkili kelime puanları gibi ikramiye veya dizenin gerçek bir kelime olup olmadığı konusunda endişelenmeyin.
  • Program, sonucu STDOUT veya benzeri bir şekilde vermelidir.
  • Varsayılan olarak yasaklanan boşluklara izin verilmez.
  • Bir web sitesi gibi harici bir kaynağın yanı sıra, Scrabble puanlarını veya uygun miktarları hesaplayan tüm kütüphaneleri, API'leri, işlevleri veya benzerlerini kullanmak ayrı değildir.
  • Bu , yani en az bayt kazanır.

Bakış

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

Giriş çıkış
------------------------
Karalama 14
CAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ Geçersiz
KIXOKEJAJAX Geçersiz
MISUNDERSTANDING Geçersiz

5
Joker karakterler kullanan geçerli bir kelime için bir test
senaryosu

2
Biliyorsunuz, Scrabble döşemeleri İspanyolca, Baskça, Macarca, Tuvan veya Galce gibi tek bir karakterle temsil edilemeyen bir dil içeriyorsa, bu meydan okuma çok daha kötü olurdu.
user0721090601 10:14

Cevaplar özellikle "Geçersiz" ifadesi için gerekli mi, yoksa açıkça bir puan olmadığı sürece herhangi bir davranış seçebilir miyiz? Örneğin, -1?
Kamil Drakari

@KamilDrakari Tam olarak söylemeli Invalid.
NinjaBearMonkey

Yanıtlar:


15

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

Perl -E ile çalıştırın.

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

Bu çözüm bazı yazdırılamayan karakterler kullanıyor, bu yüzden aşağıda bir hexdump verildi:

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

Alternatif olarak, Ctrl + Key kullanarak:

$_=<>;@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 + yorumladı:

# 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
Bazı yaratıcı manipülasyonlarla bu dizilerin en az 20 baytını
sıkabilirsiniz

1
Gah, her zaman benden bir adım önde. :) Olumlu bir oyum var.
Alconja

Bu ilginçti, sonuçlarımız çok yakındı. +1.
Seviye Nehri St

Bu -M5.010(0 ceza) yerine -e( kullanılacak dilin bir versiyonunu belirttiği için) 0 (ceza) ile çalışıyor mu? Bağımsız değişkenlerde bir bayt kaydedebilirsiniz.

13

C, Rev2, 151 145 138

@ Bebe'nin yorumundaki 159 byte kodundan esinlenerek 8 8 21 karakter daha attım :

Uzunluk sayacı yeniden düzenlenerek kaydedilen 4 bayt i. Bu, 1'e (programın hiçbir argüman almadığı varsayılarak) başlatılır, ardından her harf okunduğunda 4 ile çarpılır. Sözcük uzunluğu 15'ten büyük olduğunda sıfıra taşar, bu nedenle sözcük uzunluğunun kötü olup olmadığını kontrol etmek için, basitçe şunu kontrol ederiz i<5( i<9eğer kullanıcı yanlışlıkla yanlışlıkla 2'ye girerse bir harfli kelimeler için geçersiz kılar i. komut satırında tek bir argüman.)

Döngü koşulu testi basit olarak değiştirilerek kaydedilen 4 bayt &31. Bu, kelimenin bir boşlukla (ASCII 32) veya boş bir karakterle (ASCII 0) sonlandırılmasını gerektirir. Normal olarak klavye girişi, yeni bir satırla (ASCII 10) sonlandırılır, bu nedenle, programın kullanımı biraz zahmetlidir; boşluk daha sonra bilgisayarın arabelleği okumasını sağlamak için de return tuşuna basın. Newline-terminli dizgiler için, eşleşebilirdim ama bebeğin yaptığı gibi dövemezdim.

6 13 bayt, kodlamayı değiştirerek kaydetti - (her harfe ait çini sayısı) - (o harf için puan-1) * 13 . Bu şimdi, Q, Z için L, S, U ila -118 için -4 aralığını gerektirir. Negatif sayılar kullanmanın nedeni, yazdırılamayan ASCII 0 ila 31 aralığından kaçınmaktır. Bunun yerine kullanılan aralık, ikisinin 256-4 = 252 ila 256-118 = 138 negatif sayıları tamamlayıcısıdır. Bunlar yazdırılabilir, genişletilmiş ASCII karakterleridir. Bunları Unicode'a kopyalayıp yapıştırmakla ilgili sorunlar var (tahmin edilemeyen sonuçlara yol açabilecek ASCII'ye geri getirme şekli yüklü kod sayfasına bağlıdır) ve program yorumuna doğru ASCII kodlarını dahil ettim.

Bu kodlamanın avantajı, rfayansların sayısı her zaman 1 azaldıkça (negatif sayı olarak saklandığı gibi yaptığımız gibi) değişkenin ortadan kaldırılmasıdır t[x]++. Ayrıca, postfix operatörü, bu artışı aynı anda gerçekleştirebileceğimiz anlamına gelir. skoru ekleyerek 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 (veya derleyici seçeneğine sahip 172)

GCC kullanıyorum ve derleyici seçeneğiyle , bir ek noktalı virgül tasarrufu için döngü başlangıcına geçmeme -std=c99izin verecek . Okunabilirlik için programı bu değişiklik olmadan ve boşluk bırakılmış olarak gösterdim.char t[]="...."for

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

Hile veri tablosunda. Her harf için, bir ASCII kodu ( bu harf için toplam döşeme puanı) * 10 + (bir döşeme-1 puanı) tabloda gösterilir t[]. Çalışma zamanında, bu toplam puanlar döşemeler tükendikçe azalır.

Her bir harf için tüm çinilerin toplam puanı, E için 12'den L, S, U için 4'e kadar değişmektedir. Bu kodlama biçimi yalnızca yazdırılabilir ASCII karakterlerinin kullanılmasını sağlar (ASCII 120, xE'den ASCII 40'a, (L, S, U için) . Karoların sayısının kullanılması 120'den 10'a kadar bir aralığa ihtiyaç duyar, bu yüzden I ondan kaçının.

Bir #definemakro sayesinde T, ana programda iilk komut satırı argümanından harf dizinini almak için tek bir sembol kullanılır , bir dizin oluşturmak için ASCII A= 65'i çıkarır ve dizini T: tablosunda arar t[x[1][i]-65].

forDöngü daha gibi kullanılan whiledöngü: döngü uçları sıfır bayt (string terminatör) giriş dizesi karşılaşıldığında.

Eğer o mektubun karoları tükenmemişse ( T/10sıfır değilse ) s, T%10+1toplam puanı tutmak için karo skoru ile artırılır . Aynı zamanda, karo skoru saklanır r, böylelikle temsil Tedilebilecek olan içindeki değer r*10, bir karonun kullanıldığını belirtmek için azaltılabilir . Döşemeler tükenirse, joker / boş sayıcı bartırılır.

printfİfadesi oldukça kendini açıklayıcı. kelime uzunluğu sınırların dışındaysa veya boşluk sayısı çok yüksekse, yazdırın, Invalidaksi takdirde skoru yazdırın s.


Şimdi bir başka gün olduğundan, bir karakteri r + = (r == 7) * 3 yerine r + = r-7? 0: 3 ile kaydedebilirsiniz. Ayrıca, T- = r * 9, s + = r yuvarlak parantezlere ihtiyacınız yoktur.
Simyacı

@Alchymist teşekkürler parantez hakkında ipucu için, ben her zaman arasındaki operatör önceliği ile hiçbir sorunları yoktur unutmak ?ve :. Kodlama işlemini tamamen değiştirdiğim için diğer noktanızın yerini aldığınızdan Q ve Z'nin özel olarak kullanılmasına gerek yok. Şimdi sizin yardımınızla 173/172'ye kadar.
Seviye River St

1
ile getchar(): o 159 var 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);}hala neden almamış char*foo=<string>çöküyor. 2 karakter kurtarabilir.
bebe,

1
@bebe char*foo="string"bir karakter dizisidir ve içeriğinin değiştirilmesine izin verilmez. Öte yandan, char foo[]="string"başlangıçta değiştirilen bir dizi karakter yaratır ve string\0bu daha sonra değiştirilebilir.
es1024

@bebe cool, kodunda yaptığım getchar().iyileştirmeleri (cevabımın geri kalanıyla tutarlılık için değişken isimlerimle) kullandım, artı kelime uzunluğu geçerlilik kontrolünde bir iyileştirme ve döngü koşulunda arsız bir iyileştirme kullanma fikrini kaçırdım testi (seninkini kısaltmaya çalıştım, ancak aynı işlevsellik ile yapamadım.) Ayrıca denedim getche()ve getch()derleyicim (cyccwin'de gcc) bunları otomatik olarak bağlamaz.
Seviye Nehri 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)}

Düzenleme - büyüklüğü azaltmak ve ascii olmayan değişkenleri kaldırmak için miktarları / puanları kodlama biçimimi değiştirdi

Düzenleme 2 - miktar / puan kodlamalarını dizge yerine tamsayı olarak değiştirdi

Düzenleme 3 - %13(teşekkürler @ edc65), kodlamayı ters çevirmiş, değerleri doğrudan değiştirmiş ve birkaç diğer küçük iyileştirme

Firefox konsolunda test edilmiştir.


1
+1 çok akıllıca. Öneriler: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2.Neden% 13 kullanmayın
edc65

1
192 f = s => {(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 = burada R = t = 6, O = 8, Q = Z = 118, $ = 2, t = i = 0, c = s [i ++ ]) (f [c] = - ~ f [c])> (l bu [c]),% 13 = - $: t * = l / 13 + 1 | 0, uyarı, (i <3 | i> 16 | $ <0? "Geçersiz": t)}
edc65

@ edc65 - Teşekkürler yığınları. Bu ilk numarayı görmemiştim, ama şimdi değerleri doğrudan değiştirdiğim için kullanmaya son vermedim (zihinsel olarak gelecekteki golf için uzaklaştırarak). %13gerçi bir dahi felçtir. Bazı şeyleri basamaklarda saklamak zorunda kaldığımı düşünerek şaşkına döndüm, ancak matematik, taban10 ve taban13 arasındaki farkı umursamıyor.
Alconja

Güzel! (Chrome konsolunda çalışmaz, BTW SyntaxError: Unexpected token >
:.

@DLosc - Evet, sanırım şu anda tüm ECMAScript 6 öğelerini destekleyen tek tarayıcı Firefox'tur (Chrome f=s=>{...}notasyonu sevmez ).
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])

Düzenleme: @BeetDemGuise sayesinde beni en fazla 1 karakterlik bir azaltmaya yönlendiren bir ipucu için teşekkürler! Aşağıdaki orijinal kod:

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

Oldukça az ancak puanları int('1332142418513113a11114484a'[o],16)
dizginizi

4

BEFUNGE 93 - 210 bayt.

Ancak 15 harf sınırını kontrol etmiyor.

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

Dizenin komut satırı argümanı olarak verildiğini varsayar, örneğin ./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)

zkelime saklar. Alarm olarak çıkar.

Düzenleme: aşağıdaki önerilere göre geliştirilmiştir.


2
ssadece bir kez kullanılır, bu yüzden onu bir değişken yapmanıza gerek kalmaz; O bildiriyi kaldırıp yerine r+=s[x]sahip r+=-~"02210313074020029000033739"[x]. Ayrıca, (w>2|y<2|y>15)alarmın çevresinde parantez içinde olmanız gerekmez .
NinjaBearMonkey

4

Haskell - 538

Scrabble.hs olarak kaydedin ve sonra kullanarak derleyin

ghc --make scrabble && ./scrabble

Ardından kelimenizi giriş olarak girin ve enter tuşuna basın.

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"

Çok fazla boşluk kaldırabilirsiniz ve Haskell `['A', 'B', 'C'] ==" ABC ". Ayrıca, her girinti düzeyi için yalnızca bir boşluk kullanabilirsiniz. Ve daha kısa isimler kullanabilirsiniz. Golf için çok şey var.
Ray

@Ray, Haskell için yeniyim, Int'lerin listelerini [1,2,3] 'den daha özeleştirmenin bir yolu var mı?
Tuomas Laakkonen

"ABCDEFG"olarak yazılabilir ['A'..'G'], [1,2,3]olarak yazılabilir[1..3]
Ray

Bayt sayınızı nasıl alıyorsunuz? wc, kodunuz için bana 500'den fazla karakter verir.
TheSpanishInquisition 7:14

@TheSpanishInquisition Benim st3 kelime sayısı uzatma için bir güncelleme var, yazar yanlışlıkla iki sayıları değiştirdi, 538 düzenlenmiş
Tuomas Laakkonen

3

Python 2,7 - 263

DLosc'un cevabına yakın bir yere gelemedim , ama bu her mektubu çekip çıkardığınız, boşalıncaya kadar boş bıraktıktan sonra boşlukları çeken bir 'torba' gibi davranıyor ve bu boşaldığında hata veriyor.

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
Bu temiz bir yaklaşım! raw_inputPython2 (Python3 hakkında sevdiğim bir şey) olup olmadığına ihtiyacınız var. Giriş kaldır böylece, büyük garantili .lower()ve değişim 97+iiçin 65+i. 2 karakterden daha küçük bir girişin de geçersiz olması gerekir. Bir olmadan sıfır bölme hatasını yükseltebilirsiniz ifaçıklamada: göre toplam puanı bölmek (1<len(S)<16). Diğer bir kaç tane ise s'leri printblok başlıklarıyla aynı satıra koymak ve önce alanı silmek gibi "Invalid"sayılarıma göre 250'ye düşürüyor. :)
DLosc

2

Haskell, 290 283

Şimdilik yapabileceğim kadarıyla:

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

Bu kod kurallara çok sıkı bir şekilde uyuyor, bu yüzden herhangi bir fazladan karakter (satır sonu gibi) geçmediğinizden emin olun. Bunun gibi kullanın:echo -n "JAZZ" | runghc scrabble.hs .

açıklama

Desen (_:_:_), yalnızca en az iki karakterden oluşan dizelerin dikkate alınmasını sağlar, diğer her şey sonuçlanır "Invalid"(geri dönüş deseni _). Fayans tablosu, her biri 6 defadan fazla gerçekleştiği 11*nTiles+valueiçin harflerin AEIOçoğaltıldığı arama modülünün 11 çalışmasına izin veren bir kayma ile ASCII'ye dönüştürülmüş olarak kodlanır . Ardından, fayans havuzu replicate, kelime içindeki karakterlerin ortaya çıktıkça kaldırıldığı kullanılarak yaratılır (liste farkı,\\ ) ). Havuz 98 karo içerdiğinden, kelimenin toplam uzunluğu ve havuzun kalan kısmı 100'den büyükse, o zaman çok fazla joker kullandık. Ayrıca, eksi ilk 15 harften kelime uzunluk hesaplamasına üç kez eklenir, böylece 15 harften daha uzun olan herhangi bir kelime otomatik olarak üç joker karakter kullanır ve bu nedenle geçersizdir. Başlangıçta 187 puana sahip olan kalan havuzda basitçe çıkardığımız puanlama yapılır. Not f 61ziyadef 65, 65 , havuzun başındaki 'A'kopya olduğundan dolayı ASCII sayısı "AEIO". Gerisi sadece kazan plakasıdır.


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

Kullanılacak bignums'ları koyalım: D (Şu anda joker karakterleri işlemiyor, bu kuralı tamamen okudum, kahretsin)


1

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

Çıktısının "Invalid"iyi olduğunu farz ediyorum, yapmam gerekmeyecekse $><<(-b<1&&w.size<16?s:'Invalid')1985'e kadar çıkacaktı.


Clojure - 325

Bir süredir clojure yapmadım, bu yüzden çözümümü geliştirmenin birkaç yolu olduğuna eminim.

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

Bazı ne Un 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)))

1

ES6: 184 (katı olmayan)

wzaten sözcüğü içerdiği varsayılır. rçıktı dizesidir.

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"

İşte açıkladı ve biraz daha az golf oynadı:

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

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

Bu bignums gerektirir, bu yüzden JavaScript ile derlenmez.
Daha fazla boşlukla:

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 bayt

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;

Yuppi! JS yenerek!

Yıkmak

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'dan büyük harf notu olmadığı için çok mutluyum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.