Określ wynik Scrabble i jego ważność

24

Twoim zadaniem jest ustalenie, czy dany ciąg ma odpowiednią długość i może być reprezentowany za pomocą płytek Scrabble, a jeśli tak, to wyświetl sumę wyniku każdej litery.

Jeśli nie wiesz, jak grać w Scrabble: masz 100 płytek z nadrukowanymi różnymi literami A – Z, a także dwie symbole wieloznaczne, które mogą reprezentować dowolną literę. Każda litera ma określoną liczbę punktów, a każda płytka (ale niekoniecznie słowo) może być użyta tylko raz. Kiedy słowo jest odtwarzane, sumuje się wartość punktową każdego użytego kafelka, który staje się wynikiem. Ponieważ dostępna jest ograniczona liczba liter, słowo może mieć tylko określoną literę tyle razy, ile litera ma kafelki + wszelkie nieużywane symbole wieloznaczne. Tablica Scrabble ma 15 × 15 komórek, więc słowo musi mieć od 2 do 15 znaków.

Aby uzyskać listę ilości i punktacji każdej litery w wersji angielskiej, patrz poniżej lub http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( archiwum ).

Liczba listów Liczba Liczba listów
------------------- -------------------
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 [dziki] 2 0
N 6 1

Dalsze zasady

  • Program pobiera pojedynczy ciąg danych wejściowych ze STDIN lub podobnego.
  • Dane wejściowe zawsze będą zawierać tylko wielkie litery.
  • Jeśli ciąg zawiera więcej kopii litery niż nieużywane symbole wieloznaczne lub kafelki dla tej litery LUB długość łańcucha nie jest zawarta między 2 a 15 włącznie, program powinien wypisać dane Invalid.
  • W przeciwnym razie wynik należy zsumować z wykorzystaniem danych z powyższej tabeli i wyników.
  • Nie używaj symboli wieloznacznych, chyba że jest to konieczne.
  • Nie martw się o bonusy, takie jak wyniki podwójnych słów lub to, czy ciąg znaków jest prawdziwym słowem.
  • Program wyświetli wynik poprzez STDOUT lub podobny.
  • Luki, które są domyślnie zabronione, nie są dozwolone.
  • Korzystanie z zewnętrznego źródła, takiego jak strona internetowa, a także dowolnych bibliotek, interfejsów API, funkcji itp., Które obliczają wyniki Scrabble lub odpowiednie ilości nie są dozwolone.
  • To jest , więc wygrywa najmniej bajtów.

Przewodnik

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

Przypadki testowe

Wejście wyjście
------------------------
SCRABBLE 14
JAZZ 19
WYMIANA STOSUNKU 32
XYWFHQYVZVJKHFW 81
PIZZAZZ Nieprawidłowy
KIXOKEJAJAX Niepoprawny
NIEPRAWIDŁOWOŚĆ Niepoprawny
NinjaBearMonkey
źródło
5
Może chcę dodać przypadek testowy dla poprawnego słowa, które używa
symboli
2
Wiesz, to wyzwanie byłoby o wiele bardziej złe, gdyby dotyczyło języka, którego kafelków Scrabble nie można przedstawić za pomocą jednego znaku, takiego jak hiszpański, baskijski, węgierski, tuvan czy walijski.
user0721090601
Czy odpowiedzi są szczególnie wymagane do wypisania „Nieprawidłowy”, czy też możemy wybrać jakieś zachowanie, o ile wyraźnie nie jest to wynikiem? Na przykład -1?
Kamil Drakari,
@KamilDrakari To musi dokładnie powiedzieć Invalid.
NinjaBearMonkey

Odpowiedzi:

15

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

Uruchom z perl -E.

Gra w golfa:

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

To rozwiązanie wykorzystuje niektóre niedrukowalne znaki, więc zrzut heksowy znajduje się poniżej:

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

Alternatywnie, używając 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 + skomentował:

# 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
źródło
1
możesz wycisnąć z tych tablic co najmniej 20 bajtów przy pomocy kreatywnej manipulacji
Sparr
1
Gah, zawsze o krok przede mną. :) Mam opinię.
Alconja,
To było interesujące, nasze wyniki były tak blisko. +1.
Level River St
Czy działa to z -M5.010(kara 0, ponieważ określa wersję używanego języka), a nie -e(kara 1)? Możesz być w stanie zapisać bajt w argumentach.
13

C, Rev 2, 151 145 138

Zainspirowany 159-bajtowym kodem w komentarzu @ bebe, wycisnąłem kolejne 8 14 21 znaków:

4 bajty zapisane przez przestawienie licznika długości i. Jest to inicjalizowane na 1 (zakładając, że program nie przyjmuje argumentów), a następnie mnożone przez 4 za każdym razem, gdy czytana jest litera. Przepełnia się do zera, gdy długość słowa jest większa niż 15, więc aby sprawdzić, czy długość słowa jest zła, po prostu sprawdzamy, czy i<5( i<9wstawiam, iaby nadal dawał niepoprawne dla słów jednoliterowych, jeśli użytkownik przypadkowo zainicjuje wartość 2, ustawiając pojedynczy argument w wierszu poleceń).

4 bajty zapisane przez zmianę testu warunku pętli na prosty &31. Wymaga to, aby słowo zostało zakończone spacją (ASCII 32) lub znakiem zerowym (ASCII 0.) Zwykle wprowadzanie z klawiatury kończy się znakiem nowej linii (ASCII 10), więc korzystanie z programu jest nieco niewygodne, ponieważ musisz wpisać spacja, a następnie naciśnij klawisz Return, aby komputer odczytał bufor. W przypadku ciągów zakończonych znakiem nowej linii mogłem dopasować, ale nie pobić sposobu, w jaki bebe to robi.

6 13 bajtów zapisanych przez zmianę kodowania na - (liczba płytek każdej litery) - (wynik dla tej litery-1) * 13 . Wymaga to teraz zakresu od -4 dla L, S, U do -118 dla Q, Z. Powodem użycia liczb ujemnych jest uniknięcie zakresu niedrukowalnego ASCII od 0 do 31. Zamiast tego zastosowany zakres stanowi uzupełnienie liczb ujemnych od 256 do 4 = 252 do 256-118 = 138. Są to drukowane, rozszerzone znaki ASCII. Występują problemy z kopiowaniem i wklejaniem ich w Unicode (sposób, w jaki upraszcza z powrotem do ASCII, zależy od zainstalowanej strony kodowej, co może prowadzić do nieprzewidywalnych wyników), dlatego w komentarzu do programu umieściłem prawidłowe kody ASCII.

Zaletą tego kodowania jest eliminacja zmiennej, rponieważ liczba kafelków jest zawsze zmniejszana o 1 (ponieważ jest ona przechowywana jako liczba ujemna, robimy to t[x]++. Dodatkowo operator postfiksu oznacza, że ​​możemy wykonać ten przyrost w tym samym czasie, co dodanie wyniku do 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 (lub 172 z opcją kompilatora)

Korzystam z GCC, a dzięki opcji kompilatora -std=c99pozwoli mi przejść char t[]="...."do inicjalizacji forpętli w celu zaoszczędzenia jednego dodatkowego średnika. Dla czytelności pokazałem program bez tej zmiany i pozostawiono spację.

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

Sztuczka znajduje się w bazie danych. Dla każdej litery w tabeli zapisany jest kod ASCII formularza (łączny wynik płytek dla tej litery) * 10 + (wynik jednej płytki-1)t[] . W czasie wykonywania te łączne wyniki są zmniejszane w miarę zużycia płytek.

Całkowity wynik wszystkich płytek dla każdej litery wynosi od 12 dla E do 4 dla L, S, U. Ta forma kodowania umożliwia stosowanie tylko drukowalnych znaków ASCII (ASCII 120, xdla E do ASCII 40, (dla L, S, U). Użycie liczby kafelków wymagałoby zakresu od 120 do 10, dlatego I uniknąłem tego.

Dzięki #definemakro, pojedynczy symbol Tjest używany w programie głównym, aby pobrać indeks się iz pierwszego argumentu wiersza poleceń, odejmowanie ASCII A= 65 od niego podania indeksu i szukać go w tabeli T: t[x[1][i]-65].

forPętla jest stosowany raczej do whilepętli: końce pętli, gdy zerowy bajt (terminatora łańcuch) spotyka się w ciągu wejściowego.

Jeśli kafelki tej litery nie są wyczerpane ( T/10są niezerowe), ssą zwiększane o wynik kafelka, T%10+1aby zachować łączny wynik. Jednocześnie zapisywany jest wynik kafelka r, dzięki czemu wartość w stanie reprezentowanym przez Tmoże zostać zmniejszona o, r*10aby wskazać, że użyto jednego kafelka. Jeśli płytki zostaną wyczerpane, licznik symboli zastępczych / pustych bjest zwiększany.

To printfstwierdzenie jest dość oczywiste. jeśli długość słowa jest poza zakresem lub liczba pustych miejsc jest zbyt wysoka, wydrukuj w Invalidprzeciwnym razie wydrukuj wynik s.

Level River St
źródło
Ponieważ jest teraz kolejny dzień, możesz uratować jedną postać, zastępując r + = (r == 7) * 3 r + = r-7? 0: 3. Również nie potrzebujesz nawiasów okrągłych T- = r * 9, s + = r.
Alchymist
@Alchymist Dzięki za poradę w nawiasach, zawsze zapominam, że nie ma problemów z pierwszeństwem operatora między ?i :. Twój drugi punkt został zastąpiony, ponieważ całkowicie zmieniłem kodowanie, więc nie ma potrzeby specjalnej obsługi Q i Z. Teraz z pomocą do 173/172.
Level River St
1
z 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);}chociaż wciąż nie rozumiem, dlaczego się char*foo=<string>zawiesza. może zaoszczędzić 2 znaki.
bebe
1
@bebe char*foo="string"jest literałem ciągowym , a jego zawartość nie może być modyfikowana. Z drugiej strony char foo[]="string"tworzy tablicę znaków zainicjowanych string\0, które mogą być następnie modyfikowane.
es1024,
@bebe cool, brakowało mi pomysłu użycia getchar().Użyłem ulepszeń w kodzie (z moimi zmiennymi nazwami w celu zachowania spójności z resztą mojej odpowiedzi), a także ulepszenia sprawdzania poprawności długości słowa i bezczelnej poprawy stanu pętli Test (próbowałem skracając je, ale nie mógł zrobić z tą samą funkcjonalność.) próbowałem też getche()i getch()ale mój kompilator (gcc na cygwin) nie odwołuje się je automatycznie.
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)}

