Bestimmen Sie die Scrabble-Bewertung und die Gültigkeit einer Zeichenfolge

24

Ihre Aufgabe ist es, zu bestimmen, ob eine bestimmte Zeichenfolge die richtige Länge hat und mit Scrabble-Kacheln dargestellt werden kann, und in diesem Fall die Summe der Punkte jedes Buchstabens auszugeben.

Wenn Sie nicht wissen, wie man Scrabble spielt: Sie haben 100 Kacheln mit verschiedenen Buchstaben von A bis Z sowie zwei Platzhalter, die für jeden Buchstaben stehen können. Jeder Buchstabe hat eine bestimmte Anzahl von Punkten, und jedes Plättchen (aber nicht unbedingt ein Wort) kann nur einmal verwendet werden. Wenn ein Wort gespielt wird, wird der Punktewert jedes verwendeten Plättchens addiert, was zur Punktzahl wird. Da nur eine begrenzte Anzahl von Buchstaben verfügbar ist, kann ein Wort nur so oft einen bestimmten Buchstaben haben, wie der Buchstabe Kacheln + nicht verwendete Platzhalter enthält. Die Scrabble-Tafel besteht aus 15 × 15 Zellen, daher muss das Wort zwischen 2 und 15 Zeichen lang sein.

Eine Liste der Anzahl und Punktzahl der einzelnen Buchstaben in der englischen Version finden Sie unten oder unter http://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( Archiv ).

Buchstabenanzahl Punkte Buchstabenanzahl Punkte
------------------- -------------------
A 9 1 O 8 1
B 2 3 P 2 3
C 2 3 Q 1 10
D 4 2 R 6 1
E 12 1 S 4 1
F 2 4 T 6 1
G 3 2 U 4 1
H 2 4 V 2 4
I 9 1 W 2 4
J 1 8 X 1 8
K 1 5 Y 2 4
L 4 1 Z 1 10
M 2 3 [wild] 2 0
N 6 1

Weitere Regeln

  • Das Programm soll eine einzelne Folge von Eingaben von STDIN oder dergleichen annehmen.
  • Die Eingabe enthält immer nur Großbuchstaben.
  • Wenn die Zeichenfolge mehr Kopien eines Buchstabens enthält, als Platzhalter oder Kacheln für diesen Buchstaben nicht verwendet wurden, ODER wenn die Länge der Zeichenfolge nicht zwischen 2 und 15 einschließlich liegt, sollte das Programm eine Ausgabe durchführen Invalid.
  • Andernfalls sollte die Punktzahl mit den Daten aus der obigen Tabelle addiert und ausgegeben werden.
  • Verwenden Sie keine Platzhalter, es sei denn, dies ist erforderlich.
  • Sorgen Sie sich nicht um Boni wie doppelte Wortwerte oder ob die Zeichenfolge ein echtes Wort ist.
  • Das Programm soll das Ergebnis über STDOUT oder dergleichen ausgeben.
  • Lücken, die standardmäßig verboten sind, sind nicht erlaubt.
  • Die Verwendung einer externen Quelle wie einer Website sowie von Bibliotheken, APIs, Funktionen oder Ähnlichem, die Scrabble-Scores oder geeignete Mengen berechnen, ist nicht zulässig.
  • Das ist , also gewinnen die wenigsten Bytes.

Komplettlösung

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

Testfälle

Input-Output
------------------------
SCRABBLE 14
JAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ Ungültig
KIXOKEJAJAX Ungültig
MISUNDERSTANDING Ungültig
NinjaBearMonkey
quelle
5
Möglicherweise möchten Sie einen Testfall für ein gültiges Wort hinzufügen, das
Platzhalter
2
Wissen Sie, diese Herausforderung wäre um so schlimmer, wenn es sich um eine Sprache handeln würde, deren Scrabble-Kacheln nicht mit einem einzigen Zeichen dargestellt werden können, wie Spanisch, Baskisch, Ungarisch, Tuvanisch oder Walisisch.
user0721090601
Werden Antworten speziell für die Ausgabe von "Ungültig" benötigt, oder können wir ein beliebiges Verhalten auswählen, sofern es sich eindeutig nicht um eine Punktzahl handelt? Zum Beispiel -1?
Kamil Drakari
@KamilDrakari Muss es genau sagen Invalid.
NinjaBearMonkey

