Scrabble scorer

42

0

Challenge:

Take a string of upper or lower case letters as input (optional), and calculate the score that string would get in a game of Scrabble in English.

Rules:

The score of each letter is as follows (use this even if there are other versions of the game):

1 point: E, A, I, O, N, R, T, L, S, U
2 points: D, G
3 points: B, C, M, P
4 points: F, H, V, W, Y
5 points: K
8 points: J, X
10 points: Q, Z

The score of a string is simply the sum of the scores of each of the letters used. You may assume that you have plenty of tiles available, so long words, and words with many of the same letters are valid input.

Test cases:

ABC       ->    7
PPCG      ->   11
STEWIE    ->    9
UGPYKXQ   ->   33
FIZZBUZZ  ->   49
ABCDEFGHIJKLMNOPQRSTUVWXYZ  -> 87

The shortest answer in each language wins! The input and output formats are flexible, so you may take the input as an array of characters (upper or lower case) if you want.

Stewie Griffin

Posted 2018-04-17T18:53:45.610

Reputation: 43 471

6I'm hoping to see a MATLAB/Octave solution. All my attempts were horribly long... =/ – Stewie Griffin – 2018-04-17T19:04:37.053

4I'm hoping to see a Beatnik solution. Cuz, you know, that would be the right tool for the job. – Giuseppe – 2018-04-17T19:28:16.417

@StewieGriffin Does 85 bytes count as horribly long? – Luis Mendo – 2018-04-17T21:11:06.003

3Hasn't Mathematica a built-in for it? – sergiol – 2018-04-18T00:30:44.820

@StewieGriffin Down to 73 with Octave now. – Tom Carpenter – 2018-04-18T06:06:22.377

@LuisMendo Is 85 bytes horribly long compared to 50...? :) – Sanchises – 2018-04-18T08:31:57.657

@StewieGriffin I've been thinking of making a more complex Scrabble challenge. Unless someone else does it first I may (finally) go ahead and do that. – manassehkatz-Moving 2 Codidact – 2018-04-18T17:50:08.217

1

@manassehkatz you should definitely give it a go! I highly recommend that you post the challenge in the Sandbox to get some feedback and help with it before posting it on the main site. Complex challenges are notoriously difficult to get right without any feedback.

– Stewie Griffin – 2018-04-18T19:37:15.607

@StewieGriffin Are we allowed to have the program fail if the input is longer than what fits on a Scrabble board (15)? – mbomb007 – 2018-04-20T16:20:21.940

It should work for the test cases @mbomb007. You have plenty of tiles (and boards) available. You may add it as a "this would work if...", if it's an interesting/fun/short solution. :-) – Stewie Griffin – 2018-04-20T16:44:05.420

@StewieGriffin Added to Sandbox - please take a look at it. – manassehkatz-Moving 2 Codidact – 2018-04-22T03:51:35.083

Answers

16

sed 4.2.2, 81

s/[QZ]/JD/g
s/[JX]/KB/g
s/K/FE/g
s/[FHVWY]/BE/g
s/[BCMP]/DE/g
s/[DG]/EE/g
s/./1/g

Output is in unary.

Reduces each letter to a combination of lower-scoring letters until all letters are 1-scorers. Then replaces those with 1s to give a unary count.

Try it online!

Digital Trauma

Posted 2018-04-17T18:53:45.610

Reputation: 64 644

10

Haskell, 86 84 bytes

f s=length s+sum[n|x<-s,(n,y)<-zip(9:7:[1..])$words"QZ JX DG BCMP FHVWY K",x`elem`y]

Try it online!

Explanation

Most letters give a score of 1 and thus we don't need to keep track of these, instead we just decrement each score (saves 1 byte on 10 as well) and then add the length of the string to the resulting score.

Thanks @nimi for -2 bytes (rearanging the words and using [1..] instead of [4,3..])!

ბიმო

Posted 2018-04-17T18:53:45.610

Reputation: 15 345

1zip[1..]$words"DG BCMP FHVWY K . . JX . QZ" gives another alternative with equal length – Angs – 2018-04-17T21:54:36.483

10

Octave, 50 bytes

@(t)'				'/3*sum(65:90==t')'

Try it online!

Challenge accepted. Explanation:

@(t)             % Define anonymous function taking a single argument t.
    ' ... '/3    % Row vector with letter scores. Corresponds to char([1 3 3 2 ...]*3). 
                 % The factor 3 was necessary to avoid a newline.

*                % Dot product (yes, * is dot product, .* is not. Go figure). Equivalent to sum of element-wise products.
     65:90       % Alphabet
          ==t'   % Broadcast equality with input string.
 sum(         )  % Sum this matrix. Gives the count of each letter in the alphabet
               ' % Transpose into column vector for dot product

Sanchises

Posted 2018-04-17T18:53:45.610

Reputation: 8 530

Very clever! Using unprintables was a nice touch! :) – Stewie Griffin – 2018-04-18T08:22:37.813

@StewieGriffin It's only one byte compared to -47 but that's code-golfing for you! – Sanchises – 2018-04-18T08:31:14.590

1Sigh. Well and truly out golfed. I hadn't realised you could use == like that in Octave. Doesn't work in MATLAB. Good to know. – Tom Carpenter – 2018-04-18T08:43:09.927

@Sanchises Interesting. I've been using R2014b up until recently (just switched to R2017a). Haven't had a chance to explore the differences. – Tom Carpenter – 2018-04-18T08:48:50.070

2

@TomCarpenter I don't mean to rub any salt in the wound, but the 'old' way of doing this (with bsxfun) is also shorter at 61 bytes: Try it online!

– Sanchises – 2018-04-18T08:57:56.627

3WAT 50 bytes I don't even – Luis Mendo – 2018-04-18T10:54:25.447

@LuisMendo This may just be the first time I properly outgolfed you. – Sanchises – 2018-04-18T10:55:12.223

"properly" is an understatement for 35 bytes :-D – Luis Mendo – 2018-04-18T10:55:46.027

I had tried encoding the scores as unprintables but the newlines screwed it up! Nicely done! – Giuseppe – 2018-04-18T11:56:54.190

9

