You've been given a task to take notes for a meeting. You start typing on your Google Doc, but you don't have enough time during the meeting to look at your keyboard while you type.

Fortunately for you, you can type without looking at your keyboard. After the meeting, you realize that everything you typed was one key to the left.

The Challenge

For this challenge, you will be using the letters, numbers, and space bar of the QWERTY keyboard layout.

  • Given an input of text (from any standard input method), output the resulting text, where every character is moved one to the left on the keyboard.

    • For the majority of letters, just look at the letter and translate it to the letter to the left (c becomes x, t becomes r, etc).

    • For letter q, translate to a literal tab character (\t).

    • For letter a, enable caps lock, so the capitalization of the rest of the string is reversed.

    • For letter z, capitalize the next letter in the string.

    • No translation is required for the space bar.

  • Preserve capitalization while translating, and be mindful of caps lock (if caps lock is enabled, make sure the case is the opposite).

  • All characters in the input string will be letters, numbers, or a space. No punctuation or other characters can be included.

Test Cases

\t is a literal tab character

Hello world    -> Gwkki qieks
Code Golf      -> Xisw Fikd
Queried apples -> \tyweuws OOKWA


Lowest score in bytes wins. Have fun!

  • 11
    \$\begingroup\$ A quick reference of the relevant rows of the QWERTY keyboard would be useful, and keep the challenge self-contained \$\endgroup\$
    – Jo King
    Commented Oct 9, 2019 at 1:17
  • 4
    \$\begingroup\$ Do numbers get shifted up to punctuation if there was a "Z" prior to them? \$\endgroup\$
    – ErikF
    Commented Oct 9, 2019 at 1:27
  • 10
    \$\begingroup\$ But Z corresponds to shift...? \$\endgroup\$ Commented Oct 9, 2019 at 1:34
  • 4
    \$\begingroup\$ Suggested test case: Azerty -> wERT \$\endgroup\$
    – Jitse
    Commented Oct 9, 2019 at 7:28
  • 5
    \$\begingroup\$ For letter z, capitalize the next letter in the string -> does that mean that we only have to care about letter capitalization and don't have to toggle between digits and symbols? What's the expected output for 0123456789, a0123456789 and z0z1z2z3z4z5z6z7z8z9? (Besides, on many non-QWERTY keyboards, 'Caps Lock' really acts as a 'Shift Lock'. I believe that QWERTY doesn't follow this pattern, but it should be specified for those of us who are not familiar with it.) \$\endgroup\$
    – Arnauld
    Commented Oct 9, 2019 at 9:02

5 Answers 5


JavaScript (V8), 271 bytes

f=(s,k='~!@#$%^&*()_+`1234567890-=\tQWERTYUIOP{}|\tqwertyuiop[]\\ASDFGHJKL:"\n\\asdfghjkl;\'ZXCVBNM<>?zxcvbnm,./')=>s.replace(/[^ ]/g,c=>k[k.indexOf(c)-1]).replace(/\\([^\\]*)\\?/g,(m,c)=>c.replace(/[a-zA-z]/g,l=>l>'Z'?l.toUpperCase():l.toLowerCase())).replace(/[?']/,"")

Try it online! My first JavaScript code golf. It could definitely be shorter, but I think this is a good start.
It basically finds each character in the k string and replaces it with the previous one, then swaps the case of everything between the A or a, and removes all occurences of Z or z (as shift key does nothing on its own).
This should be a normal QWERTY keyboard layout, but let me know if not.

  • \$\begingroup\$ In your own TIO link, zebras=>wveA test case seems to be wrong. The first z should cause the e to print an uppercase w. From OP: "For letter z, capitalize the next letter in the string." \$\endgroup\$
    – Night2
    Commented Oct 9, 2019 at 11:19
  • \$\begingroup\$ @Night2 Cheers, I posted before OP made the clarification. I assumed pressing the shift key once will do nothing. \$\endgroup\$ Commented Oct 9, 2019 at 20:43

Python 3, 211 bytes

d=' ~!@#$%^&*()`~1!2@3#4$5%6^7&8*9(0)		qQwWeErRtTyYuUiIoOpPaAsSdDfFgGhHjJkKlLzZxXcCvVbBnNmM  '
for i in input():k=d.find(i);print(end=d[k-2+(c*i.isalpha()^s)*(1-k%2*2)][i in'aAzZ':]);c^=i in'aA';s=i in'zZ'

Try it online!

Uses a lookup string in which the normal character and its shift-modified version are grouped together. For each character in the input, it will retreive the character two places to the left. Changes capitalization by adding 1 (or -1 if the current character is uppercase) to the lookup value when shift XOR caps lock is active. Numbers are not influenced by the caps lock modifier.


PHP, 227 bytes

for(;''<$s=$argn[$i++];)$s!=a&&$s!=A?$s!=z&&$s!=Z?($t=$m[stripos($m='~1!2@3#4$5%6^7&8*9(0	qwertyuiopasdfghjklzxcvbnm',$s)-1])+(print$s>' '?$s<A?!$h?$s-1?$s?$s-1:9:'`':$t:($t>=A&&(($s<a)+$h+$c)%2?$t^' ':$t):$s)+$h=0:$h=1:$c=!$c;

Try it online!

I have created a mapping string (~1!2@3#4$5%6^7&8*9(0 qwertyuiopasdfghjklzxcvbnm) which for each digit has their SHIFT mode on the left and for each letter has the letter/key to their left.

I loop over input characters and for each character:

  • If character is a or A, caps lock flag gets reversed (logical not).
  • If character is z or Z, shift flag is set to 1.
  • When character is not in aAzZ:
    • Character to the left of current character in the mapping string is stored in $t.
    • If current character is an space, it is printed.
    • If current character is a digit, and if shift flag is 1, $t is printed, else, if digit is 1, ` is printed, if digit is 0, 9 is printed and otherwise, digit-1 is printed.
    • If current character is a letter, based on status of shift flag, caps lock flag and casing of current character (lower/upper), $t in lower or upper case is printed. The only special case here is tab character, which is printed as is.
    • Shift flag is always set back to 0 at the end.

Red, 218 bytes

func[t][c: z: 0 rejoin collect[foreach s t[case[find"Aa"s[c: c xor 32]find"Zz"s[z: 32]on
[keep(select/case"  poiuytrewq^-lkjhgfdsamnbvcxzPOIUYTREWQ^-LKJHGFDSAMNBVCXZ0987654321~"s)xor either s <#"Z"[0][c xor z]z: 0]]]]]

Try it online!

Currently AaZz don't affect digits.

  • \$\begingroup\$ This does not seem to work for 'A pear' -> ' OWe' \$\endgroup\$
    – Jitse
    Commented Oct 9, 2019 at 9:00
  • \$\begingroup\$ @Jitse Hmm \$\endgroup\$ Commented Oct 9, 2019 at 9:04
  • \$\begingroup\$ @Jitse But really doesn't work well with digits, it is not entirely clear from the OP \$\endgroup\$ Commented Oct 9, 2019 at 9:07
  • 2
    \$\begingroup\$ I agree, the challenge is very ambiguous as is. \$\endgroup\$
    – Jitse
    Commented Oct 9, 2019 at 9:13

C (gcc), 276 bytes

i;j;k;h;l;m;n;o;f(char*b){char*c=calloc(m=strlen(b),1),*a=" \tqwertyuiop\aasdfghjkl\nzxcvbnm\tQWERTYUIOP\aASDFGHJKL\nZXCVBNM`1234567890";for(i=k=j=n=0;j<=m;l=a[i=index(a,b[j++])-a-1])k=l^7?k:!k,o=l>64&l<91?a[i-30*k]:l<97?h=i?l^7?l?l^10?l:0:32:0:0:a[i+29*k],o?c[n++]=o:n;b=c;}

Thanks to ceilingcat for -33 bytes.

Try it online!

  • \$\begingroup\$ Suggest k^=!(l^7) instead of k=l^7?k:!k \$\endgroup\$
    – ceilingcat
    Commented Feb 26, 2020 at 2:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.