กำหนดคะแนน Scrabble และความถูกต้องของสตริง


24

งานของคุณคือการตรวจสอบว่าสายที่กำหนดมีความยาวที่เหมาะสมและสามารถแสดงด้วยกระเบื้อง Scrabble และถ้าเป็นเช่นนั้นเอาท์พุทผลรวมของคะแนนของตัวอักษรแต่ละตัว

หากคุณไม่ทราบวิธีการเล่น Scrabble: คุณมีไพ่ 100 ใบที่มีตัวอักษรต่าง ๆ A – Z พิมพ์อยู่รวมถึง wildcard สองใบที่สามารถใช้แทนตัวอักษรใดก็ได้ ตัวอักษรแต่ละตัวมีจำนวนแต้มที่แน่นอนและสามารถเรียงต่อกันได้ (แต่ไม่จำเป็นต้องใช้คำ) เมื่อเล่นคำศัพท์จะมีการเพิ่มค่าคะแนนของแต่ละไทล์ที่ใช้ซึ่งจะกลายเป็นคะแนน เนื่องจากมีจำนวน จำกัด ของตัวอักษรคำสามารถมีตัวอักษรบางตัวได้หลายครั้งตามที่ตัวอักษรนั้นมีไพ่ + สัญลักษณ์แทนที่ไม่ได้ใช้ Scrabble board มีขนาด 15 × 15 เซลล์ดังนั้นคำจะต้องมีความยาวระหว่าง 2 ถึง 15 ตัวอักษร

สำหรับรายการปริมาณและคะแนนของตัวอักษรแต่ละตัวในฉบับภาษาอังกฤษดูด้านล่างหรือhttp://boardgames.about.com/od/scrabble/a/tile_distribute.htm ( เก็บถาวร )

คะแนนตัวอักษรจำนวนคะแนนตัวอักษรจำนวน
------------------- -------------------
A 9 1 O 8 1
B 2 3 P 2 3
C 2 3 Q 1 10
D 4 2 R 6 1
E 12 1 S 4 1
F 2 4 T 6 1
G 3 2 U 4 1
H 2 4 V 2 4
ฉัน 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
ไม่มี 6 1

กฎเพิ่มเติม

  • โปรแกรมจะใช้สตริงอินพุตเดี่ยวจาก STDIN หรือสิ่งที่คล้ายกัน
  • ข้อมูลที่ป้อนจะประกอบด้วยตัวอักษรตัวพิมพ์ใหญ่เท่านั้น
  • ถ้า string มีสำเนาของตัวอักษรมากกว่าที่มีสัญลักษณ์ไม่ได้ใช้หรือกระเบื้องสำหรับจดหมายฉบับนั้นหรือความยาวของสายไม่ได้ระหว่าง 2 และ 15 Invalidรวมโปรแกรมควรเอาท์พุท
  • มิฉะนั้นควรเพิ่มคะแนนด้วยการใช้ข้อมูลจากแผนภูมิด้านบนและผลลัพธ์
  • อย่าใช้สัญลักษณ์แทนเว้นแต่จำเป็น
  • ไม่ต้องกังวลเกี่ยวกับโบนัสเช่นคะแนนคำคู่หรือว่าสตริงเป็นคำจริง
  • โปรแกรมจะแสดงผลลัพธ์ผ่าน STDOUT หรือที่คล้ายกัน
  • ช่องโหว่ที่ถูกห้ามโดยค่าเริ่มต้นจะไม่ได้รับอนุญาต
  • การใช้แหล่งข้อมูลภายนอกเช่นเว็บไซต์เช่นเดียวกับไลบรารี APIs ฟังก์ชั่นหรือสิ่งที่คล้ายกันที่คำนวณคะแนน Scrabble หรือปริมาณที่เหมาะสมจะไม่ได้รับอนุญาต
  • นี่คือซึ่งมีจำนวนน้อยที่สุดที่จะชนะ

เกมส์

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

อินพุตเอาต์พุต
------------------------
SCRABBLE 14
JAZZ 19
STACKEXCHANGE 32
XYWFHQYVZVJKHFW 81
PIZZAZZ ไม่ถูกต้อง
KIXOKEJAJAX ไม่ถูกต้อง
MISUNDERSTANDING ไม่ถูกต้อง

5
อาจต้องการเพิ่มกรณีทดสอบสำหรับคำที่ถูกต้องซึ่งใช้ wild cards (เช่น JAZZ = 19 ไม่ใช่ 29)
Alconja

2
คุณรู้ไหมว่าความท้าทายนี้จะยิ่งเลวร้ายไปกว่านั้นถ้ามันเกี่ยวข้องกับภาษาที่ไพ่แบบสแครบเบิลไม่สามารถแสดงด้วยตัวละครเดียวเช่นสเปนบาสก์ฮังการีฮังการีตูวานหรือเวลส์
0721090601

