J - 30
'`z'(]-32*1=I.)&.(a.&i.)1!:1]1
J is read right-to-left, so to break this down:
- Prompt user for input:
1!:1]1
- Perform algorithm in code-point-space:
&.(a.&i.)
- Identify character range for each letter; the characters between codepoints "`" and "z" are considered lowercase:
1=I.
. - For each lower-case codepoint, subtract 32: `']-32* ...'
- Note that step (2) creates an implicit step (5): we started out by projecting from character to integer domain, so now that we're finished, we map those integers back onto characters.
Obviously this particular implementation only considers ASCII; but the approach could be extended to at least the basic multilingual plane in Unicode.