# 'Add' up the letters in a word

My dad is a retired teacher, and he used to give combined spelling and math quizzes, where the student would spell a word, and then 'score' the word by adding up the letters, where a=1, b=2, etc. (e.g. cat = 3+1+20=24). This made grading the quizzes easier, as he would just have to check for incorrect 'scores' rather than incorrectly spelled words, and had the added benefit of testing 2 skills at once.

He hired a friend of mine to write a program that would score words for him, so he could generate lengthy answer keys without error. This problem is inspired by that program.

Requirements:

1. Accept any word with uppercase and lowercase letters
2. Return an error for any special characters, i.e. spaces, hyphens, @^%# etc.
3. a=1, b=2,... and A=1, B=2,...
4. Print the score of the word
5. (Optional) check that the word is in a dictionary after scoring, and print a warning if it is not.
6. No importing an external letter->number dictionary. You must generate it yourself.

Any language is acceptable. This is similar to the 'digital root battle,' but much simpler.

• Is this supposed to be a code golf? – Peter Taylor Apr 23 '11 at 18:08
• @Zach Using the code-golf tag. – Lowjacker Apr 23 '11 at 18:24
• Yeah, only checking scores? I'd spell cat as aaaaaaaaaaaaaaaaaaaaaaaa. Dad: Score is 24? That's right! – ericw31415 May 8 '16 at 14:13
• @ericw31415 Every hashing function has collisions ;-). So far none of his students have tried that attack vector – Zach May 9 '16 at 15:39
• @Zach Also, it would be too complex if his dad made his students do SHA-512 of their words. – ericw31415 May 10 '16 at 20:42

# JavaScript, 68 Bytes

This can almost certainly be golfed more

w=>[...w.toLowerCase()].map(v=>v.charCodeAt()-96).reduce((a,b)=>a+b)

## With dictionary check (Node.js & Unix Descendants only) 195 Bytes

Uses /usr/share/dict/words, and can definitely be shortened (see the warn message)

w=>(require("fs").readFile("/usr/share/dict/words",(e,t)=>!(t+"").split
• For an error message, you do console.error(), not console.warn(). – ericw31415 May 8 '16 at 17:59
• But the challenge said to warn (5. (Optional) check that the word is in a dictionary after scoring, and print a warning if it is not.) Don't mean to be pedantic, but the challenge specified a warning – MayorMonty May 8 '16 at 20:24
• @SpeedyNinja I think it still counts, that isn't really the point of the challenge... – Rɪᴋᴇʀ May 8 '16 at 20:48
• @EᴀsᴛᴇʀʟʏIʀᴋ it is 1 character shorter ;) – MayorMonty May 8 '16 at 20:59
• @SpeedyNinja You're right, I misread. – ericw31415 May 9 '16 at 0:55

## JavaScript (V8), 51 bytes

w=>w.split.reduce((a,l)=>a+parseInt(l,36)-9,0)||x

Surprised nobody's made this golf yet.

Explanation:

w =>                // Function with w as argument
w.split           // Split w into an array of characters
.reduce((a,l)=>a+   // Take the sum of...
parseInt(l,36)-9    // The value of the letter in base 36, then subtract nine (gives the number of the letter)
,0)||x              // Error if it's NaN (there was a special character), because x is not defined
• Does this error for input of "123"? – Dominic van Essen Nov 19 '20 at 22:46
• @DominicvanEssen No, but my understanding of the requirements was that only symbols/special characters had to be handled, not numbers. If numbers also need to be handled it would be 12 more bytes. (As far as I can tell, none of the other JS answers error if given symbols anyway) – Redwolf Programs Nov 19 '20 at 22:56

/\PL/||map$\+=037&ord,@F}{ Try it online! Outputs nothing as its error condition # K, 44 {$[=/x in\:a:.Q.a,.Q.A;+/(a!,/2#,1+!26)x;]}

Returns  for any non alphabetic input

## VBA 120

Sub s(t)
For i=1 To Len(t)
a=Asc(Mid(t,i,1))-64
a=IIf(a>32,a-32,a)
If a<1 Or a>26 Then Print
b=b+a
Next
MsgBox b
End Sub

Print does not cause a compile-time error, though the syntax is invalid, which causes an exception to be thrown and the program to exit if, and only if, the character is not an upper- or lower-case letter.

# C, 97 Chars

int r(c*z){int x=0;while(*z){char w=tolower(*(z++));if(w<96|w>122)return-1;x+=w-96;}return x;}

It returns -1 if there's an invalid character.

# Perl (42 31)

perl -F -pale '$c+=ord(uc$_)-64for@F;$_=$c'

I hope counting F, p, a and l as 1 character was correct.

# Forth, 48 bytes

0 -rot bounds [do] [i] c@ 32 xor 64 - + [loop] .

(takes arguments from the stack)

a version that reads from stdin:

the second version, but commented:

pad \ where to put the bytes
pad \ how many bytes (it's an address, so it's a big number, and forth doesn't have types)
stdin \ where to get the bytes
read-line \ get the bytes (also returns the number of bytes got)
2drop \ ignore IO errors
bounds \ turn an address and a length into a start and end address
[do] \ iterate over all the address in said range
[i] \ get the current address
c@ \ get the character at the current address
32 xor \ make it uppercase
64 - \ letter to number (eg a -> 1)
+ \ add number to total (this is what the 0 is for)
[loop] \ end loop
. \ print resulting number
• This doesn't handle uppercase characters in the input correctly, but the fix actually saves a byte: Try it online! That being said, this also doesn't appear to perform the required input validation. If validation is too clunky, feel free to keep a non-validating version as well, so long as you mark it as such. Also I'm not entirely sure that that snippet is a valid submission, but you save two more bytes by making it a named function. – Unrelated String Nov 19 '20 at 23:28