จำเป็นต้องมีคำตอบเฉพาะสำหรับการส่งออก "ไม่ถูกต้อง" หรือเราอาจเลือกพฤติกรรมใด ๆ ตราบใดที่ไม่ใช่คะแนนอย่างชัดเจนหรือไม่? ยกตัวอย่างเช่น-1?
Kamil Drakari

@KamilDrakari Invalidมันต้องบอกว่า
NinjaBearMonkey

คำตอบ:


15

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

ทำงานด้วย perl -E

แข็งแรงเล่นกอล์ฟ:

$_=<>;@a=@b=map-ord,'            0 0@0 H        ``'=~/./g;say s!.!($a[$q=64-ord$&]+=8)<8?$-+=1-29/$b[$q]:++$j!ge~~[2..15]&&$j<3?$-:Invalid

วิธีการแก้ปัญหานี้ใช้อักขระที่ไม่สามารถพิมพ์ได้ดังนั้น hexdump จึงมีให้ด้านล่าง:

00000000: 245f 3d3c 3e3b 4061 3d40 623d 6d61 702d  $_=<>;@a=@b=map-
00000010: 6f72 642c 2703 0904 0909 2030 2030 030e  ord,'..... 0 0..
00000020: 4030 0e20 0704 4809 1809 601d 0e0e 6027  @0. ..H...`...`'
00000030: 3d7e 2f2e 2f67 3b73 6179 2073 212e 2128  =~/./g;say s!.!(
00000040: 2461 5b24 713d 3634 2d6f 7264 2426 5d2b  $a[$q=64-ord$&]+
00000050: 3d38 293c 383f 242d 2b3d 312d 3239 2f24  =8)<8?$-+=1-29/$
00000060: 625b 2471 5d3a 2b2b 246a 2167 657e 7e5b  b[$q]:++$j!ge~~[
00000070: 322e 2e31 355d 2626 246a 3c33 3f24 2d3a  2..15]&&$j<3?$-:
00000080: 496e 7661 6c69 64                        Invalid

อีกทางเลือกหนึ่งโดยใช้ Ctrl + Key:

$_=<>;@a=@b=map-ord,'^C^I^D^I^I 0 0^C^N@0^N ^G^DH^I^X^I`^]^N^N`'=~/./g;print s!.!($a[$q=64-ord$&]+=8)<8?$-+=1-29/$b[$q]:++$j!ge~~[2..15]&&$j<3?$-:Invalid

Ungolfed + แสดงความคิดเห็น:

# Read in input
$_=<>;
# @a and @b: represents approximately 8x the number of tiles (when rounded up). The 
#   non-multiple-of-8 values distinguish tiles that are given equally, but are worth
#  different values
@b=@a=map-ord,"...."~=/./g;
# above is equivalent to
# @a=@b=(-03,-09,-04,-09,-09,-32,-48,-32,-48,-03,-14,-64,-48,-14,-32,-07,-04,-72,-09,-24,-09,-96,-29,-14,-14,-96);
say
    # for each character
    s!.!
        # $q: A->-1, B->-2, etc.
        # decrement number of $q tiles, add points if needed, otherwise
        #    increment j, which counts number of wilds used
        # truncate(1-29/b[q]): decimal values were chosen specifically
        #    for this to return the point value. b[q] is the number of tiles
        #    of the qth letter after a originally given.
        #  $- contains the score, is initially zero (if in a one line program, 
        #   as the golfed version is), and is always an integer
        ($a[$q=64-ord$&]+=8)<8 ? $- += 1 - 29/$b[$q] : ++$j
    # s returns length, check if between 2 and 15
    !ge ~~ [2..15]
    # make sure less than 3 negative tiles (aka wilds) 
    && $j < 3 ?
        # print score
        $-
    # or invalid
    : Invalid

1
คุณสามารถบีบอย่างน้อย 20 ไบต์จากอาร์เรย์เหล่านั้นด้วยการจัดการที่สร้างสรรค์
Sparr

1
Gah อยู่ข้างหน้าฉันเสมอหนึ่งก้าว :) มี upvote
Alconja

สิ่งนี้น่าสนใจคะแนนของเราใกล้เคียงกันมาก +1
เลเวลริเวอร์เซนต์

ใช้งานได้กับ-M5.010(ปรับเป็น 0 เพราะระบุรุ่นของภาษาที่จะใช้) แทน-e(ปรับ 1)? คุณอาจบันทึกไบต์ในอาร์กิวเมนต์ได้

13

C, Rev 2, 151 145 138

แรงบันดาลใจจากรหัส 159 ไบต์ในความคิดเห็นของ @ bebe ฉันบีบอีก8 14 21 ตัวอักษร:

บันทึกได้ 4 ไบต์โดยจัดเรียงตัวนับความยาวiใหม่ นี่คือการเริ่มต้นที่ 1 (สมมติว่าโปรแกรมจะไม่ขัดแย้ง) แล้วคูณด้วย 4 ทุกครั้งที่อ่านจดหมาย มันล้นไปเป็นศูนย์เมื่อความยาวของคำมากกว่า 15 ดังนั้นเพื่อตรวจสอบว่าความยาวของคำไม่ดีเราเพียงตรวจสอบว่าi<5(ฉันใส่i<9ดังนั้นมันจะยังคงไม่ถูกต้องสำหรับคำหนึ่งตัวอักษรถ้าผู้ใช้ตั้งใจ intialises iถึง 2 โดยการใส่ อาร์กิวเมนต์เดียวในบรรทัดคำสั่ง)

4 &31ไบต์ที่บันทึกไว้โดยการเปลี่ยนสภาพการทดสอบวงที่เรียบง่าย สิ่งนี้ต้องการให้คำนั้นถูกยกเลิกด้วยช่องว่าง (ASCII 32) หรืออักขระ null (ASCII 0) โดยปกติแล้วการป้อนข้อมูลด้วยแป้นพิมพ์จะถูกยกเลิกโดยบรรทัดใหม่ (ASCII 10) ดังนั้นโปรแกรมจึงใช้งานไม่สะดวกเนื่องจากคุณต้องพิมพ์ เว้นวรรคแล้วกด return เช่นกันเพื่อให้คอมพิวเตอร์อ่านบัฟเฟอร์ สำหรับสตริงที่ขึ้นบรรทัดใหม่ฉันสามารถจับคู่ แต่ไม่สามารถเอาชนะได้ด้วยวิธีที่ bebe ทำ