Beatnik, 733 bytes

Since it really had to be done, here it is. It was a really nasty to debug and provided a few challenges.

Input must be uppercase letters only. Output is unary (hope that is OK?)

J K ZZZZZZK Z ZD ZB ZZZZZZZZZZZZZZZZZA K A Z ZD ZB ZZZZZZZZZZZZZZZKF K A Z ZD ZB ZZZZZZZZZZZZZZZB K A Z ZD ZB ZZZZZZZZZZZZZZZ K A Z ZD ZB ZZZZZZZZZZZZZZKD K A Z ZD ZB ZZZZZZZZZZZZZD K A Z ZD ZB ZZZZZZZZZZZZZD K A Z ZD ZB ZZZZZZZZZZZZ K A Z ZD ZB ZZZZZZZZZZZZB K A Z ZD ZB ZZZZZZZZZKA K A Z ZD ZB ZZZZZZZZZKF K A Z ZD ZB ZZZZZZZZZZK K A Z ZD ZB ZZZZZZZZZB K A Z ZD ZB ZZZZZZZZZB K A Z ZD ZB ZZZZZZZZKD K A Z ZD ZB ZZZZZZZK K A Z ZD ZB ZZZZKB K A Z ZD ZB ZZZZZZKF K A Z ZD ZB ZZZZZZB K A Z ZD ZB ZZZZZFB K A Z ZD ZB ZZZZZA K A Z ZD ZB ZZZAK K A Z ZD ZB ZZZ K A Z ZD ZB ZD K A Z ZD ZB ZKB K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K A ZKA ZZZZZZZZZZZZZZZZZZY

Try it online!

General process is:

  • get character from input
  • subtract 65
  • check if result is 0
    • if 0 jump specified amount of words.
    • otherwise subtract 1 and repeat check.
  • the jump targets are push print operations followed be a loop back to beginning of program.

Ends with an error.

A more complete explanation:

J K ZZZZZZK Z ZD               # Get input and subtract 65
ZB ZZZZZZZZZZZZZZZZZA K A Z ZD # Character A - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZZKF K A Z ZD  # Character B - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZZB K A Z ZD   # Character C - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZZ K A Z ZD    # Character D - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZKD K A Z ZD   # Character E - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZD K A Z ZD     # Character F - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZD K A Z ZD     # Character G - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZ K A Z ZD       # Character H - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZB K A Z ZD      # Character I - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZKA K A Z ZD        # Character J - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZKF K A Z ZD        # Character K - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZK K A Z ZD        # Character L - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZB K A Z ZD         # Character M - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZB K A Z ZD         # Character N - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZKD K A Z ZD         # Character O - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZK K A Z ZD           # Character P - if 0 jump to print, otherwise subtract 1
ZB ZZZZKB K A Z ZD             # Character Q - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZKF K A Z ZD           # Character R - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZB K A Z ZD            # Character S - if 0 jump to print, otherwise subtract 1
ZB ZZZZZFB K A Z ZD            # Character T - if 0 jump to print, otherwise subtract 1
ZB ZZZZZA K A Z ZD             # Character U - if 0 jump to print, otherwise subtract 1
ZB ZZZAK K A Z ZD              # Character V - if 0 jump to print, otherwise subtract 1
ZB ZZZ K A Z ZD                # Character W - if 0 jump to print, otherwise subtract 1
ZB ZD K A Z ZD                 # Character X - if 0 jump to print, otherwise subtract 1
ZB ZKB                         # Character Y - if 0 jump to print, otherwise subtract 1
K ZZZZKF KF                    # Jump Point for print 1111111111
K ZZZZKF KF                    #
K ZZZZKF KF                    # Jump Point for print 11111111
K ZZZZKF KF                    #
K ZZZZKF KF                    #
K ZZZZKF KF                    # Jump Point for print 11111
K ZZZZKF KF                    # Jump Point for print 1111
K ZZZZKF KF                    # Jump Point for print 111
K ZZZZKF KF                    # Jump Point for print 11
K ZZZZKF KF                    # Jump Point for print 1
K A ZKA ZZZZZZZZZZZZZZZZZZAAAA # Jump back to start

MickyT

Posted 2018-04-17T18:53:45.610

Reputation: 11 735

1Golfed. – jimmy23013 – 2019-05-31T22:55:38.247

@jimmy23013 very nice, you should post that one up. – MickyT – 2019-06-03T18:19:03.843

8

Brain-Flak, 210, 204, 198, 184, 170 bytes

({<([{}]<>(({}{}))(([][][][][])<((([]())<([][])>))((((()))))>)[](((()()())<((()))>)((())()()()()))((())()()())((()())()())[]((((())())()))(())){({}<{}>())}>{}{}<{{}}><>})

Try it online!

Thanks to @JoKing for saving 14 bytes!

Readable version:

({              # For each character

                # Push array of letter scores
                # Also adjust character to 1-indexing
        <([{}]<>
        (({}{}))    # Push 2 0s
        (([][][][][])   # 10
        <((([]())   # 4
        <([][])>    # 8
        ))      # 4,4
        ((((()))))> # 1,1,1,1
        )       # 10
        []      # Add 12 to difference
        (((()()())  # 3
        <((()))>    # 1,1
        )       # 3
        ((())()()()())) # 1, 5
        ((())()()())    # 1, 4
        ((()())()())    # 2, 4
        []      # Add 22 to difference
        ((((())())()))  # 1,2,3
        (())        # 1
        )   # Push 65-char

        {({}<{}>())} # Index character into score array
        >
        {}{}         # Add score to running total
        <{{}}><>     # Clear the stack

})               # Implicit print of total score

James

Posted 2018-04-17T18:53:45.610

Reputation: 54 537

170 bytes – Jo King – 2018-04-18T01:47:29.283

2For a given definition of 'readable' :) – Matt Lacey – 2018-04-19T11:59:14.730

I made an edit to try and clarify the explanation, feel free to rollback if you find an issue. – Kamil Drakari – 2018-04-24T20:31:40.300

7

Pyth, 40 bytes

sm+2x.e}dbc." zØÍ jÙ¹>;%OG5§"\ 1