Edytuj - zmieniłem sposób, w jaki kodowałem ilości / wyniki, aby zmniejszyć rozmiar i usunąć zmienne inne niż ascii

Edycja 2 - zmieniono kodowanie ilości / wyniku na liczby całkowite zamiast ciągów

Edycja 3 - zmieniono na %13(dzięki @ edc65), odwrócono kodowanie, bezpośrednio zmodyfikowano wartości i kilka innych drobnych usprawnień

Testowany w konsoli Firefox.

Alconja
źródło
1
+1 bardzo sprytny. Sugestie: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2. dlaczego nie używać% 13
edc65
1
192 f = s => {dla (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 = ten [c])% 13? - $: t + = l / 13 + 1 | 0; alert (i <3 | i> 16 | $ <0? "Invalid": t)}
edc65
@ edc65 - Dzięki stosy. Nie widziałem tej pierwszej sztuczki, ale nie skończyłem z nią, ponieważ teraz bezpośrednio modyfikuję wartości (mentalnie zapisuję ją do przyszłego golfa). %13jest jednak genialny. Utknąłem, myśląc, że muszę przechowywać rzeczy w cyfrach, ale matematyki nie obchodzi różnica między bazą 10 a bazą 13.
Alconja,
Miły! (Nie działa w konsoli Chrome, BTW SyntaxError: Unexpected token >
:.
@DLosc - Tak, myślę, że Firefox jest obecnie jedyną przeglądarką obsługującą wszystkie funkcje ECMAScript 6 (Chrome nie lubi f=s=>{...}notacji).
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])

Nie golfowany:

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

Edycja: Dzięki @BeetDemGuise za wskazówkę, która ostatecznie doprowadziła mnie do znacznie więcej niż 1-znakowej redukcji! Oryginalny kod poniżej:

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
źródło
Jest dość minimalny, ale możesz zaoszczędzić 1 bajt, kodując ciąg znaków w int('1332142418513113a11114484a'[o],16)
zapisie
4

BEFUNGE 93-210 bajtów.

Ale nie sprawdza limitu 15 liter.

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
źródło
4

C 197

Zakłada, że ​​ciąg jest podany jako argument wiersza poleceń, np ./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);}
piskliwy kostuch
źródło
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)

zprzechowuje słowo. Wysyła jako alert.

Edycja: ulepszona zgodnie z zaleceniami poniżej.

Matt
źródło
2
sjest używany tylko raz, więc nie musisz wcale zmieniać go; możesz usunąć tę deklarację i zastąpić r+=s[x]r+=-~"02210313074020029000033739"[x]. Ponadto nie trzeba nawiasów (w>2|y<2|y>15)w alercie.
NinjaBearMonkey
4

Haskell - 538

Zapisz go jako scrabble.hs, a następnie skompiluj za pomocą

ghc --make scrabble && ./scrabble