6 13 ไบต์ที่บันทึกไว้โดยการเปลี่ยนการเข้ารหัสเพื่อ- (จำนวนกระเบื้องของแต่ละตัวอักษร) - (คะแนนที่ตัวอักษร ตอนนี้ต้องมีช่วงจาก -4 สำหรับ L, S, U ถึง -118 สำหรับ Q, Z เหตุผลในการใช้จำนวนลบคือเพื่อหลีกเลี่ยงช่วง ASCII ที่ไม่สามารถพิมพ์ได้ 0 ถึง 31 แต่ช่วงที่ใช้คือส่วนเติมเต็มของตัวเลขลบทั้งสอง 256-4 = 252 ถึง 256-118 = 138 เหล่านี้เป็นอักขระ ASCII ที่พิมพ์ได้และขยายออกไป มีปัญหาเกี่ยวกับการคัดลอกและวางสิ่งเหล่านี้ใน Unicode (วิธีที่ทำให้กลับสู่ ASCII ง่ายขึ้นอยู่กับหน้ารหัสที่ติดตั้งซึ่งสามารถนำไปสู่ผลลัพธ์ที่ไม่คาดคิด) ดังนั้นฉันจึงได้รวมรหัส ASCII ที่ถูกต้องในความคิดเห็นของโปรแกรม

ข้อได้เปรียบของการเข้ารหัสนี้คือการกำจัดของตัวแปรrเนื่องจากจำนวนของไพ่จะลดลง 1 เสมอ (เนื่องจากมันถูกเก็บไว้เป็นจำนวนลบเราทำได้t[x]++นอกจากนี้ตัวดำเนินการ postfix หมายความว่าเราสามารถทำการเพิ่มได้ในเวลาเดียวกัน sการเพิ่มคะแนนไป

//char t[]={32,247,228,228,239,244,215,240,215,247,164,203,252,228,250,248,228,138,250,252,250,252,215,215,164,215,138,0};
b,s;
main(i,x){
  for(char t[]=" ÷ääïô×ð×÷¤ËüäúøäŠúüúü×פ׊";x=getchar()&31;i*=4)
    t[x]%13?
      s-=t[x]++/13-1:
      b++;
  printf(i<9|b>2?"Invalid":"%d",s);
} 

C, 184 Rev 1 173 (หรือ 172 พร้อมตัวเลือกคอมไพเลอร์)

ฉันกำลังใช้ GCC และด้วยตัวเลือกคอมไพเลอร์-std=c99มันจะช่วยให้ฉันย้ายไปchar t[]="...."สู่การเริ่มต้นของforลูปเพื่อประหยัดเซมิโคลอนเพิ่มเติมอีกหนึ่งตัว เพื่อความสะดวกในการอ่านฉันได้แสดงโปรแกรมโดยไม่มีการเปลี่ยนแปลงและมีช่องว่างเหลืออยู่

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

เคล็ดลับอยู่ใน DataTable สำหรับแต่ละตัวอักษรรหัส ASCII ของแบบฟอร์ม(คะแนนรวมของกระเบื้องจดหมายนั้น) * 10 + (คะแนนกระเบื้อง-1)t[]จะถูกเก็บไว้ในตาราง ที่รันไทม์คะแนนรวมเหล่านี้จะลดลงเมื่อไทล์หมดแล้ว

คะแนนรวมของไพ่ทั้งหมดสำหรับแต่ละตัวอักษรมีตั้งแต่ 12 ถึง E ถึง 4 สำหรับ L, S, U การเข้ารหัสรูปแบบนี้ช่วยให้สามารถใช้อักขระ ASCII ที่พิมพ์ได้เท่านั้น (ASCII 120, xสำหรับ E ถึง ASCII 40, (สำหรับ L, S, U.) การใช้จำนวนแผ่นจะต้องมีช่วงตั้งแต่ 120 ถึง 10 ซึ่งเป็นเหตุผลที่ฉัน หลีกเลี่ยงมัน

ขอขอบคุณที่#defineแมโครสัญลักษณ์เดียวTที่ใช้ในโปรแกรมหลักเพื่อดึงดัชนีจดหมายiจากอาร์กิวเมนต์ commandline แรก ASCII ลบA= 65 จากมันเพื่อให้ดัชนีและมองมันได้ใน T t[x[1][i]-65]ตาราง:

การforวนซ้ำถูกใช้มากขึ้นเช่นการwhileวนซ้ำ: การวนซ้ำจะสิ้นสุดลงเมื่อพบศูนย์ไบต์ (ตัวลงท้ายสตริง) ในอินพุตสตริง

หากไทล์ของตัวอักษรนั้นไม่หมด ( T/10ไม่ใช่ศูนย์) sจะเพิ่มขึ้นด้วยคะแนนไทล์T%10+1เพื่อเก็บคะแนนรวม ในเวลาเดียวกันคะแนนกระเบื้องจะถูกเก็บไว้ในrเพื่อให้ค่าในความสามารถแทนโดยTสามารถลดลงโดยr*10เพื่อระบุว่ามีการใช้กระเบื้องหนึ่ง หากไทล์หมดแล้วตัวนับ / ว่างเปล่าbจะเพิ่มขึ้น

printfงบค่อนข้างอธิบายตนเอง ถ้า wordlength อยู่นอกขอบเขตหรือนับว่างเปล่าที่สูงเกินไปพิมพ์ตัวเลขที่มิฉะนั้นพิมพ์คะแนนInvalids


เนื่องจากเป็นอีกวันหนึ่งคุณสามารถบันทึกอักขระหนึ่งตัวโดยแทนที่ r + = (r == 7) * 3 ด้วย r + = r-7? 0: 3 นอกจากนี้คุณไม่จำเป็นต้องใช้เครื่องหมายวงเล็บรอบ T- = r * 9, s + = r
เล่นแร่แปรธาตุ

ขอบคุณ @Alchymist สำหรับเคล็ดลับเกี่ยวกับวงเล็บที่ฉันมักจะลืมว่ามีปัญหาใด ๆ กับผู้ประกอบการมีความสำคัญระหว่างและ? :จุดอื่นของคุณถูกแทนที่เนื่องจากฉันได้เปลี่ยนการเข้ารหัสอย่างสมบูรณ์ดังนั้นจึงไม่จำเป็นต้องจัดการ Q และ Z เป็นพิเศษอีกต่อไปจนถึง 173/172 ด้วยความช่วยเหลือของคุณ
เลเวลริเวอร์เซนต์

1
ด้วยgetchar()159: l,w,f;main(t,i){for(char b[]="Z>>QxS=SZW6(><P>m<(<(SSWSm";(i=getchar()-65)>=0;l++)b[i]/10?f+=t=b[i]%10+1,b[i]-=t*10:w++;printf(l<2|l>15|w>2?"Invalid":"%d",f);}แม้ว่าฉันยังไม่เข้าใจว่าทำไมจึงchar*foo=<string>ขัดข้อง มันสามารถบันทึก 2 ตัวอักษร
bebe

1
@bebe char*foo="string"เป็นตัวอักษรสตริงและเนื้อหาไม่ได้รับอนุญาตให้แก้ไข ในอีกทางหนึ่งchar foo[]="string"สร้างอาร์เรย์ของตัวอักษรเริ่มต้นstring\0ซึ่งอาจมีการแก้ไข
es1024

@bebe cool ฉันคิดถึงความคิดในการใช้getchar().ฉันใช้การปรับปรุงโค้ดของคุณ (ด้วยชื่อตัวแปรของฉันสำหรับความสอดคล้องกับคำตอบที่เหลือ) บวกกับการปรับปรุงการตรวจสอบความถูกต้องของ wordlength และการปรับปรุงหน้าตาของเงื่อนไขลูป ทดสอบ (ฉันพยายามทำให้สั้นลง แต่ไม่สามารถทำได้ด้วยฟังก์ชั่นเดียวกัน) ฉันลองgetche()แล้วและgetch()คอมไพเลอร์ของฉัน (gcc บน cygwin) จะไม่เชื่อมโยงมันโดยอัตโนมัติ
เลเวลริเวอร์เซนต์

5

JavaScript (ES6) - 241 230 199 182

f=s=>{for(i=t=_=0,E=12,A=I=9,B=C=M=P=28,D=17,F=H=V=W=Y=41,G=16,J=X=92,K=53,L=S=U=4,N=R=T=6,O=8,Q=Z=118;c=s[i++];)this[c]%13<1?_++:t+=1+this[c]--/13|0;alert(i<3|i>16|_>2?"Invalid":t)}

แก้ไข - เปลี่ยนวิธีที่ฉันเข้ารหัสปริมาณ / คะแนนเพื่อลดขนาดและลบตัวแปรที่ไม่ใช่ ASCII

แก้ไข 2 - เปลี่ยนการเข้ารหัสปริมาณ / คะแนนเป็นจำนวนเต็มแทนที่จะเป็นสตริง

แก้ไข 3 - เปลี่ยนเป็น%13(ขอบคุณ @ edc65) สลับการเข้ารหัสปรับเปลี่ยนค่าโดยตรงและการปรับปรุงเล็กน้อยอื่น ๆ

ทดสอบในคอนโซล Firefox


1
+1 ฉลาดมาก คำแนะนำ: 1. f[c]=1+f[c]||1-> f[c]=-~f[c], 2. ทำไมไม่ใช้% 13
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 = R = T = 6, O = 8, Q = Z = 118 $ = 2 t = i = 0; c = s [ผม ++ ];) (ฉ [C] = - ~ ฉ [C])> (L = นี้ [C])% 13 - $: T + = ลิตร / 13 + 1 | 0; แจ้งเตือน (i <3 | i> 16 | $ <0? "ไม่ถูกต้อง": t)}
edc65

@ edc65 - ขอบคุณมาก ไม่เห็นเคล็ดลับแรกนั้น แต่ไม่ได้ใช้เพราะฉันกำลังแก้ไขค่าโดยตรงในขณะนี้ %13เป็นจังหวะของอัจฉริยะแม้ว่า ฉันคิดว่าฉันต้องเก็บของเป็นตัวเลข แต่คณิตศาสตร์ไม่สนใจความแตกต่างระหว่าง base10 กับ base13
Alconja

ดี! (ใช้งานไม่ได้ในคอนโซลของ Chrome, BTW SyntaxError: Unexpected token >
:.

@DLosc - ใช่ฉันคิดว่า Firefox เป็นเบราว์เซอร์เดียวในขณะนี้ที่รองรับ ECMAScript 6 ทุกสิ่ง (Chrome ไม่ชอบf=s=>{...}สัญลักษณ์)
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])