Try it here

Explanation

sm+2x.e}dbc." zØÍ jÙ¹>;%OG5§"\ 1
 m                              Q  For each character in the (implicit) input...
    x.e  b                     1   ... find the first index in...
          c." zØÍ jÙ¹>;%OG5§"\     ['dg','bcmp','fhvwy','k','','','jx','','qz']
       }d                          ... containing the character...
  +2                               ... 2-indexed.
s                                  Take the sum.

user48543

Posted 2018-04-17T18:53:45.610

Reputation:

7

Python 2, 78 bytes

lambda x:sum(map(('ABCEIKLMNOPRSTU'+'BCDGMPQZ'*2+'FHJJKQQVWXXYZZ'*4).count,x))

Try it online!

Shorter version, port of DanielIndie's answer, 71 70 bytes

-1 byte thanks to Sunny Patel

lambda x:sum(int('02210313074020029000033739'[ord(c)-65])+1for c in x)

Try it online!

Rod

Posted 2018-04-17T18:53:45.610

Reputation: 17 588

7

JavaScript (Node.js), 71 66 63 62 bytes

  • @Arnauld awesome as always reducing 7 bytes
  • thanks to l4m2 for rducing by 1 byte
s=>Buffer(s).map(x=>s="02210313074020029000033739"[x-65]-~s)|s

Try it online!

DanielIndie

Posted 2018-04-17T18:53:45.610

Reputation: 1 220

6

Java 8, 75 71 70 bytes

s->s.chars().map(c->"\n\n".charAt(c-65)).sum()

-1 byte by changing "02210313074020029000033739".charAt(c-65)-47 to unprintables (and two \n) so the -47 can be removed. Inspired by @Sanchises' Octave answer.

Try it online.

s->          // Method with String parameter and integer return-type
  s.chars()  //  Loop over the characters as IntStream
   .map(c->"\n\n".charAt(c-65))
             //   Convert the character to its value
   .sum()    //   And sum it all together

Kevin Cruijssen

Posted 2018-04-17T18:53:45.610

Reputation: 67 575

5

R, 90 63 bytes

function(W,u=utf8ToInt)sum(u('

')[u(W)-64])

Try it online!

Takes input as an uppercase string. R handles unprintables and multiline strings without issues, so that's nice. Now we're almost twice the external package!

And because CRAN has so many random goodies:

R + ScrabbleScore 31 bytes

ScrabbleScore::sws(scan(,""),F)

Try it online!

Sadly, sws checks for validity by default.

Giuseppe

Posted 2018-04-17T18:53:45.610

Reputation: 21 077

Had a play with the score list and trimmed a couple

– MickyT – 2018-04-18T20:44:39.400

@MickyT nice! I played around with unprintables and re-using utf8ToInt instead of match and managed to get a few more down! – Giuseppe – 2018-04-18T22:04:35.493

5

Octave / MATLAB, 85 bytes

@(x)sum([1:4 7 9]*any(reshape(char(strsplit('DG BCMP FHVWY K JX QZ')),6,1,5)==x,3)+1)

Try it online!

Luis Mendo

Posted 2018-04-17T18:53:45.610

Reputation: 87 464

Better than my attempts :-) still longer than I would have thought before I tried it though... You had a very different approach to it! – Stewie Griffin – 2018-04-18T06:01:36.753

5

Jelly, 19 bytes

Oị“ÆẠḃbṂƬɠF#ṁ²’ḃ⁵¤S

A monadic link accepting a list of upper-case characters which returns an integer

Try it online! Or see the test-suite.

How?

Oị“ÆẠḃbṂƬɠF#ṁ²’ḃ⁵¤S - Link: list of characters
O                   - ordinals ('A'->65, B->66...)
                 ¤  - nilad followed by link(s) as a nilad:
  “ÆẠḃbṂƬɠF#ṁ²’     -   literal 14011114485013321424185131
                ⁵   -   literal 10
               ḃ    -   bijective-base = [1,3,10,1,1,1,1,4,4,8,4,10,1,3,3,2,1,4,2,4,1,8,5,1,3,1]
 ị                  - index into (1-based & modular) (vectorises)
                    -  i.e. mapping from: O P  Q R S T U V W X Y  Z A B C D E F G H I J K L M N)
                  S - sum

Jonathan Allan

Posted 2018-04-17T18:53:45.610

Reputation: 67 804

4

Emojicode, 358 bytes

➡️s 0ls➕sa1e1i1l1n1o1r1s1t1u1d2g2b3c3m3p3f4h4v4w4y4k5j8x8q10z10ls 10

Try it online!

Explanation:

I changed the variable names from single letters to more meaningful words, and expanded some parts of my code to hopefully make it more readable for people unfamiliar with the language. You can test the expanded program here.

       define a class that takes a string
 ➡️     define a method that returns a string
  values     create int dictionary
   a1 e1 i1 l1 n1 o1 r1 s1 t1 u1 d2 g2
   b3 c3 m3 p3 f4 h4 v4 w4 y4 k5 j8 x8
   q10 z10
           ^ dictionary contains letters(keys) and their numerical values

  score 0                          declare 'score' variable and set to 0
   iterator                      transform input string to iterator
    letter iterator                 iterate over each byte in input string
     score➕score values letter    add value of each letter to score
   
  score 10     return the score as a string
 


           begin the program here
 abc     call scoring method and print the score
 ppcg     repeat with other test cases
 stewie
 fizzbuzz
 abcdefghijklmnopqrstuvwxyz

X1M4L

Posted 2018-04-17T18:53:45.610

Reputation: 1 586

7ouch... my eyes... is there an option on golf.se to hide some specific langages? ^^ – Olivier Dulac – 2018-04-19T12:15:34.070

1@OlivierDulac There's probably a way to prevent the browser from rendering emoji specially. They do each have standard Unicode black and white characters associated with them. – mbomb007 – 2018-04-20T15:19:30.273

3

05AB1E, 21 bytes

Takes input as a lowercase list of characters.

•_JÊ¿ùã$Ƶ½œM•11вAIkèO

Try it online! or as a Test suite

Emigna

