# The Speed of Letters

Given a string as input, print a new string with each letter pushed to the right by its respective alphabet index.

We all know that A is a slow and Z is a fast letter. This means that Z gets shifted to the right by 25 spaces, A doesn't get shifted at all and B gets shifted by 1 space.

Your program only has to handle uppercase letters from A-Z, and no other characters, no whitespaces, no punctuation.

Note that if 2 or more letters fall onto the same space after shifting, the latest character will be used. (Example: BA ->  A)

## Examples

"AZ" -> "A                         Z"

"ABC" -> "A B C"

"ACE" -> "A  C  E"

"CBA" -> "  A"

"HELLOWORLD" -> "     E H    DLL   OLO   R  W"


## Rules

• This is , so the shortest code in any language bytes wins.
• Standard loopholes are forbidden.

• Input must be received as a string.

• You may print the result to stdout or return a string.
• A single trailing whitespace and/or newline is allowed.
• You may also use lowercase letters as input or output, but only use either case.
• Trailing whitespace okay?
– Okx
Commented Oct 13, 2017 at 13:56
• @Okx Yes, note my previous comment. Commented Oct 13, 2017 at 13:58
• What about a lot of trailing spaces?
– Okx
Commented Oct 13, 2017 at 13:59
• @Okx Forbidden, one is all you get. Commented Oct 13, 2017 at 13:59
• I assume we can use lowercase letters instead, right? Commented Oct 13, 2017 at 15:53

# Python 2, 81 bytes

t=[]
i=65
for c in input():t+=[' ']*26;t[ord(c)-i]=c;i-=1
printt[2::5].rstrip()


Try it online!

# MATL, 11 bytes

''jtfy65-+(


### Explanation

MATL indexing is 1-based. This golfing trick is used here. This other one cannot be used because we need an empty string, not an empty numeric array.

Consider input 'ACE' as an example. Stack contents are shown bottom to top.

''     % Push empty string
%   Stack: ''
j      % Input string
%   Stack: '', 'ACE'
t      % Duplicate
%   Stack: '', 'ACE', 'ACE'
f      % Indices of nonzero entries. Gives [1 2 ... n] where n is input length
%   Stack: '', 'ACE', [1 2 3]
y      % Duplicate from below
%   Stack: '', 'ACE', [1 2 3], 'ACE'
65     % Push 65
%   Stack: '', 'ACE', [1 2 3], 'ACE', 65
-      % Subtract, element-wise. Characters are converted to codepoints
%   Stack: '', 'ACE', [1 2 3], [0 2 4]
+      % Add, element-wise
%   Stack: '', 'ACE', [1 4 7]
(      % Fill string '' with values 'ACE' at positions [1 4 7]. The original
% empty string is extended. Non-existing values are filled with char 0,
% which is displayed as space. Implicitly display
%   Stack: 'A  C  E'

• (: nice builtin Commented Oct 13, 2017 at 14:39
• @EriktheOutgolfer I think it's similar to 05AB1E's ǝ? Ah, but that doesn't seem to vectorize over the second/third inputs Commented Oct 13, 2017 at 14:46
• Exactly why it's unique :p and also how MATL auto-fills with 0s and displays 0 as space. Commented Oct 13, 2017 at 14:50
• @LuisMendo Nice answer. Out of curiosity, and this question is probably applicable to most stack based langs, when you write in MATL do you need to keep track of the stack (eg, in a line above the code, or a piece of paper, etc) as you compose code? Or has it become natural enough to you that you don't? Commented Oct 14, 2017 at 1:20
• Heh - learned something new today; you can index into the same position twice without any problem in MATL(AB). I already started writing a complicated loop-based answer because I assumed it would give an error otherwise. Commented Oct 15, 2017 at 12:07

# R, 140133129 74 bytes

Saved a ton of bytes porting an ASCII value approach like everyone else. Sad I didn't think of it before :(

function(s){F[X-65+1:sum(X|1)]=X=utf8ToInt(s)
F[is.na(F)]=32
intToUtf8(F)}


Try it online!

### original answer, 129 bytes:

function(s){o=rep(' ',(n=nchar(s))+25)
for(i in 1:n){k=substr(s,i,i)
o[x<-i+match(k,LETTERS)-1]=k
F=max(F,x)}
cat(o[1:F],sep='')}


Try it online!

generates a too-long list o of spaces, then iterates through s, replacing the values in o with the correct value and updating F, the position of the rightmost character. Then prints out the first F elements of o with no separators between them.

# 05AB1E, 20 16 bytes

-4 bytes thanks to Emigna

ð₄×svyAuykN+ǝ}ðÜ


Try it online!

• I think you can shorten to ð₄×svyAuykN+ǝ}ðÜ at least. Also, is there a guarantee that the input string shifted isn't larger than 1000 chars? If not, g₂+ð× should work. Commented Oct 13, 2017 at 14:10

# JavaScript (ES6), 81 bytes

s=>[...s].map((c,i)=>a[i+parseInt(c,36)-10]=c,a=[])&&[...a].map(c=>c||" ").join


Somewhat builds off of Rick Hitchcock's incomplete answer but ended up rather different.

Places the characters into their respective index of an empty array, then uses array spread ([...a]) to turn the missing elements into undefined, allowing map to replace empty elements with a space.

## Test Cases

let f=
s=>[...s].map((c,i)=>a[i+parseInt(c,36)-10]=c,a=[])&&[...a].map(c=>c||" ").join

;["AZ", "ABC", "ACE", "CBA", "HELLOWORLD"]
.forEach(t=>console.log("${t}", "=>", "${f(t)}"))

• Very nice! I was about to post an 88-byte solution, but yours is much better. Commented Oct 13, 2017 at 19:45

## Perl 5, 42 bytes

41 bytes code + 1 for -p. The \x1bs in the code are literal escape characters.

Relies on ANSI escape sequences to position the cursor and therefore doesn't work on TIO.

s/./($-=-65+ord$&)?"\x1b[$-C$&\x1b[--$-D":$&/ge


### Usage

perl -pe 's/./($-=-65+ord$&)?"\x1b[$-C$&\x1b[--$-D":$&/ge' <<< 'HELLOWORLD'
E H    DLL   OLO   R  W

• Here's one that works on TIO but comes in at one byte more (41 bytes of code + 2 for -F): Try it online! Commented Oct 13, 2017 at 18:03
• @Xcali You should post that so I can upvote it :)
– lynn
Commented Oct 13, 2017 at 18:46
• @Xcali Agree with Lynn too more posts are great. I like language competition too! Commented Oct 13, 2017 at 21:08