Antworten:

15

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

Führen Sie mit Perl -E.

Golf gespielt:

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

Bei dieser Lösung werden einige nicht druckbare Zeichen verwendet, sodass nachfolgend ein Hexdump bereitgestellt wird:

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

Alternativ können Sie auch Strg + Taste verwenden:

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

# 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
quelle
1
Mit einigen kreativen Manipulationen können Sie mindestens 20 Bytes aus diesen Arrays herausholen
Sparr
1
Gah, immer einen Schritt voraus. :) Habe eine positive Bewertung.
Alconja
Das war interessant, unsere Punktzahlen waren den ganzen Weg so nah. +1.
Level River St
Funktioniert dies mit -M5.010(Strafe von 0, da es eine zu verwendende Sprachversion angibt) anstatt mit -e(Strafe von 1)? Möglicherweise können Sie ein Byte in den Argumenten speichern.
13

C, Rev. 2, 151 145 138

Inspiriert durch den 159-Byte-Code in @ bebes Kommentar, habe ich weitere 8 14 21 Zeichen herausgedrückt:

4 Bytes werden durch Umstellen des Längenzählers eingespart i. Dies wird auf 1 initialisiert (vorausgesetzt, das Programm akzeptiert keine Argumente) und dann bei jedem Lesen eines Buchstabens mit 4 multipliziert. Es läuft auf Null über, wenn die Wortlänge größer als 15 ist. Um zu überprüfen, ob die Wortlänge schlecht ist, überprüfen wir einfach, obi<5i<9 Um (ich setze es so , dass es für Ein-Buchstaben-Wörter immer noch ungültig ist, wenn der Benutzer versehentlich durch Setzen iauf 2 initialisiert ein einzelnes Argument in der Kommandozeile.)

4 Bytes gespart, indem der Schleifenbedingungstest auf einfach geändert wird &31 . Dies erfordert, dass das Wort mit einem Leerzeichen (ASCII 32) oder einem Nullzeichen (ASCII 0) abgeschlossen wird. Normalerweise wird die Tastatureingabe durch eine neue Zeile (ASCII 10) abgeschlossen, sodass die Verwendung des Programms etwas umständlich ist, da Sie das eingeben müssen Leerzeichen und dann die Eingabetaste drücken, damit der Computer den Puffer liest. Bei Strings mit Zeilenende könnte ich mithalten, aber nicht mithalten, wie ich es tue.

6 13 Bytes, die durch Ändern der Kodierung auf - (Anzahl der Kacheln für jeden Buchstaben) - (Punktzahl für diesen Buchstaben-1) * 13 gespeichert wurden . Dies erfordert jetzt einen Bereich von -4 für L, S, U bis -118 für Q, Z. Der Grund für die Verwendung negativer Zahlen ist die Vermeidung des nicht druckbaren ASCII-Bereichs 0 bis 31. Stattdessen wird der Bereich verwendet, der das Zweierkomplement der negativen Zahlen 256-4 = 252 bis 256-118 = 138 ist. Dies sind druckbare, erweiterte ASCII-Zeichen. Es gibt Probleme beim Kopieren und Einfügen dieser in Unicode (die Art und Weise, wie die Rückkehr zu ASCII vereinfacht wird, hängt von der installierten Codepage ab, was zu unvorhersehbaren Ergebnissen führen kann). Ich habe daher die richtigen ASCII-Codes in den Programmkommentar aufgenommen.

