ABAP, 228 bytes, letters only
I wrote a FORM subroutine for an ABAP report. i is input, o is output.
FORM h USING i o.TRANSLATE i TO UPPER CASE.DO strlen( i ) TIMES.data c(2).c = sy-index - 1.FIND i+c(1) IN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' RESULTS data(r).CHECK sy-subrc = 0.c = r-offset + 1.CONCATENATE o c ` ` INTO o.ENDDO.ENDFORM.
Look at it on Pastebin.com for syntax highlighting. (Not that it looks much better)
"This stuff is used to actually run the program, call the form and output the results.
PARAMETERS se_input TYPE string.
DATA ret type string.
PERFORM h USING se_input ret.
"---- CODE STARTS HERE ----
FORM f USING i o. "Two parameters: i for input, o for output.
TRANSLATE i TO UPPER CASE. "All to uppercase
DO strlen( i ) TIMES. "Do for each character
data c(2). "A char field, length of 2
c = sy-index - 1. "Current loop index - 1 = index in string. Loop index starts at 1.
FIND i+c(1) "Find substring: input at position index, length 1...
IN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' RESULTS data(r). "...in the alphabet, save to "r"
CHECK sy-subrc = 0. "sy-subrc <> 0 => not in the alphabet, skips the rest of this loop (same as CONTINUE)
c = r-offset + 1. "r-offset is the index in the string, add one for alphabet position
CONCATENATE o c ` ` INTO o. "Concatenate it all into the output chars, including the literal space.
" ^- had I used ' ' here, CONCATENATE would remove blank space, but ` ` stays untouched.
ENDDO. "Loop end
ENDFORM. "FORM end
Notes, thoughts, background stuff
First of all, no, I did not miss spaces in my code. ABAP wants them and will not run without them...
The USING parameters i and o are of unknown type, so the program calling the FORM must use a string (or char field with at least
length of input * 3: 2 characters + space per letter) for o, otherwise results can be cut off or it all just dumps right away if it's a numeric value for example.
I saved a few bytes here by re-using the same character field over and over again, abusing the fact that ABAP implicitly converts numbers to chars and vice versa without any issues. This is especially better than using the
CONDENSE <var> statement, which was initially necessary to not have my integers padded to 26 characters width.
Getting substrings in ABAP is super quick and easy once you get used to it:
substring = string+offset(length).
Thanks to the implicit conversion,
offset can be even a character field. Nasty, but great for us in this case. But be careful: While
string+5 gives you the substring starting from index 5,
string + 5 will try to cast your string to a number and add 5. Spaces matter!
There's also an easy way to convert the character to a byte value, giving me the ASCII code and removing the need to do the lengthy
FIND IN ... stuff, but on a Unicode SAP system there's no quick and dirty way to convert that byte value into a "readable" number that I know of, so it's kind of a red herring.
By the way:
TRANSLATE i TO UPPER CASE. is exactly 26 bytes long, so at first glance it looks like we don't even need it and can just add the lowercase letters to the alphabet string instead. But you probably realized right away why we can't do that. ;-)
ABAP, 238 bytes, alphanumeric
For the alphanumeric version we just add 0123456789 to the alphabet string, hence increasing the length of the code by 10 bytes. Not very interesting, but any other approach would just be longer thanks to the very, uhm, verbose language that ABAP is.
FORM h USING i o.TRANSLATE i TO UPPER CASE.DO strlen( i ) TIMES.data c(2).c = sy-index - 1.FIND i+c(1) IN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' RESULTS data(r).CHECK sy-subrc = 0.c = r-offset + 1.CONCATENATE o c ` ` INTO o.ENDDO.ENDFORM.
I hope my explanation is somewhat interesting. Thanks for the challenge!