# Java (OpenJDK 8), 207191189183178174173 170 bytes

s->{char i=0,l,c[]=new char[s.chars().map(j->j+s.lastIndexOf(j)).max().getAsInt()-64];for(;i<s.length();c[i+l-66]=l)l=s.charAt(i++);return"".valueOf(c).replace('',' ');}


Try it online!

# Perl 5, 41 + (-F) = 43 bytes

map$r[$i++-65+ord]=$_,@F;print$_||$"for@r  Try it online! Just for @lynn # brainfuck, 127 bytes ,[[-<+<+>>]----[----<<->>]<<-[[>]>++++>[-<[-]<+>>]<[-<++++++++>]<[<]>-]>[>]<[-]+[<]>-[[>]<+[<]>-]>.[-]>[>]<[[->>+<<]<]>,]>>[.>]  Try it online! ### Explanation ,[ Take input and start main loop [-<+<+>>] Make two copies of input byte ----[----<<->>]<<- Subtract 64 from one of them to get position in alphabet There are two zero cells between the input and the remaining output cells; we wish to move these zeroes to indicate where the letter is to be moved [ A number of times equal to the position in the alphabet: [>] Go to current position in output string >++++> Create 4 (as part of creating a space if needed) [-<[-]<+>>] Move output byte back two cells; zero the previous 4 if output existed <[-<++++++++>] Otherwise move a space (32) into that position <[<]>- Move back to counter and decrement ] >[>]<[-] Delete last moved byte to make room for input byte +[<]>- Initialize slot at 1 so it is always nonzero in this loop [[>]<+[<]>-] Move input byte into slot >.[-] Output next output byte and clear >[>]< Move to space vacated in preparation to remove gap (Moves to end instead if input was A; this causes no problems) [[->>+<<]<] Move values two cells right until zero reached >, Get into position and take another byte of input ] >>[.>] Output characters beyond end of input  # Proton, 78 bytes x=>{t=[' ']*26*(q=len(x))for i:0..q{t[i+ord(k=x[i])-65]=k}"".join(t).rstrip()}  Try it online! 69 bytes by porting Lynn's solution: x=>{t=[]i=65for k:x{t+=[' ']*26t[ord(k)-i]=k;i--}"".join(t).rstrip()} # Jelly, 20 bytes ØAiÐ€+JṬ€a"⁸Zḟ€0Ṫ€o⁶  Try it online! # Haskell, 90 88 bytes d=drop 1 [a]#s|s<"A"=a:d s|0<1=s b#s=(s++" ")!!0:d b#d s f(c:t)=['A'..c]#(' ':f t) f s=s  Try it online! • @Laikoni Oh dang, I misread that. Will fix... Commented Oct 13, 2017 at 21:04 • Well, it's no longer shorter. :/ Commented Oct 13, 2017 at 21:13 # Japt, 23 bytes ;iB ç Ng £=hX10nY+XnG U  Test it online! First attempt, may be improvable... • It looks like you should be able to save a byte by assigning the initial string to V instead of U: ethproductions.github.io/japt/… Commented Oct 13, 2017 at 21:02 # Wolfram Language (Mathematica), 76 bytes SparseArray[Reverse@MapIndexed[#&@@#2+LetterNumber@#-1->#&,#]]<>""/. 0->" "&  Takes a list of characters as input. This generates some error messages that are safe to ignore. I included Print and Character command in the footer of the TIO link for ease of use. (Character command simply converts a string to a list of characters) Try it online! • LetterNumber is a built-in for finding the position of a letter in the alphabet? Holy crap, that's ridiculous. Commented Oct 14, 2017 at 6:40 # J, 37 31 bytes [](' '#~(1+>./)@])}(i.@#+65-~a.&i.) [](' '#~(1+>./)@])}#\-66-3&u:  -6 bytes thanks to FrownyFrog ### explanation The entire thing is a hook: [](' '#~(1+>./)@])} #\-66-3&u:  The right side calculates the new indexes for all the letters. The left side uses the gerund form of Amend } first to create a string of the necessary number of spaces: (' '#~(1+>./)@]) . And then to place each letter of the original string into its appropriate index within the all-space string. Try it online! • (i.@#+65-~a.&i.) -> (i.@#+65-~3&u:) -> (i.@#-65-3&u:) -> (#\-66-3&u:) Commented Oct 13, 2017 at 17:13 • You can drop the parentheses too. Commented Oct 13, 2017 at 17:18 • @FrownyFrog tyvm. i'd forgotten about both those golf tricks. Commented Oct 13, 2017 at 17:52 • You can save 3 bytes with (]' '#~1+>./) Commented Oct 14, 2017 at 1:28 • @miles. Nice. I need to make dyadic hooks part of my regular toolbox, I noticed you used them in that revision from this morning as well. Commented Oct 14, 2017 at 1:49 # Haskell, 88 bytes foldr(\c->(((['B'..c]>>" ")++[c])#).(' ':))[] (x:r)#(y:t)|y>' '=y:r#t|1<3=x:r#t r#t=r++t  Try it online! ## Haskell, 88 bytes f s|q<-zipWith((+).fromEnum)s[0..]=[last$' ':[c|(c,i)<-zip s q,i==p]|p<-[65..maximum q]]