Der Vorteil dieser Kodierung ist die Eliminierung der Variablen, rda die Anzahl der Kacheln immer um 1 verringert wird (da sie als negative Zahl gespeichert wird, tun wir das t[x]++. Zusätzlich bedeutet der Postfix-Operator, dass wir diese Inkrementierung gleichzeitig mit ausführen können Hinzufügen der Partitur zu 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 (oder 172 mit Compiler-Option)

Ich verwende GCC und mit der Compiler-Option -std=c99kann ich char t[]="...."in die Initialisierung der forSchleife einsteigen, um ein zusätzliches Semikolon zu speichern. Aus Gründen der Lesbarkeit habe ich das Programm ohne diese Änderung und mit Leerzeichen angezeigt.

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

Der Trick liegt in der Datentabelle. Für jeden Buchstaben wird ein ASCII-Code der Form (Gesamtpunktzahl der Kacheln für diesen Buchstaben) * 10 + (Punktzahl einer Kachel-1) in der Tabelle gespeichert t[]. Zur Laufzeit werden diese Gesamtpunktzahlen reduziert, wenn die Kacheln aufgebraucht sind.

Die Gesamtpunktzahl aller Kacheln für jeden Buchstaben reicht von 12 für E bis 4 für L, S, U. Diese Form der Codierung ermöglicht nur die Verwendung von druckbaren ASCII-Zeichen (ASCII 120 xfür E bis ASCII 40 (für L, S, U). Die Verwendung der Anzahl der Kacheln würde einen Bereich von 120 bis 10 erfordern, weshalb ich vermieden es.

Dank eines #defineMakros Twird im Hauptprogramm ein einzelnes Symbol verwendet, um den Buchstabenindex iaus dem ersten Befehlszeilenargument abzurufen , ASCII A= 65 davon zu subtrahieren , um einen Index zu erhalten, und in der Tabelle T: nachzuschlagen t[x[1][i]-65].

Die forSchleife wird eher wie eine whileSchleife verwendet: Die Schleife endet, wenn in der Eingabezeichenfolge ein Null-Byte (Zeichenfolgen-Abschlusszeichen) angetroffen wird.

Wenn die Kacheln dieses Buchstabens nicht erschöpft sind ( T/10ungleich Null sind), swird sie um die Kachelpunktzahl erhöht T%10+1, um eine Gesamtpunktzahl zu erhalten. Gleichzeitig wird die Kachelbewertung in gespeichert r, so dass der Wert in der durch dargestellten Kachel Tum dekrementiert werden kann, r*10um anzuzeigen, dass eine Kachel verwendet wurde. Wenn die Kacheln erschöpft sind, wird der Platzhalter- / Leerzähler berhöht.

Die printfAussage ist ziemlich selbsterklärend. Wenn die Wortlänge außerhalb der Grenzen liegt oder die Anzahl der Leerzeichen zu hoch ist, drucken Sie, Invalidandernfalls drucken Sie die Partitur s.

Level River St
quelle
Da es jetzt ein anderer Tag ist, können Sie ein Zeichen speichern, indem Sie r + = (r == 7) * 3 durch r + = r-7? 0: 3 ersetzen. Auch brauchen Sie die Klammern um T- = r * 9, s + = r nicht.
Alchymist
@Alchymist Danke für den Tipp zu den Klammern, ich vergesse immer, dass es keine Probleme mit der Operator-Priorität zwischen ?und gibt :. Ihr anderer Punkt ist überholt, da ich die Codierung vollständig geändert habe, sodass keine besondere Behandlung von Q und Z erforderlich ist. Jetzt bis 173/172 mit Ihrer Hilfe.
Level River St
1
mit 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);}obwohl ich immer noch nicht verstehe, warum es char*foo=<string>abstürzt. es könnten 2 Zeichen gespart werden.
bebe
1
@bebe char*foo="string"ist ein String-Literal und sein Inhalt darf nicht geändert werden. Auf der anderen Seite char foo[]="string"wird ein Array von Zeichen erstellt, auf das initialisiert wird string\0und das dann geändert werden kann.
Es1024
@bebe cool, ich habe die Idee der Verwendung verpasst. getchar().Ich habe Ihre Verbesserungen am Code (mit meinen Variablennamen für die Konsistenz mit dem Rest meiner Antwort) sowie eine Verbesserung der Wortlängen-Gültigkeitsprüfung und eine freche Verbesserung der Schleifenbedingung verwendet Test (ich habe versucht , sie zu verkürzen, kann aber nicht so mit der gleichen Funktionalität tun.) ich habe auch versucht , getche()und getch()aber mein Compiler (gcc auf cygwin) würde sie nicht automatisch verknüpfen.
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)}

