# '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? Apr 23 '11 at 18:08
• @Zach Using the code-golf tag. Apr 23 '11 at 18:24
• Yeah, only checking scores? I'd spell cat as aaaaaaaaaaaaaaaaaaaaaaaa. Dad: Score is 24? That's right! 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. 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(). 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
– bren
May 8 '16 at 20:24
• @SpeedyNinja I think it still counts, that isn't really the point of the challenge... May 8 '16 at 20:48
• @EᴀsᴛᴇʀʟʏIʀᴋ it is 1 character shorter ;)
– bren
May 8 '16 at 20:59
• @SpeedyNinja You're right, I misread. 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"? 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) Nov 19 '20 at 22:56

/\PL/||map$\+=037&ord,@F}{  Try it online! Outputs nothing as its error condition # Forth, 48 bytes 0 -rot bounds [do] [i] c@ 32 xor 64 - + [loop] . (takes arguments from the stack) a version that reads from stdin: 0 pad pad pad stdin read-line 2drop bounds [do] [i] c@ 32 xor [if] 64 - + [loop] . the second version, but commented: 0 pad \ used later 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. Nov 19 '20 at 23:28 # 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.