Try it online!

q is the list of the final indices of the letters of the input string (with an offset of 65). Loop through all indices (starting at 65) and find all letters for it, prepending a space. Take the last.

• Yet another 88 byte Haskell solution, see here and here.
– nimi
Commented Oct 14, 2017 at 17:51

# C# (.NET Core), 117110 84 bytes

Saved 7 bytes thanks to Ayb4tu.

Changed return type from string to char[] to save 26 bytes.

n=>{int i=0,l=n.Length;var t=new char[l+26];for(;i<l;)t[i+n[i]-65]=n[i++];return t;}


Try it online!

• You can save 7 bytes by changing t[i+((int)n[i]-65)] to t[i+n[i]-65]. Commented Oct 14, 2017 at 9:28
• @Ayb4btu Thanks forgot that char -> int conversions are implicit. Commented Oct 14, 2017 at 9:37

# C# .NET, 89 Bytes 87 Bytes

-2 bytes thanks to Lan H.

f=>{var s=new char[f.Length+26];for(int i=0;i<f.Length;i++)s[f[i]+i-65]=f[i];return s;}


Try it Online!

• Welcome to the site! :) Commented Oct 16, 2017 at 15:44
• Thanks! I hope it's ok to post multiple answer in the same language Commented Oct 16, 2017 at 16:07
• You can omit the curly brackets in your for-loop for -2 bytes. Commented Oct 16, 2017 at 20:50