Następnie wprowadź słowo jako wejście i naciśnij klawisz 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
źródło
Możesz usunąć wiele spacji i w Haskell `['' ',' B ',' C '] ==" ABC ". Możesz także użyć tylko jednej spacji dla każdego poziomu wcięcia. I możesz używać krótszych nazw. Jest wiele do gry w golfa.
Ray
@Ray Czy już to zrobiłem, jestem nowy w Haskell, czy istnieje sposób, aby przedstawiać listy Ints bardziej zwięźle niż [1,2,3]?
Tuomas Laakkonen
"ABCDEFG"można zapisać jako ['A'..'G'], [1,2,3]można zapisać jako[1..3]
Ray
Jak uzyskać liczbę bajtów? wc daje mi ponad 500 znaków dla twojego kodu.
TheSpanishInquisition
@TheSpanishInquisition Właśnie dostałem aktualizację mojego rozszerzenia licznika słów st3, autor zamienił dwie liczby przypadkowo, zredagowane na 538
Tuomas Laakkonen
3

Python 2.7 - 263

Nie mogłem zbliżyć się do odpowiedzi DLosc , ale to traktuje każdą literę jako „torbę”, z której się wyciąga, dopóki nie jest pusta, a następnie ciągnie się puste, a kiedy jest pusta, popełnia błąd.

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"
Społeczność
źródło
1
To miłe podejście! Potrzebujesz, raw_inputjeśli jest to Python2 (jedna rzecz, którą lubię w Python3). Dane wejściowe są gwarantowane wielkimi literami, więc usuń .lower()i zmień 97+ina 65+i. Wprowadzanie mniej niż 2 znaków również musi być nieprawidłowe. Możesz podnieść błąd podziału zerowego bez ifinstrukcji: podziel swój wynik przez (1<len(S)<16). Kilka innych drobiazgów, takich jak umieszczenie prints na tej samej linii co nagłówki bloków i usuwanie spacji przed "Invalid"obniżeniem jej do 250 według moich obliczeń. :)
DLosc
2

Haskell, 290 283

Tak daleko, jak tylko mogłem, na razie:

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

Ten kod bardzo ściśle przestrzega reguł, więc upewnij się, że nie przekazujesz żadnych dodatkowych znaków (takich jak koniec linii). Używać tak: echo -n "JAZZ" | runghc scrabble.hs.

Wyjaśnienie

Wzorzec (_:_:_)upewnia się, że brane są pod uwagę tylko łańcuchy co najmniej dwóch znaków, wszystko inne skutkuje "Invalid"(wzorzec rezerwowy _). Tabela kafelków jest kodowana jako 11*nTiles+valueprzekonwertowana na ASCII z przesunięciem, które pozwala na działanie modułu wyszukiwania 11, gdzie litery AEIOsą duplikowane, ponieważ występują one więcej niż 6 razy. Następnie tworzona jest pula kafelków replicate, z której usuwane są znaki w słowie w miarę ich pojawiania się (różnica list,\\). Pula zawiera 98 kafelków, więc jeśli łączna długość słowa i pozostałej części puli jest większa niż 100, to użyliśmy zbyt wielu symboli wieloznacznych. Ponadto słowo pomniejszone o pierwsze 15 liter jest dodawane trzykrotnie do obliczeń długości, więc każde słowo dłuższe niż 15 liter automatycznie wydaje się używać trzech symboli wieloznacznych i dlatego jest nieprawidłowe. Punktacja odbywa się na pozostałej puli, która początkowo miała 187 punktów, z których po prostu odejmujemy. Zauważ, że f 61zamiast f 6565 oznacza liczbę ASCII 'A', z powodu dwóch egzemplarzach "AEIO"na początku basenie. Reszta to tylko płyta kotłowa.

TheSpanishInquisition
źródło
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)])

Wykorzystajmy bignum: D (obecnie nie obsługuje symboli wieloznacznych, pominąłem czytanie tej reguły, cholera)

LemonBoy
źródło
1

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

Zakładam, że wynik "Invalid"jest w porządku, jeśli nie, musiałbym zrobić, $><<(-b<1&&w.size<16?s:'Invalid')co podniosłoby go do 198


Clojure - 325

Od jakiegoś czasu nie robiłem clojure, więc jestem pewien, że istnieje kilka sposobów na ulepszenie mojego rozwiązania. Listy qty i 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))))))

Niektóre co 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)))
Ebtoulson
źródło
1

ES6: 184 (nie ścisłe)

wzakłada się, że zawiera już słowo. rjest łańcuchem wyjściowym.

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"

Oto wyjaśnienie i trochę mniej golfa:

// 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
źródło
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");}

Wymaga to bignum, więc nie będzie się kompilowało do JavaScript.
Z większą ilością białych znaków:

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
źródło
0

PHP, 180 170 168 bajtów

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;

Tak! pokonując JS!

awaria

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

Tak się cieszę, że nie ma więcej punktów niż 10.

Tytus
źródło