Bearbeiten - hat die Art und Weise geändert, wie ich die Mengen / Punktzahlen codiert habe, um die Größe zu verringern und nicht-ASCII-Variablen zu entfernen

Edit 2 - Ändert die Anzahl / Punktzahl-Codierungen in Ganzzahlen anstelle von Zeichenfolgen

Edit 3 - auf %13(danke @ edc65) umgestellt, die Codierung invertiert, die Werte direkt geändert und ein paar kleinere Verbesserungen vorgenommen

Getestet in der Firefox-Konsole.

Alconja
quelle
1
+1 sehr klug. Vorschläge: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2. warum nicht% 13
edc65
1
192 f = s => {für (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 - Danke vielmals. Hatte diesen ersten Trick nicht gesehen, habe ihn aber am Ende nicht verwendet, da ich die Werte jetzt direkt ändere (und sie mental für künftiges Golfen ablege). %13ist ein Geniestreich. Ich dachte nicht, ich müsse die Dinge in Ziffern speichern, aber Mathe kümmert sich nicht um den Unterschied zwischen base10 und base13.
Alconja
Nett! (Funktioniert nicht in Chrome Konsole, BTW: SyntaxError: Unexpected token >.)
DLosc
@DLosc - Ja, ich denke, Firefox ist derzeit der einzige Browser, der alle ECMAScript 6-Inhalte unterstützt (Chrome mag die f=s=>{...}Notation nicht).
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])

Edit: Danke an @BeetDemGuise für einen Tipp, der mich letztendlich zu weit mehr als einer 1-Zeichen-Reduzierung geführt hat! Originalcode unten:

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
quelle
Es ist ziemlich minimal, aber Sie können 1 Byte sparen, indem Sie Ihre Punktzahl-Zeichenfolge in hexadezimal codieren: int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise
4

BEFUNGE 93 - 210 Bytes.

Das 15-Buchstaben-Limit wird jedoch nicht überprüft.

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

C 197

Angenommen, die Zeichenfolge wird als Befehlszeilenargument bereitgestellt, z ./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);}
zimperliches Ossifrage
quelle
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)

zspeichert Wort. Ausgänge als Alarm.

Bearbeiten: Verbessert gemäß den folgenden Empfehlungen.

Matt
quelle
2
swird nur einmal verwendet, so dass Sie es nicht zu einer Variablen machen müssen; Sie können diese Erklärung entfernen und ersetzen r+=s[x]mit r+=-~"02210313074020029000033739"[x]. Außerdem benötigen Sie (w>2|y<2|y>15)in der Warnung keine runden Klammern .
NinjaBearMonkey
4

Haskell - 538

Speichern Sie es als scrabble.hs und kompilieren Sie es dann mit

ghc --make scrabble && ./scrabble

Geben Sie dann Ihr Wort als Eingabe ein und drücken Sie die Eingabetaste

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
quelle
Sie können viele Leerzeichen und in Haskell "[" A "," B "," C "] ==" ABC "entfernen. Außerdem können Sie für jede Einrückungsstufe nur ein Leerzeichen verwenden. Und Sie können kürzere Namen verwenden. Es gibt viel zum Golfen.
Ray
@ Ray Habe ich das getan, ich bin neu in Haskell, gibt es eine Möglichkeit, Ints-Listen übersichtlicher darzustellen als [1,2,3]?
Tuomas Laakkonen
"ABCDEFG"kann geschrieben werden als ['A'..'G'], [1,2,3]kann geschrieben werden als[1..3]
Ray
Wie erhalten Sie Ihre Byteanzahl? wc gibt mir über 500 Zeichen für Ihren Code.
TheSpanishInquisition
@TheSpanishInquisition Ich habe gerade ein Update für meine st3-Wortanzahl-Erweiterung erhalten. Der Autor hat die beiden Zahlen versehentlich vertauscht und sie auf 538
Tuomas Laakkonen,
3

Python 2.7 - 263