# Kotlin, 207 bytes189 bytes187 bytes 177 bytes

fun main(){val i=(readLine()+" ".repeat(26)).toCharArray();for(x in(i.size-1) downTo 0){if(i[x]!=' '){i[x+i[x].toInt()-65]=i[x];i[x]=' '}};print(i.joinToString("").trim())}


If the leading blank should remain I would just call trimEnd() instead of trim().

Unminified:

fun main() {
val m = (readLine() + " ".repeat(26)).toCharArray()
for (x in (m.size - 1) downTo 0) {
if(m[x] != ' ') {
m[x + m[x].toInt() - 65] = m[x]
m[x] = ' '
}
}

print(m.joinToString("").trim())
}


Maybe Kotlin is not the best language for code golfing but I liked the challenge and I wanted to make myself more familiar with Kotlin's standard library.

# q/kdb+, 37 bytes

Solution:

@[max[1+m]#" ";m:!:[x#:]+.Q.A?x;:;]x:


Examples:

q)@[max[1+m]#" ";m:!:[x#:]+.Q.A?x;:;]x:"AZ"
"A                         Z"
q)@[max[1+m]#" ";m:!:[x#:]+.Q.A?x;:;]x:"ABC"
"A B C"
q)@[max[1+m]#" ";m:!:[x#:]+.Q.A?x;:;]x:"ACE"
"A  C  E"
q)@[max[1+m]#" ";m:!:[x#:]+.Q.A?x;:;]x:"CBA"
"  A"
q)@[max[1+m]#" ";m:!:[x#:]+.Q.A?x;:;]x:"HELLOWORLD"
"     E H    DLL   OLO   R  W"


Explanation:

I think this is the same idea as the J solution, calculate the correct indices for the input array and then assign them to an empty string of correct length:

@[max[1+m]#" ";m:til[count x]+.Q.A?x;:;]x: / ungolfed solution
x: / save input as x
@[            ;                     ; ;]   / apply[variable;indices;function;parameters]
:     / assignment
.Q.A?x       / location of x in uppercase alphabet
+             / added to
count x               / length of input
til[       ]              / range, 0..n
m:                          / save as m
max[   ]                                 / maximum of list
1+m                                  / m + 1
#" "                             / take " ", creates empty character list


# Jq 1.5, 91 bytes

reduce(explode|[.,keys]|transpose[]|.[1]+=.[0]-65)as[$c,$p]([];.[$p]=$c)|map(.//32)|implode


Expanded

  reduce(  explode         # convert string to array of ordinals
| [.,keys]        # [ [v0,v1,...], [0,1,2,...] ]
| transpose[]     # [ [v0,0], [v1,1], [v2,2]...]
| .[1]+=.[0]-65   # adjust position of each value
) as[$c,$p] (
[]
; .[$p]=$c               # store each value at its position
)
| map(.//32)               # map null values to spaces
| implode                  # convert back to string


Try it online!

# Charcoal, 16 bytes

Ｐ ＦＳ«Ｍ⌕αι→ιＭ⌕αι←


Try it online! Link is to verbose version of code. Explanation:

Ｐ                   Output a space to force the indent
Ｓ                Input string
Ｆ «               Loop over each letter
α            Uppercase letters predefined variable
⌕ ι           Find index of current letter
Ｍ   →          Move that many characters right
ι         Implicitly print the current letter
Ｍ⌕αι←    Move the same number of characters left


# APL (Dyalog), 26 bytes

Anonymous prefix lambda which takes the input string as argument and returns the output string. Assumes ⎕IO (Index Origin) 0, which is default on many systems.

{⍵@i⊢''↑⍨1+⌈/i←(⎕A⍳⍵)+⍳≢⍵}


Try it online!

{} anonymous lambda; ⍵ represents the argument

≢⍵ tally of the argument

⍳ than many ɩntegers (0…LengthOfArgument-1)

()+ plus:

⎕A⍳⍵ the indices of the argument in the uppercase Alphabet

i← strore in i (for indices)

⌈/ maximum (reduction)

1+ add one

''↑⍨ take that many characters from the empty string, padding with spaces as needed

⊢ yield that (serves to separate i from '')

⍵@i amend that with the argument letters at the i indices

# SOGL V0.12, 10 bytes

ā,{ZFWē+1ž


Try it Here!

Explanation:

ā           push an empty array
,{         for each char in the input
ZFW        get its index in the uppercase alphabet
ē+      add to that the 0-indexed counter
1ž    at [pop; 1] insert in the array the current character


# Pyth, 44 38 bytes

Striked out 44 is still 44 :(

Bloody Pyth beginner.

Saved 6 bytes thanks to @Mr. Xcoder.

K*d+lz26Vlz K=XK-C@zN-65N@zN;.WqeHdPZK


Try it online!

How?

K*d+lz26Vlz K=XK-C@zN-65N@zN;.WqeHdPZK          Full program

K*d+lz26                                        Assign a string consisting of
(26 + input.length) whitespaces to K
Vlz                                     For-loop from 0 to input.length
-C@zN-65N                       Calculate the index for the current letter
@zN                    The current letter
K=XK                                Insert the current letter into K at
position i
;                   End statement
.WqeHdPZK          While the last character of H is not a
whitespace, pop the last character off K

• 38 bytes: K*d+lz26Vlz K=XK-C@zN-65N@zN;.WqeHdPZK. WqeKd K=PK;K is replaced by .W (functional while) and its arguments of course, and FNrZlz can be replaced VrZlz, but rZ... means U..., and U is generated automatically by V. So FNrZlz becomes Vlz Commented Oct 17, 2017 at 10:55

# Batch, 418 331 bytes

Works with uppercase letters only and will take some seconds for longer strings.

Learned new tricks here, the character to ASCII value conversion using %=exitcodeAscii%. Also, if defined and "array" access using call. Also, golfing by almost 100 bytes was good batch code golf training.

Note the trailing space in set z=set.

@echo off
setlocal EnableDelayedExpansion
set z=set
%z%a=%1
:a
%z%v=64
:b
%z%/Av+=1
cmd/Cexit %v%
if %=exitcodeAscii% neq %a:~0,1% goto b
%z%/Ao=v+c
%z%a%o%=%a:~0,1%
if %o%. geq %m%. %z%m=%o%
%z%/Ac+=1
%z%a=%a:~1%
if %a%. neq . goto a
for /l %%n in (65,1,%m%)do (
if defined a%%n (call %z%r=%%r%%%%a%%n%%
)else %z%r=!r! )
echo %r%


# Ruby, 68 bytes

->s{r,w="",-66;s.bytes{|b|r[(b+w+=1).times{|a|r[a]||=" "}]=b.chr};r}


Try it online!

# x86-16 machine code, PC DOS, 27 bytes

00000000: b403 cd10 d1ee ad98 91ac b402 8ad0 80ea  ................
00000010: 4102 d343 cd10 cd29 e2ef c3              A..C...)...


Listing:

B4 03       MOV  AH, 3          ; get current cursor position row into DH
CD 10       INT  10H            ; call BIOS
D1 EE       SHR  SI, 1          ; SI to DOS PSP
AD          LODSW               ; AL = command line string length
98          CBW                 ; AH = 0
91          XCHG AX, CX         ; CX = length
OUTPUT:
AC          LODSB               ; load DS:SI into AL
B4 02       MOV  AH, 2          ; BIOS set cursor position function
8A D0       MOV  DL, AL         ; ASCII char to DL
80 EA 41    SUB  DL, 'A'        ; convert ASCII char to numeric val (A=0, Z=25)
02 D3       ADD  DL, BL         ; add current position offset
43          INC  BX             ; increment position offset
CD 10       INT  10H            ; move cursor to column in DL
CD 29       INT  29H            ; write char in AL to console
E2 EF       LOOP OUTPUT         ; loop until end of input
C3          RET                 ; exit to DOS


Standalone PC DOS executable. Input from command line and prints the new "faster" version to console.

Output:

# PHP, 127 123 bytes

function b($i){for($q=0;$q<strlen($i);$q++){$n[ord($i[$q])-65]=$i[$q];}while($x++<26){$m.=$n[$x-1]?$n[$x-1]:" ";}return\$m;}


Try it online

Had to fix a bug that wouldn't output 'A'...

• To who-ever downvoted: You probably mis-clicked the up-button. Please correct, or drop me a line on why the downvote... Tnx Commented Oct 13, 2017 at 21:47