แก้ไข:ขอบคุณ @BeetDemGuise สำหรับเคล็ดลับที่นำฉันไปสู่การลดลงมากกว่า 1 ตัวอักษรในที่สุด! รหัสเดิมด้านล่าง:

q=[77-ord(x)for x in'DKKIAKJKDLLIKGEKLGIGIKKLKL'];b=2;s=0;w=input()
for c in set(w):n=w.count(c);o=ord(c)-65;b-=max(0,n-q[o]);s+=min(n,q[o])*(1+int('02210313074020029000033739'[o]))
print(["Invalid",s][-b<1<len(w)<16])

ค่อนข้างน้อย แต่คุณสามารถบันทึก 1byte โดยการเข้ารหัสสตริงคะแนนของคุณในฐานสิบหก: int('1332142418513113a11114484a'[o],16) :)
BeetDemGuise

4

ก่อนหน้านี้ 93 - 210 ไบต์

แต่ไม่ได้ตรวจสอบขีด จำกัด 15 ตัวอักษร

v1332142418513113:11114484: >01g:"0"-!#v_1-01p1+\v
 9224<232911426821646422121v  "Invalid"<      vp0<
<vp00p10"20"p200p900
>>~:55+-!#v_"@"-::1g:"0"-! #^_1-\1p0g+"0"-02g+>02p
_v#:-1<    #p90+g90-"0"g1:<
     @.g20<        @,,,,,,,<

4

C, 197

ถือว่าสตริงนั้นมีให้เป็นอาร์กิวเมนต์บรรทัดคำสั่งเช่น ./scrabble STACKEXCHANGE