Ich konnte nicht annähernd an DLoscs Antwort herankommen , aber dies behandelt jeden Buchstaben als eine "Tasche", aus der Sie ziehen, bis er leer ist, und dann ziehen Sie Leerzeichen, und wenn das leer ist, macht es Fehler.

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"
Gemeinschaft
quelle
1
Dies ist ein ordentlicher Ansatz! Sie brauchen, raw_inputwenn es Python2 ist (eine Sache, die ich an Python3 mag). Die Eingabe erfolgt garantiert in Großbuchstaben. Entfernen Sie sie .lower()und ändern Sie sie 97+iin 65+i. Die Eingabe von weniger als 2 Zeichen muss ebenfalls ungültig sein. Sie können den Nullteilungsfehler ohne eine ifAussage erhöhen : Teilen Sie Ihre Gesamtpunktzahl durch (1<len(S)<16). Ein paar andere Optimierungen, wie das Setzen des prints in die gleiche Zeile wie die Blocküberschriften und das Löschen des Leerzeichens davor, "Invalid"bringen es nach meiner Zählung auf 250 herunter. :)
DLosc
2

Haskell, 290 283

So weit ich konnte:

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

Dieser Code hält sich strikt an die Regeln. Übergeben Sie also keine zusätzlichen Zeichen (z. B. Zeilenende). Verwenden Sie wie folgt:echo -n "JAZZ" | runghc scrabble.hs .

Erläuterung

Das Muster (_:_:_)stellt sicher, dass nur Zeichenfolgen mit mindestens zwei Zeichen berücksichtigt werden, alles andere ergibt sich "Invalid"(Fallback-Muster _). Die Kacheltabelle wird 11*nTiles+valuemit einem Versatz in ASCII konvertiert, der es dem Lookup-Modulo 11 ermöglicht, zu arbeiten, wobei die Buchstaben AEIOdupliziert werden, da sie mehr als sechsmal vorkommen. Der Fliesenpool wird dann mit erstelltreplicate , aus dem die Zeichen im Wort entfernt werden, sobald sie auftreten (Listendifferenz,\\). Der Pool enthält 98 Kacheln. Wenn also die Gesamtlänge des Wortes und der verbleibende Teil des Pools größer als 100 sind, haben wir zu viele Platzhalter verwendet. Außerdem wird das Wort abzüglich der ersten 15 Buchstaben dreimal zur Längenberechnung hinzugefügt, sodass jedes Wort, das länger als 15 Buchstaben ist, automatisch drei Platzhalterzeichen belegt und daher ungültig ist. Die Wertung erfolgt für den verbleibenden Pool, der ursprünglich 187 Punkte hatte, von denen wir einfach subtrahieren. Beachten Sie , dass 65 die ASCII-Nummer von ist , da sich das Duplikat am Anfang des Pools befindet. Der Rest ist nur Boilerplate.f 61 stattdessenf 65'A'"AEIO"

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

Lassen Sie uns die Bignums verwenden: D (Es behandelt derzeit keine Platzhalter, ich habe das Lesen dieser Regel ganz ausgelassen, verdammt)

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

Ich gehe davon aus, dass die Ausgabe von "Invalid"in Ordnung ist, wenn ich das nicht tun $><<(-b<1&&w.size<16?s:'Invalid')müsste, würde es auf 198 ansteigen


Clojure - 325

Ich habe seit einiger Zeit keine Clojure mehr durchgeführt, daher gibt es sicher verschiedene Möglichkeiten, um meine Lösung zu verbessern

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

Einige was Ungolfenes

(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
quelle
1

ES6: 184 (nicht streng)

wEs wird davon ausgegangen, dass das Wort bereits enthalten ist. rist die Ausgabezeichenfolge.

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"

Hier ist es erklärt und ein bisschen weniger 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
quelle
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");}

Dies erfordert Bignums, sodass keine Kompilierung mit JavaScript möglich ist.
Mit mehr Leerzeichen:

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
quelle
0

PHP, 180 170 168 Bytes

for($q=str_split(KDKKIAKJKDLLIKGEKLGIGIKKLKL);$o=31&ord($argv[1][$i++]);)$s+=$q[$o]++>L?$q[0]++>L?$f=1:0:X02210313074020029000033739[$o]+1;echo$f|$i<3|$i>16?Invalid:$s;

Yay! JS schlagen!

Nervenzusammenbruch

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

Ich bin so froh, dass es keinen Buchstaben gibt, der größer als 10 ist.

Titus
quelle