Posted 2018-04-17T18:53:45.610

Reputation: 50 798

3

Octave, 73 bytes

@(x)sum('09977433333222211'(([~,y]=ismember(x,'QZJXKFHVWYBCMPDG'))+1)-47)

Try it online!

Uses ismember to map each character in the input stream x onto it's index in the lookup string 'QZJXKFHVWYBCMPDG'. Any element not found will be mapped to an index of 0 (this will include the 1-point characters).

Next we add 1 to the index to make the 0's become valid 1-index references, and lookup into the string '09977433333222211'. This is one element longer than the first lookup string. The digits represent the point value of each element in the original string, minus 1, with the extra element being a '0' at the beginning .

Finally the resultant string is converted to integers by subtracting 47 ('0'-1), yielding the point value for each letter, and all point values are then summed.

Tom Carpenter

Posted 2018-04-17T18:53:45.610

Reputation: 3 990

1Very clever! :) – Stewie Griffin – 2018-04-18T07:44:00.810

3

Haskell, 66 bytes

sum.map(\c->1+read["02210313074020029000033739"!!(fromEnum c-65)])

Try it online! Same approach as DanielIndie's JavaScript answer.


Haskell, 82 81 bytes

sum.map(\c->1+sum(read.pure<$>lookup c(zip"DGBCMPFHVWYKJXQZ""1122223333347799")))

Try it online!

Laikoni

Posted 2018-04-17T18:53:45.610

Reputation: 23 676

3

C++, 95 bytes

char*m="02210313074020029000033739";
int f(char*p){int n=0;while(*p)n+=m[*p++-65]-47;return n;}

Try it online (not a TIO link sorry)

Explanation:

  • Declares m, an array of the values of each letter in order, minus 1. The minus 1 is because of Q and Z: I couldn't have a two digit number in there
  • Iterates through through the string p until we get to null character, and adds the score of the number (*p gives us the letter, and -65 so we can properly index the array). Since m is a char* it converts to a char so we minus 48 so bring it back to 0, but add 1 since m is declared as one score less for each character.

I'm not an avid poster here so I hope I've done this correctly. I believe they returning n counts as printing the value, and that declaring a function is fine.

Tas

Posted 2018-04-17T18:53:45.610

Reputation: 593

Very nice! The only byte you can save, is the newline: Try it online!

– movatica – 2019-04-30T21:39:57.177

3

PowerShell, 60 bytes

$args|% t*y|%{$s+='02210313074020029000033739'[$_-65]-47}
$s

Try it online!

mazzy

Posted 2018-04-17T18:53:45.610

Reputation: 4 832

2

Japt -x, 43 39 35 30 bytes

£2+`dglbcÛghvwylk¥ljx¥qz`qÊaøX

Try it online!

35 byte solution:

¬£Ò('0+#Ý03#740#È29e4+33739 g65nXc

Run it online

Oliver

Posted 2018-04-17T18:53:45.610

Reputation: 7 160

2

Retina 0.8.2, 41 bytes

T`BCDGJKMPQXZF\HVWY`221174229793
.
$*..
.

Try it online! Link includes test cases. Explanation: Like the Haskell answer, nontrivial letters are translated to 1 less than their score, and 1 is added later when the characters are converted to unary. Putting FHVWY last allows them all to map to a score of 3 + 1.

Neil

Posted 2018-04-17T18:53:45.610

Reputation: 95 035

2

Japt, 36 bytes

£2+`dg
bcmp
fhvwy
k


jx

qz`·bøX
x

Takes input as a lowercase string, returns a number.
Short explanation:

£2+`dg
¬       // Split the input into chars,
 £      // then map over each char, returning
  2+`dg // 2 plus

qz`·bøX
    bøX // the char's index in
qz`·    // the hardcoded string split by newlines.
x       // And finally sum the whole thing.

Try it online!

Nit

Posted 2018-04-17T18:53:45.610

Reputation: 2 667

2

Ruby, 60 bytes

->s{s.sum{|c|"BDDCBECEBIFBDBBDKBBBBEEIEK"[c.ord-65].ord-65}}

Try it online!

A lambda, accepting input as an array of (uppercase) characters and returning an integer.

benj2240

Posted 2018-04-17T18:53:45.610

Reputation: 801

2

Perl 5 -pF, 50 bytes

_1DG2BCMP3FHVWY4K7JX9QZ=~/\d\D*$_/,$\+=1+$&for@F}{

Try it online!

nwellnhof

Posted 2018-04-17T18:53:45.610

Reputation: 10 037

2

Gforth, 109 Bytes

: V s" 1332142418513113:11114484:" ; : C 0 NAME 0 DO DUP C@ 65 - V DROP + C@ 48 - ROT + SWAP 1+ LOOP DROP . ;

Input must be uppercase:
C PPCG 11 OK

Readable

\ String used as table with values for each letter in the alphabet
\ : follows 9 in the ASCII-table
: V
   s" 1332142418513113:11114484:"
;

: C
   0                   \ Initialize sum        ( sum               )
   NAME                \ Get the string        ( sum  c-addr count )
   0 DO                \ Start of loop         ( sum  c-addr       )
      DUP C@           \ Get letter            ( sum  c-addr char  )
      65 -             \ Calculate table index ( sum  c-addr index )
      V DROP + C@      \ Get table entry       ( sum  c-addr entry )
      48 -             \ Calculate entry value ( sum  c-addr value )
      ROT + SWAP       \ Update sum            ( sum' c-addr       )
      1+               \ Next character        ( sum' c-addr'      )
   LOOP
   DROP .              \ Drop c-addr and print result
;

Try it online!

Kitana

Posted 2018-04-17T18:53:45.610

Reputation: 171

2

C (gcc), 78 72 bytes

i;f(char*s){for(i=0;*s;)i+="\n\n"[*s++-65];s=i;}

There are actually 26 characters in that string. See the code rendered properly and run it here.

Thanks to gastropner for golfing 6 bytes.

Ungolfed version:

i; // declare a variable to store the score; it is implicitly of type int
f(char* s) { // function taking a string as argument and implicitly returning an int
    for(i = 0; // initialize the score to 0
        *s; ) // iterate over the string until we hit terminating NUL byte
        i += "\n\n"[*s++ - 65]; // this is a 26-char string containing the ASCII equivalent of each numeric scrabble value; 65 is ASCII code for 'A', mapping the alphabet onto the string
    s = i; // implicitly return the score
}

O.O.Balance

Posted 2018-04-17T18:53:45.610

Reputation: 1 499

2

C# (.NET Core), 50 + 18 = 68 bytes

s=>s.Sum(c=>"02210313074020029000033739"[c-65]-47)

+18 bytes for using System.Linq;

Try it online!

TheLethalCoder

Posted 2018-04-17T18:53:45.610

Reputation: 6 930

2

Perl 6, 52 bytes

{TR/A..Z/02210313074020029000033739/.comb.sum+.ords}

Try it online!

Maps every character to a digit, and sums them. And adds 1 for each character because there isn't a digit 10 without incurring unicode bytes.

Phil H

Posted 2018-04-17T18:53:45.610

Reputation: 1 376

2

Excel, 91 bytes

{=LEN(A1)+SUM(0+("0"&MID("02210313074020029000033739",CODE(MID(A1,ROW(A:A),1)&"z")-64,1)))}

Explanation:

  • Input is in cell A1
  • The formula must be entered as an array formula with Ctrl+Shift+Enter, which adds the curly brackets { } to both ends.
  • MID(A1,ROW(A:A),1) pulls out each character in turn (and a lot of empty values, too, since it's going to return as many values as there are rows in the sheet)
  • CODE(MID(~)&"z") pulls out the ASCII value for the each character. The &"z" appends a z to the end of the MID() result because CODE() doesn't like empty inputs. The ASCII value for z is higher than every capital letter, though, so it's effectively ignored later.
  • MID("02210313074020029000033739",CODE(~)-64,1) pulls out a letter from the score string based on its ASCII value adjusted down by 64 so the letters run 1-26 instead of 65-90.
  • "0"&MID(~) prepends a zero to the MID() result because Excel won't let you do math with empty strings, of which there will be several.
  • 0+("0"&MID(~)) turns all those strings into numbers.
  • SUM(0+("0"&MID(~))) adds up all those strings that are now numbers.
  • LEN(A1)+SUM(~) adds the length of the input to the sum because all the values in the score string (02210313074020029000033739) were adjusted down by one so they would all be one digit long.

There's a very similar solution in Google Sheets but it comes in at 97 bytes because ArrayFromula() is longer than {} (but at least it can handle 0 + "" = 0).

=Len(A1)+ArrayFormula(Sum(0+Mid("02210313074020029000033739",Code(Mid(A1,Row(A:A),1)&"z")-64,1)))

Engineer Toast

Posted 2018-04-17T18:53:45.610

Reputation: 5 769

1Well done. I have a Excel solution using 26 SUBSTITUTE(), coming in at a hefty 527 bytes. – Wernisch – 2018-04-20T12:35:20.647

2

Wolfram Language (Mathematica), 74 bytes

Of course Wolfram|Alpha supports Scrabble scoring! This is an anonymous function.

Plus@@(First[WolframAlpha["Scrabble "<>##,"NumberData"]]&/@Characters[#])&

This doesn't work on TIO.

To run, go here, scroll down and click "Create a New Notebook »". The code to use in the notebook is in this TIO program so you can copy it. Paste each function call in its own code block. If you run too many in a single block, the execution won't complete.

Note that WolframAlpha sends a request using the Internet. Though there are other answers on PPCG that use it, I thought you should know.

This program uses the below shorter function, but calls it on each individual character of the input (sending a separate call to Wolfram|Alpha each time!)


This only works for input up to length 15, the width of a Scrabble board. (49 bytes)

First[WolframAlpha["Scrabble "<>#,"NumberData"]]&

Same as above, but will display the result in a box, along with whether the input is a valid Scrabble word. (45 bytes)

First[WolframAlpha["Scrabble "<>#,"Result"]]&

mbomb007

Posted 2018-04-17T18:53:45.610

Reputation: 21 944

2

K (oK), 60 38 bytes

Solution:

+/1+.:'"02210313074020029000033739"65!

Try it online!

Explanation:

Index into the scores, sum up result.

+/1+.:'"02210313074020029000033739"65! / the solution
                                   65! / input modulo 65 to get position in A-Z
       "02210313074020029000033739"    / index into the scores (1 point lower)
    .:'                                / value (.:) each (') to convert to ints
  1+                                   / increase by 1
+/                                     / sum up

streetster

Posted 2018-04-17T18:53:45.610

Reputation: 3 635

2

PowerShell, 92 bytes

$args|% T*y|%{$i+=switch -r($_){[DG]{2}[BCMP]{3}[FHVWY]{4}K{5}[JX]{8}[QZ]{10}default{1}}};$i

Try it online!

Didn't notice @Add-TheNewOne's answer before writing this, but I think it's fairly different in any case.

Gabriel Mills

Posted 2018-04-17T18:53:45.610

Reputation: 778

2

05AB1E, 18 bytes

•Q<ß÷λv¸Ïàœ¶•IÇè>O

Try it online!

Explanation:

•Q<ß÷λv¸Ïàœ¶•           # compressed integer 30740200290000337390221031
             IÇ         # codepoints of the input
               è        # index into the digits of the large integer
                >       # increment each
                 O      # sum

The large integer encodes the point value of each letter. Since encoding numbers in the range 1-10 would be inconvenient, we subtract 1 so that each one fits on a single digit (this is why the > is needed).

Note that indexing in 05AB1E wraps around, so the first digit of the number actually corresponds to "h" ("h"'s codepoint is 104, which is 0 mod 26). This is convenient: since numbers can't start with 0, we don't want the first digit to correspond to "a".

Alternative 18-byter:

A•Θ¡₆öηÖ&'/α°•R‡>O

Try it online!

A pushes "abcdefghijklmnopqrstuvwxyz". transliterates, replacing each letter in the input with the corresponding digit in the compressed integer. A‡ saves one byte over IÇè; unfortunately, this encoding puts "a" first, so we have to use R (reverse) to get around the issue that numbers can't start with 0.

Yet another 18-byter:

žW•Δÿ¦ÝZ=áí4_ø•‡>O

Try it online!

Same idea as above, but this one uses the obscure žW built-in to push "qwertyuiopasdfghjklzxcvbnm". žW is one byte longer than A, but it saves the R since "q" isn't a 1-point letter.

Grimmy

Posted 2018-04-17T18:53:45.610

Reputation: 12 521

2

Beatnik, 379 bytes

K ZZZZKF ZD ZD ZD ZD ZD ZD ZD
K ZZZZZZZZA J Z ZD ZB B
K XA KD ZD ZF F ZA ZD KF KF ZD ZB B
K D Z ZD ZB B
K ZF Z ZD ZF KA ZA ZD ZD KF KF KF ZD ZB B
K A KD ZD ZF D ZA KF ZD ZB B
K ZF KD ZD ZB B
K D Z ZD ZB B
K A Z ZD ZB B
K ZF Z ZD ZB B
K D Z ZD ZF D ZA KF ZD ZB B
K Z KD ZD ZB B
K B Z ZD ZB B
K Z Z ZD ZB B
K A Z ZD ZF F ZA KF ZB Z
K K KD ZD ZB B
K B Z ZF A KF
KF
XX ZZZZZZZZZZZZZX

Try it online!

See also MickyT's answer.

jimmy23013

Posted 2018-04-17T18:53:45.610

Reputation: 34 042

1

JavaScript (ES6), 69 bytes

Takes input as an array of characters.

s=>s.map(c=>t-=~'9200204703130122093733'[parseInt(c,36)*25%26],t=0)|t

Try it online!

Arnauld

Posted 2018-04-17T18:53:45.610

Reputation: 111 334

1

Bash + GNU utilities, 64

sed -es/[{QZ]/JD,JX]/KB,K]/FE,FHVWY]/BE,BCMP]/DE,DG]/EE}/g|wc -c

Try it online!

Input read from STDIN. Uses a brace expansion to generate sed expressions equivalent to those in my sed answer.

Digital Trauma

Posted 2018-04-17T18:53:45.610

Reputation: 64 644

1

Perl 6, 55 bytes

{sum .map:{:36<Z3P8JOBRZ4X1FBXLWSVL>+>(.ord*4-260)%16}}

Try it online!

Takes an array of characters. Uses a 4-bit lookup table encoded in base-36.

nwellnhof

Posted 2018-04-17T18:53:45.610

Reputation: 10 037

1

Perl 5 -pF, 73 bytes

$\+=(1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,(1)x4,4,4,8,4,10)[-65+ord]for@F}{

Try it online!

Xcali

Posted 2018-04-17T18:53:45.610

Reputation: 7 671

Managed to save a few using =~/./g, but can't get it down as far as @nwellnhof's answer... Try it online!

– Dom Hastings – 2018-04-18T11:48:11.530

My Perl6 solution is pretty similar to this, I opted to use value-1 thus only needing 0-9 which are single digits and then split 022103... – Phil H – 2018-04-19T21:11:39.993

1

Red, 97 bytes

func[s][t: :to-integer n: 0 foreach c s[n: n - 47 + t pick{02210313074020029000033739}t c - 64]n]

Takes a string as input.

Explanation of the ungolfed solution:

f: func[s][
    n: 0                  ; n will store the sum
    foreach c s [         ; for each character in the argument 
        n: n - 47 + to-integer pick {02210313074020029000033739} to-integer c - 64
                          ; find its offset from "A" (to-integer c - 64)
                          ; use this as an index in the string with scores (pick {...} ...)
                          ; to extract the score and convert it to an integer 
                          ; increase it with 1 and add it to the sum    
    ]
    n                     ; return the sum 
]

Try it online!

Galen Ivanov

Posted 2018-04-17T18:53:45.610

Reputation: 13 815

1

Pip, 34 33 bytes

1+("3V1S1QFRU1SMQ12W7"FB36)@A_MSa

Takes input in lowercase as a command-line argument. Try it online!

Explanation

We map a function to each character of the command-line argument a and sum the results using MS.

In the function, we convert the argument _ to its ASCII code using A, and then use that to index into the magic number 30740200290000337390221031. With cyclic indexing, this maps a -> 0, b -> 2, ... , z -> 9 (one less than the Scrabble score). We then add 1 to get the correct score of each letter.

We save one byte by encoding the number in base 36 (the highest base Pip's builtin base conversion can handle) as the string "3V1S1QFRU1SMQ12W7" and then converting it from base 36 to decimal using FB.

DLosc

Posted 2018-04-17T18:53:45.610

Reputation: 21 213

1

SmileBASIC, 87 85 78 bytes

INPUT S$WHILE""<S$S=S+VAL(@2210313074020029000033739[ASC(POP(S$))-65])+1WEND?S

Old method:

INPUT S$WHILE""<S$S=S+(INSTR(@DG+@___BCMP_FHVWYK*2+"JX"*4+@QZ,POP(S$))+4)DIV 5+1WEND?S

12Me21

Posted 2018-04-17T18:53:45.610

Reputation: 6 110

1

Go, 96 94 bytes

func(i string){a,s:=`

`,0;for _,c:=range i{s+=int(a[c-65])};print(s)}

Go allows any byte sequence in a raw string, except \r and `, this saves about 3 bytes off the total.

This is just a remix of existing solutions in other languages, so no real new innovation here.

Edit: I missed the memo where we dont have to name our functions

Try it online!

Kristoffer Sall-Storgaard

Posted 2018-04-17T18:53:45.610

Reputation: 489

1

Powershell with amazing 297 Bytes

Any idea to make the script shorter?

$1=read-Host
$s=0
$l=$1.ToCharArray()
$l|%{switch($_){{'E','A','I','O','N','R','T','L','S','U'-contains$_}{$s+=1}{'D','G'-contains$_}{$s+=2}{'B','C','M','P'-contains$_}{$s+=3}{'F','H','V','W','Y'-contains$_}{$s+=4}{'J','X'-contains$_}{$s+=8}{'Q','Z'-contains$_}{$s+=10}{'K'-contains$_}{$s+=5}}}
$s

Add-TheNewOne

Posted 2018-04-17T18:53:45.610

Reputation: 21

You can remove the string $s=0. The -in is sorter than -contains. switch can returns a value $s+=$(switch($_){...{1}...{2}... ...{5}}). and etc :) Welcome!

– mazzy – 2019-03-01T14:50:49.077

Thank you :D !!! I'm not very experienced in Code golfing so can you explain me what you did in your Code? – Add-TheNewOne – 2019-03-01T15:08:15.530

Step 1: obvious thing 240 bytes

– mazzy – 2019-03-01T17:05:35.300

Step 2: big case to default 195 bytes

– mazzy – 2019-03-01T17:07:20.440

Step 3: to take out repeating code 171 bytes

– mazzy – 2019-03-01T17:09:37.027

Step 4: replace .ToCharArray() with shortcut 163 bytes

– mazzy – 2019-03-01T17:11:31.750

Step 5: use switch with regexp instead long expressions with char array 92 bytes from Gabriel Mills :)

– mazzy – 2019-03-01T17:13:22.533

I will be happy to delete my answer if and when you choose to implement my 92 byte strategy, as @mazzy mentioned. – Gabriel Mills – 2019-03-05T22:18:01.033

1

IBM PC DOS, 8088 assembly, 36 bytes

bb33 01ac 2c41 d0d8 d772 0651 b104 d2e8 5924 0f02 d0e2 ec13 3214 2418 5131 13a1 1114 484a

Unassembled.

; score a Scrabble word string
; input:
;   I: pointer to input string
;   IL: length of input string
;   TBL: pointer to score table
; output:
;   SC: word score (reg8)
SCRAB_SCORE MACRO   I, IL, TBL, SC
            LOCAL   LOOP_LETTER, ODD
        IFDIFI <I>,<SI>     ; skip if I is already SI
    MOV  SI, I              ; load string into SI 
        ENDIF
        IFDIFI <IL>,<CX>    ; skip if IL is already CX
    MOV  CX, IL             ; set up loop counter
        ENDIF
    MOV  BX, OFFSET TBL     ; load score table into BX
LOOP_LETTER:
    LODSB                   ; load next char from DS:SI into AL, advance SI
    SUB  AL, 'A'            ; convert letter to zero-based index
    RCR  AL, 1              ; divide index by 2, set CF if odd index
    XLAT                    ; lookup score
    JC   ODD                ; if odd index use low nibble; if even use high nibble
    PUSH CX                 ; save loop counter (since SHR can only take CL)
    MOV  CL, 4              ; set up right shift for 4 bits
    SHR  AL, CL             ; shift high nibble into low nibble
    POP  CX                 ; restore loop counter
ODD:
    AND  AL, 0FH            ; mask low nibble
    ADD  SC, AL             ; add letter score to total
    LOOP LOOP_LETTER
        ENDM

; Score table
SCTBL DB 013H,032H,014H,024H,018H,051H,031H,013H,0A1H,011H,014H,048H,04AH

Explanation

Implemented as a MACRO (essentially a function) this uses a score table of 4-bit nibbles. Loops through the input string and converts each letter to a zero-based index. Each index is divided by two to find the corresponding byte in the table. The low nibble is added if the index is odd, otherwise the high nibble is added if the index is even.

Output

Example test program:

    MOV  SI, 80H            ; point SI to DOS PSP
    LODSW                   ; load arg length into AL, advance SI to 82H
    MOV  CL, AL             ; set up loop counter in CH
    DEC  CX                 ; remove leading space from letter count
    XOR  DX, DX             ; clear DX to hold total score

    SCRAB_SCORE SI, CX, SCTBL, DL

    MOV  AX, DX             ; put score in AX for OUTDEC display
    CALL OUTDEC             ; generic decimal display routine

enter image description here

640KB

Posted 2018-04-17T18:53:45.610

Reputation: 7 149

1

brainfuck, 386 382 bytes

->,[>>,]->+>>+++>>+++>>++>>+>>++++>>++>>++++>>+>>++++++++>>+++++>>+>>+++>>+>>+>>+++>>++++++++++>>+>>+>>+>>+>>++++>>++++>>++++++++>>++++>>+++++++++++[-<<+]->+[->++++++++[<-------->-]<-[[->+]>>-<+[-<+]->]+[->+]->[->+>[>>]>++[-<+]->]>[-<+>]<<+<[<<]>-<+[-<+]>>->+]>[>>]>>+[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->[-]>>+>+<<<]]]]]]]]]<]>>[>]++++++[-<++++++++>]>>]<<<[.[-]<<<]

Try it online!

Pretty much ungolfed, but first brainfuck code for this question. This code can only handle uppercase letters. Any other symbol will lead to an endless loop. Also the maximum score depends on the used bf-interpreter. On tio.run this can handle scores up to 254.

points:
abcde fghij klmno pqrst uvwxyz
13321 42418 51311 3x111 14484x (x = 10)

tape:
[input], 0, [points table], 0, 0, score
input: current letter marker (0 or neg 1), current letter
points table: check letter marker (0 or neg 1), points

code:
-           set current letter marker
>,[>>,]     input characters

->          set check letter marker
            fill points table
+>>+++>>+++>>++>>+>>
++++>>++>>++++>>+>>++++++++>>
+++++>>+>>+++>>+>>+>>
+++>>++++++++++>>+>>+>>+>>
+>>++++>>++++>>++++++++>>++++>>++++++++++

+[-<<+]->                   go to first input letter
+                           bugfix: intersecting pointers
[                       main loop
  -                         bugfix: intersecting pointers
  >++++++++[<-------->-]<-  subtract 65 from current letter (ASCII A)
  [                         check loop: mark the entry in points table that's related to the current letter
    [->+]                   decrease letter and go to check letter marker
    >>-                     set new check letter marker
    <+[-<+]-                go back to current letter marker
    >                       go to current letter
  ]
                            the related points entry is found so we need to add the points to the score
  +[->+]->                  go to related points entry
  [                     addition loop
    ->+                     decrease points entry and save points to temporary cell
    >[>>]>+                 go to score and add 1
    +[-<+]->                go back to related points entry
  ]
  >[-<+>]                   move points back from temp cell
  <<+                       delete "check letter marker"
  <[<<]>-                   set "check letter marker" at A
  <+[-<+]                   go to current letter marker
  >>-                       set new current letter marker
  >                         next input letter
  +                         exit loop if cell pointer is at "check letter marker" position
]

>[>>]>                      go to score
                            number printing routine from esolangs
>+[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->[-]>>+>+<<<]]]]]]]]]<]>>[>]++++++[-<++++++++>]>>]<<<[.[-]<<<]

if unary output is allowed then this 297 293 bytes code can be used:

->,[>>,]->+>>+++>>+++>>++>>+>>++++>>++>>++++>>+>>++++++++>>+++++>>+>>+++>>+>>+>>+++>>++++++++++>>+>>+>>+>>+>>++++>>++++>>++++++++>>++++>>+++++++++++[-<<+]->+[->++++++++[<-------->-]<-[[->+]>>-<+[-<+]->]+[->+]->[->+>[>>]>++[-<+]->]>[-<+>]<<+<[<<]>-<+[-<+]>>->+]>[>>]<+++++++[>+++++++<-]>>[-<.>]

Try it online!

Dorian

Posted 2018-04-17T18:53:45.610

Reputation: 1 521

1

SNOBOL4 (CSNOBOL4), 224 bytes

	V =ARRAY(10,0)
	V<1> ='EAIONRTLSU'
	V<2> ='DG'
	V<3> ='BCMP'
	V<5> ='FHVWY'
	V<8> ='JX'
	V<10> ='QZ'
	I =INPUT
N	S =I
	X =LT(X,10) X + 1	:F(O)
R	S ANY(V<X>) =	:S(R)
	O =O + X * (SIZE(I) - SIZE(S))
	I =S	:(N)
O	OUTPUT =O
END

Try it online!

Very naive approach. Stores the letters in an ARRAY with indices equal to the scores. It tries to match 0 for point values that don't exist, which ends in a score of 0.

	V =ARRAY(10,0)			;* set up value array of 10 values with contents all 0
	V<1> ='EAIONRTLSU'		;* set contents at appropriate indices
	V<2> ='DG'
	V<3> ='BCMP'
	V<5> ='FHVWY'
	V<8> ='JX'
	V<10> ='QZ'
	I =INPUT			;* read input
N	S =I				;* begin Next iteration
	X =LT(X,10)	X + 1	:F(O)	;* increment X or GOTO output
R	S ANY(V<X>) =	:S(R)		;* replace ANY letters in V<X> with nothing
	O =O + X * (SIZE(I) - SIZE(S))	;* add to the score
	I =S	:(N)			;* set I to S and goto N
O	OUTPUT =O
END

Giuseppe

Posted 2018-04-17T18:53:45.610

Reputation: 21 077

0

Visual Basic for Applications, 117 bytes

s=inputbox(u):for i=1to 16:s=replace(s,mid("DGBCMPFHVWYKJXQZ",i,1),space(mid("1122223333347799",i,1)+1)):next:?len(s)

Run in immediate (debug) window.

dnep

Posted 2018-04-17T18:53:45.610

Reputation: 301

0

C# 49 bytes

s.Sum(i=>"02210313074020029000033739"[i-65]-47);

Where s is a string containing the word in uppercase.

Uses the LINQ operator sum which examines each character and subtracts 65 (upper case A) and uses the resultant value to lookup a number in the long string, which represents the scores in alphabetical order starting with 0 as 1, 1 as 2 etc. The final subtraction -47 reduces the score to its ASCII value = 0 becomes 1, 1 becomes 2 etc

supermeerkat

Posted 2018-04-17T18:53:45.610

Reputation: 113

2

You can not assume input to be present in a predefined variable: https://codegolf.meta.stackexchange.com/a/8731/56433

– Laikoni – 2018-04-19T22:12:46.617

1

So this is the broken and "cheating" version of my answer posted a day before yours?

– TheLethalCoder – 2018-04-20T10:17:16.700

@TheLethalCoder No - whacked this out over lunch and forgot about it. Didn't see yours until I l read your comment. There aren't many ways of doing this as succinctly as possible, and I guess I came up with the same method (albeit with a glaring mistake) as you, but if it makes your fragile ego feel better, go ahead and accuse me of cheating. – supermeerkat – 2018-04-23T08:54:51.463

The "cheating" is that you haven't included the method signature, in this case i=> and you haven't included the using System.Linq; into your byte count. You can also drop the trailing semi-colon. My ego is, however, very much intact thank you very much. – TheLethalCoder – 2018-04-23T08:59:54.443

0

PHP, 74 bytes

while($c=$argn[$i++])$s+=1+_02210313074020029000033739[ord($c)&31];echo$s;

case insensitive. Run as pipe with -nR or try it online.

Titus

Posted 2018-04-17T18:53:45.610

Reputation: 13 814

0

C# (.NET Core), 48 + 18 = 66 bytes

s=>s.Sum(c=>"!#C²!$1$$XhQJ"[c%13]-16>>c%2*4&15)

+18 bytes is for using System.Linq;

Try it online!

Geoffrey

Posted 2018-04-17T18:53:45.610

Reputation: 191

Isnt the function signature part of the code? – Kristoffer Sall-Storgaard – 2018-04-20T22:01:45.270

@KristofferSall-Storgaard I'm not actually sure on the code golf rules since I don't post often. I just mimicked TheLethalCoder's setup and tried to save a few bytes. – Geoffrey – 2018-04-21T22:54:04.460

I was wrong. It would appear we dont need to name the functions – Kristoffer Sall-Storgaard – 2018-04-23T12:24:21.753

0

T-SQL, 106 bytes

Accepting uppercase characters.

Inserted a line break to make this readable:

DECLARE @ varchar(max)='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

WHILE'='<@
SET
@=stuff(@,1,1,'')+'-~'+substring('02210313074020029000033739',ascii(@)-64,1)
EXEC('print'+@)

t-clausen.dk

Posted 2018-04-17T18:53:45.610

Reputation: 2 874