s;n;m=31;main(int c,char**v){char d[]="BIBBDLBCBIAADBFHBAFDFDBBABA@ACCBADBDAHEACAACJAAAADDHDJ";for(;c=*v[1]++&m;d[c]--,s+=d[c+27]&m)n+=1+m*(!(d[c]&m||d[c=0]&m));printf(n>1&&n<16?"%d":"Invalid",s);}

4

JavaScript - 232 201

t=[9,2,2,4,12,2,3,2,9,1,1,4,2,6,8,2,1,6,4,6,4,2,2,1,2,1];w=r=0;for(i=y=z.length;i--;){x=z.charCodeAt(i)-65;if(!t[x])w++;else{t[x]--;r+=-~"02210313074020029000033739"[x]}}alert(w>2|y<2|y>15?"Invalid":r)

zเก็บคำ เอาต์พุตแจ้งเตือน

แก้ไข:ปรับปรุงตามคำแนะนำด้านล่าง


2
sใช้เพียงครั้งเดียวดังนั้นคุณไม่จำเป็นต้องทำให้มันเป็นตัวแปรเลย คุณสามารถลบประกาศที่และแทนที่ด้วยr+=s[x] r+=-~"02210313074020029000033739"[x]นอกจากนี้คุณไม่จำเป็นต้องใช้วงเล็บ(w>2|y<2|y>15)ในการแจ้งเตือน
NinjaBearMonkey

4

Haskell - 538

บันทึกเป็น scrabble.hs จากนั้นรวบรวมโดยใช้

ghc --make scrabble && ./scrabble

จากนั้นป้อนคำของคุณเป็นอินพุตแล้วกด Enter

l=['A'..'Z']
sc=zip l [1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10]
vfs a y =snd $ filter (\x -> fst x == y) a !! 0
q = zip l [9,2,2,4,12,2,3,2,9,1,1,4,2,6,8,2,1,6,4,6,4,2,2,1,2,1]
i s =filter (\x -> (fst x) >=0) [(length [x | x <- s, x == a] - vfs q a,a) | a <- l]
main = do
 s <- getLine
 if length s <= 15 && length s > 2 && sum (map fst (i s)) <= 2 then
  putStrLn $ show (sum [vfs sc x| x <- s] - sum [(vfs sc (snd x)) * (fst x) | x <- (filter (\x -> fst x > 0) (i s))])
 else do
  putStrLn "Invalid"

