Find the average of a word Inspired by this chat message


Your task will be to take a word and find the average position of its letters on the keyboard as a letter.

Keyboard Layout

Since layouts vary from keyboard to keyboard, we will be using a standard based of of my own keyboard in this question.

The keyboard has 3 rows, the top row from left to right contains the keys

QWERTYUIOP


The second row contains the letters

ASDFGHJKL


The final row contains

ZXCVBNM


Each letter is 1 unit horizontal from its neighbor to the left.  This means that W is 1 away from Q and E is 1 away from W and so on.

The keys at the beginning of each row have the positions:

Q : 0,0
A : 1/3,1
Z : 2/3,2


This means that the rows are separated one unit vertically and the bottom two rows are shifted by a third from the row above them.



You should take a word as input and output the letter that is closest to the average position of the letters in its word.  The average of a set of vectors is

(average x value, average y value)


When two keys are equidistant from the average you may output either as the "closest" key.

This is code-golf so answers will be scored in bytes with fewer bytes being better.

Example solution

Let's calculate the average of APL.

We convert each letter to a vector

A -&gt; (1/3,1)
P -&gt; (9,0)
L -&gt; (8 1/3,1)


We add these up the three vectors to get (17 2/3, 2). We then divide each coordinate by 3 (The number of letters in the word) to get (5 8/9, 2/3).

The closest letter to (5 8/9, 2/3) is J at (6 1/3,1) so our result is J.

Test Cases

APL  -&gt; J
TEXT -&gt; R
PPCG -&gt; J
QQQQ -&gt; Q
ZZZZ -&gt; Z
PPPP -&gt; P
MMMM -&gt; M
QQSS -&gt; A or W
Python 3, 130 bytes



lambda w,d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)}:min(d,key=lambda c:abs(d[c]-sum(map(d.get,w))/len(w)))


Try it online!

d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)} constructs the mapping from letters to points (represented as complex numbers, (x+y*1j)).

As for the lambda body, sum(map(d.get,w))/len(w) computes the average position of word w, and putting that in min(d,key=lambda c:abs(d[c]-…)) finds the closest letter to that position. (For complex numbers, abs(A-B) corresponds to the Euclidean distance between (A.real, A.imag) and (B.real, B.imag).)