คุณสามารถลบช่องว่างจำนวนมากและใน Haskell `['A', 'B', 'C'] ==" ABC " นอกจากนี้คุณสามารถใช้เพียงหนึ่งช่องว่างสำหรับแต่ละระดับของการเยื้อง และคุณสามารถใช้ชื่อที่สั้นกว่านี้ได้ มีจำนวนมากสำหรับการเล่นกอล์ฟ
เรย์

@ Ray ได้ทำแล้วฉันยังใหม่กับ Haskell มีวิธีแสดงรายการ Ints ที่กระชับกว่า [1,2,3] หรือไม่?
Tuomas Laakkonen

"ABCDEFG"สามารถเขียนเป็น['A'..'G'], [1,2,3]สามารถเขียนเป็น[1..3]
เรย์

คุณจะได้รับจำนวนไบต์ของคุณได้อย่างไร? ห้องสุขาให้ฉันมากกว่า 500 ตัวอักษรสำหรับรหัสของคุณ
TheSpanishInquisition

@TheSpanishInquisition เพิ่งได้รับการอัปเดตสำหรับส่วนขยายการนับคำ st3 ของฉันผู้เขียนได้เปลี่ยนการนับทั้งสองโดยไม่ได้ตั้งใจแก้ไขไปที่ 538
Tuomas Laakkonen

3

Python 2.7 - 263

ฉันไม่สามารถเข้าใกล้คำตอบของ DLoscได้ทุกที่แต่สิ่งนี้ถือว่าตัวอักษรแต่ละตัวเป็น 'กระเป๋า' ที่คุณดึงมาจนกระทั่งมันว่างเปล่าจากนั้นคุณก็ดึงช่องว่างและเมื่อมันว่างเปล่ามันผิดพลาด

S=input().lower()
X={chr(97+i):[int(y)+1]*(77-ord(x))for i,(x,y)in enumerate(zip('DKKIAKJKDLLIKGEKLGIGIKKLKL','02210313074020029000033739'))}
B=[0,0]
try:
 if len(S)>15:1/0
 print sum(map(lambda x:X[x].pop()if len(X[x])>0 else B.pop(),S))
except:
 print "invalid"

1
นี่เป็นวิธีที่เรียบร้อย! คุณต้องการraw_inputถ้าเป็น Python2 (สิ่งหนึ่งที่ฉันชอบเกี่ยวกับ Python3) การป้อนข้อมูลที่มีการประกันตัวพิมพ์ใหญ่เพื่อลบ.lower()และการเปลี่ยนแปลงไป97+i 65+iอินพุตที่น้อยกว่า 2 ตัวอักษรต้องไม่ถูกต้องเช่นกัน คุณสามารถเพิ่มศูนย์ข้อผิดพลาดส่วนโดยไม่ต้องมีifคำสั่ง: (1<len(S)<16)แบ่งคะแนนรวมของคุณโดย การปรับแต่งอื่น ๆ สองสามอย่างเช่นการวางprints ในบรรทัดเดียวกับส่วนหัวของบล็อกและการลบพื้นที่ก่อนที่จะ"Invalid"นำมันลงมาที่ 250 โดยการนับของฉัน :)
DLosc

2

Haskell, 290 283

เท่าที่ฉันทำได้ตอนนี้:

import Data.List
t="CdC8d::Od;D;d41N:dd:6dNdN;;4;6"
s w@(_:_:_)=let d=concat(zipWith(replicate.(`div`11).f 33)t("AEIO"++['A'..]))\\w;y=drop 15w in if length(d++w++y++y++y)>100 then s""else show$187-(sum$map((`mod`11).f 0.(t!!).f 61)d)
s _="Invalid"
f n=(-n+).fromEnum
main=interact s

รหัสนี้ปฏิบัติตามกฎอย่างเคร่งครัดดังนั้นโปรดตรวจสอบให้แน่ใจว่าคุณไม่ผ่านตัวอักษรพิเศษใด ๆ (เช่นจุดสิ้นสุดของบรรทัด) ใช้แบบนี้:echo -n "JAZZ" | runghc scrabble.hs .

คำอธิบาย

รูปแบบ(_:_:_)ตรวจสอบให้แน่ใจว่ามีการพิจารณาเฉพาะสตริงที่มีอักขระอย่างน้อยสองตัวเท่านั้นซึ่งจะมีผลลัพธ์อื่น ๆ"Invalid"(รูปแบบทางเลือก_) ตารางของไพ่ถูกเข้ารหัสเป็น11*nTiles+valueแปลงเป็น ASCII ด้วยออฟเซ็ตที่ทำให้การค้นหาโมดูโล 11 ทำงานได้โดยที่ตัวอักษรAEIOจะถูกทำซ้ำเพราะมันเกิดขึ้นมากกว่า 6 ครั้งในแต่ละครั้ง สระว่ายน้ำของกระเบื้องถูกสร้างขึ้นโดยใช้replicateซึ่งตัวละครในคำจะถูกลบออกเมื่อเกิดขึ้น (ความแตกต่างของรายการ\\) พูลมี 98 ไทล์ดังนั้นหากความยาวทั้งหมดของคำและส่วนที่เหลือของพูลนั้นใหญ่กว่า 100 เราจะใช้ไวด์การ์ดมากเกินไป นอกจากนี้คำที่ลบด้วยตัวอักษร 15 ตัวแรกจะถูกเพิ่มเข้ากับการคำนวณความยาวสามครั้งดังนั้นคำใดก็ตามที่มีความยาวเกินกว่า 15 ตัวอักษรจะปรากฏขึ้นโดยอัตโนมัติเพื่อใช้อักขระตัวแทนสามตัวโดยอัตโนมัติ การให้คะแนนจะทำในสระว่ายน้ำที่เหลือซึ่งเริ่มแรกมี 187 คะแนนซึ่งเราจะลบออกจาก สังเกตf 61มากกว่าf 6565 เป็นหมายเลข ASCII 'A'เนื่องจากซ้ำกัน"AEIO"ที่จุดเริ่มต้นของพูล ส่วนที่เหลือเป็นเพียงแผ่นสำเร็จรูป


1

Python3 - 197

s,i,c,r=input(),0x1a24182424416141611a2381612341151891243224c142232391,[],[]; p=len(s)
for w in s:e=8*ord(w)-520;c+=[s.count(w)<=i>>e+4&15];r+=[i>>e&15]
print(['Invalid',sum(r)][all([p>2,p<15]+c)])

เราจะนำ bignums มาใช้: D (ปัจจุบันยังไม่รองรับ wildcard, ฉันข้ามการอ่านกฎนั้นไปเลย)


1

ทับทิม - 195

b=2
i=s=0
w=$*[0]
(?A..?Z).map{|l|n=w.count(l);q='9224c232911426821646422121'[i].to_i(16);b-=[0,n-q].max;s+=[n,q].min*'1332142418513113a11114484a'[i].to_i(16);i+=1}
p(-b<1&&w.size<16?s:'Invalid')

ฉันสมมติว่าผลลัพธ์ของ"Invalid"มันก็ดีถ้าไม่ฉันก็ต้องทำ$><<(-b<1&&w.size<16?s:'Invalid')ซึ่งจะชนได้ถึง 198


Clojure - 325

ฉันยังไม่ได้ปิดบังในขณะที่ดังนั้นฉันแน่ใจว่ามีหลายวิธีในการปรับปรุงการแก้ปัญหาของฉันคือรายการ qty และ pts

(let[w(first *command-line-args*)o(map #(count(filter #{%}(seq w)))(map char(range 65 91)))i(apply +(filter neg?(map #(- % %2)'(9 2 2 4 12 2 3 2 9 1 1 4 2 6 8 2 1 6 4 6 4 2 2 1 2 1) o)))](println(if(or(> -2 i)(not(<= 2(count w)15)))"Invalid"(apply +(map #(* % %2)o'(1 3 3 2 1 4 2 4 1 8 5 1 3 1 1 3 10 1 1 1 1 4 4 8 4 10))))))

บางสิ่งที่ 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)))

1

ES6: 184 (ไม่เข้มงวด)

wจะถือว่ามีคำอยู่แล้ว rคือสตริงเอาต์พุต

i=0,o=[..."291232342c124322491181541236181231a61416141242418241a"].map(c=>parseInt(c,16)),r=!w[16]&&w[2]&&[...w].every(c=>o[c=c.charCodeAt()*2-129]-->0?i+=o[c+1]:o[0]--)?i+"":"Invalid"

นี่คือคำอธิบายและมี golfed น้อย:

// The sum.
i = 0,

// The data for the letters. It's encoded similar to the Ruby version, with
// the first being the wildcard holder. The rest hold in hex form the
// following: first = quantity left, second = value.
// The .map(c => parseInt(c, 16) simply parses all the hex characters.
o = [..."291232342c124322491181541236181231a61416141242418241a"]
  .map(c => parseInt(c, 16)),

// The result, `r`.
r = !w[16] || // If there is a 16th character in the word or no 2nd character,
    w[2] &&   // then the next section isn't evaluated. It immediately equates
              // to true, thus returning "Invalid".
   [...w] // Convert the string into an array of characters (ES6 equivalent to
          // `.split('')`
    .every(c => // This loop terminates when the callback returns a falsy
                // value.
      // Gets the ASCII value, subtracts 65, doubles it (the lookup table is
      // in pairs within one array), and decrements the counter at that entry.
      // The lookup table also doubles as a data holder.
      o[c = c.charCodeAt() * 2 - 129]--
        > 0 ?  // Test if there is something to take away. This must return
               // false at 0 and -1 so wildcards can be taken.
        i += o[c+1] : // If there was something to take away, then add the
                      // letter value to the sum.
        o[0]--) // Otherwise, take a wildcard. If this is already at 0, then
                // it returns falsy.
      ? "Invalid" : i + "" // This is where the text is returned.

1

โผ - 201

main(a,{x:0xa14281424214161416a132181632145181194223421c24323219,i,r:0,m,s:2}){if((m=a[0].length)>1&&m<16)for(i in a[s=0].codeUnits)x>>(m=i*8-520)&15>0?r+=(x-=1<<m)>>m+4&15:++s;print(s<2?r:"Invalid");}

สิ่งนี้ต้องใช้ bignums ดังนั้นจึงไม่ได้รวบรวม JavaScript
ด้วยพื้นที่ว่างเพิ่มเติม:

main(a,{x:0xa14281424214161416a132181632145181194223421c24323219,i,r:0,m,s:3}){
  if((m=a[0].length)>1&&m<16)
    for(i in a[s=0].codeUnits)
      x>>(m=i*8-520)&15>0
      ? r+=(x-=1<<m)>>m+4&15
      : ++s;
  print(s<3?r:"Invalid");
}

0

PHP, 180 170 168 ไบต์

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

เย้! เต้น JS!

ทำให้พังถล่ม

for(
    $q=str_split(KDKKIAKJKDLLIKGEKLGIGIKKLKL);  // init quantities: L=1,A=12
    $o=31&ord($argv[1][$i++]);                  // loop through characters: map to [1..26]
)
    $s+=                                          // increase score by ...
        $q[$o]++>L?                                 // old quantity below 1?
        $q[0]++>L?$f=1                              // no more wildcards? set error flag
        :0                                          // wildcard: 0 points
        :X02210313074020029000033739[$o]+1;         // else: letter score
echo$f|$i<3|$i>16?Invalid:$s;                   // output

ฉันดีใจมากที่ไม่มีคะแนนตัวอักษรมากกว่า 10

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.