Encuentra el promedio de una palabra

8

Inspirado en este mensaje de chat

Su tarea será tomar una palabra y encontrar la posición promedio de sus letras en el teclado como una letra.

Diseño del teclado

Dado que los diseños varían de un teclado a otro, utilizaremos un estándar basado en mi propio teclado en esta pregunta.

El teclado tiene 3 filas, la fila superior de izquierda a derecha contiene las teclas.

QWERTYUIOP

La segunda fila contiene las letras.

ASDFGHJKL

La fila final contiene

ZXCVBNM

Cada letra es 1 unidad horizontal de su vecino a la izquierda. Esto significa que Westá a 1 de distancia Qy Eestá a 1 de distancia, Wetc.

Las teclas al comienzo de cada fila tienen las posiciones:

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

Esto significa que las filas se separan una unidad verticalmente y las dos filas inferiores se desplazan un tercio de la fila por encima de ellas.


Debe tomar una palabra como entrada y salida de la letra más cercana a la posición promedio de las letras en su palabra. El promedio de un conjunto de vectores es

(average x value, average y value)

Cuando dos teclas son equidistantes del promedio, puede generarlas como la tecla "más cercana".

Este es el por lo que las respuestas se puntuarán en bytes, con menos bytes mejor.

Solución de ejemplo

Calculemos el promedio de APL.

Convertimos cada letra a un vector

A -> (1/3,1)
P -> (9,0)
L -> (8 1/3,1)

Sumamos estos tres vectores para obtener (17 2/3, 2). Luego dividimos cada coordenada por 3 (El número de letras en la palabra) para obtener (5 8/9, 2/3).

La carta más cerca (5 8/9, 2/3)es Ja (6 1/3,1)lo que nuestro resultado es J.

Casos de prueba

APL  -> J
TEXT -> R
PPCG -> J
QQQQ -> Q
ZZZZ -> Z
PPPP -> P
MMMM -> M
QQSS -> A or W
Ad Hoc Garf Hunter
fuente

Respuestas:

3

C # (.NET Core) , 250 + 13 bytes

+13 bytes para using System;

n=>{var a=new[]{"QWERTYUIOP","ASDFGHJKL","ZXCVBNM"};float x=0,y=0;int i=0,j=0,l=n.Length;foreach(char c in n){for(i=0,j=0;i<2;){if(a[i][j]==c)break;if(++j>=a[i].Length){i++;j=0;}}x+=j;y+=i;}return a[(int)Math.Round(y/3)][(int)Math.Round(x/l+y/l/3)];}

Pruébalo en línea!

Poco sidenote: Este salidas Fpara TEXT, ya que era la salida deseada originales.
La salida en Rlugar de Fse cambió después de que se publicó esta respuesta.

Ian H.
fuente
2

JavaScript (ES6), 166 bytes

f=
s=>[...s].map(c=>(h+=c=s.search(c),v+=c%3,l++),h=v=l=0,s='QAZWSXEDCRFVTGBYHNUJMIKKOLLP')&&[...s].map((c,i)=>(i=(i-h/l)*(i-h/l)+(i=i%3-v/l)*i*9,i)<m&&(m=i,r=c),m=9)&&r
<input oninput=o.textContent=/^[A-Z]+$/.test(this.value)?f(this.value):``><pre id=o>

Se pueden guardar 6 bytes cambiando a ES7. La solución anterior de 131 bytes utilizaba una verificación de distancia simplista que ya no es aceptable.

Neil
fuente
2

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)))

Pruébalo en línea!

d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)}construye el mapeo de letras a puntos (representado como números complejos (x+y*1j)).

En cuanto al cuerpo lambda, sum(map(d.get,w))/len(w)calcula la posición promedio de la palabra w, y al ponerla se min(d,key=lambda c:abs(d[c]-…))encuentra la letra más cercana a esa posición. (Para números complejos, abs(A-B)corresponde a la distancia euclidiana entre (A.real, A.imag)y (B.real, B.imag).)

Lynn
fuente
2

Java, 257 243 242 237 bytes

char h(String s){int l=s.length(),i=l+28;s="QAZWSXEDCRFVTGBYHNUJMIK<OL>P"+s;float d=9,x=0,y=0,e;for(;i>28;y+=(e=s.indexOf(s.charAt(--i)))%3/l,x+=e/3/l);for(;i-->0;)if((e=(x-i/3f)*(x-i/3f)+(y-i%3)*(y-i%3))<d){d=e;l=i;}return s.charAt(l);}

14 bytes guardados: la distancia desde la mejor clave será inferior a 3 unidades

Tahg
fuente
1

Jalea , 37 bytes

ØQi€µT÷3Ḣ+Ṁ;T
Ç€ZÆmðạ²SðЀØAÇ€¤iṂ$ịØA

Pruébalo en línea!

jaja demasiado tiempo

Explicación

ØQi€µT÷3Ḣ+Ṁ;T            Helper Link; compute the position of a key
   €                     For each row of
ØQ                       ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"] (hooray for builtins)
  i                      Find the first occurrence of the argument
    µ                    Start a new monadic chain
     T                   List of indices of truthy values; singleton list with the row of the key
      ÷                  Divide the index by
       3                 3
        Ḣ                Take the first element
         +               Add it to the original list
          Ṁ              Take the maximum (the adjusted horizontal position of the key)
           ;             Append
            T            The index of the truthy value (the row)
Ç€ZÆmðạ²SðЀØAÇ€¤iṂ$ịØA  Main Link
 €                       For each character in the input
Ç                        Compute its position using the helper link
  Z                      Zip (all of the horizontal positions are in the first list; all of the vertical positions are in the second list)
   Æm                    Take the arithmetic mean (of each sublist)
     ðạ²Sð               Dyadic chain to compute the distance (squared) between two coordinates
      ạ                  Take the absolute difference between each coordinate value (auto-vectorization)
       ²                 Square each value
        S                Take the sum (returns the distance squared but for comparison that's fine)
          Ѐ             Take the distance between the mean position and each element in
            ØAÇ€¤        [Nilad:] the positions of each character in the uppercase alphabet
               €         For each character in
            ØA           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
              Ç          Compute its position
                 iṂ$     Find the index of the minimum (closest)
                 i       First occurrence of             in the list of distances
                  Ṃ                          the minimum
                    ị    Index back into
                     ØA  The alphabet
Hiperneutrino
fuente
@downvoter se ha solucionado el problema con el caso de prueba; por favor, elimine su voto negativo o explique por qué desea rechazar mi respuesta
HyperNeutrino
Creo que no está de acuerdo otra vez? Fya no parece ser una salida permitida ...
Erik the Outgolfer
@EriktheOutgolfer Ah bien, no actualicé ese comentario después de que FCM corrigió el caso de prueba
HyperNeutrino
1

Java (OpenJDK 8) , 452 431 424 400 389 324 322 296 285 281 276 274 260 258 257 bytes

Algo para comenzar a jugar golf

s->{String c="QWERTYUIOPASDFGHJKL;ZXCVBNM";int i=0,r=0,l=0;double x=0,y=0,D=99,t,f=s.length();for(;i<f;x+=l%10+l/10/3d,y+=l/10)l=c.indexOf(s.charAt(i++));for(;r<27;r++)if(D>(t=Math.pow(x/f-r/10/3d-r%10,2)+Math.pow(y/f-r/10,2))){D=t;l=r;}return c.charAt(l);}

Pruébalo en línea!

Roberto Graham
fuente
Me da el resultado incorrecto TEXT.
Ian H.
@IanH. Me da 'R', que es lo que OP solicitó
Roberto Graham
No vi que se cambió en la tarea, mi mal.
Ian H.
1
431 bytes .
Jonathan Frech
No había visto esta respuesta cuando publiqué la mía, ¿debería haber sugerido la mía como un comentario o son múltiples respuestas para el mismo idioma?
Tahg
0

Mathematica, 234 bytes

(r=(K=Round)@Mean[If[(w=First[q=#&@@Position[(s=X/@{"QWERTYUIOP","ASDFGHJKL","ZXCVBNM"}),#]])==1,q=q-1,If[w==2,q=q+{-1,-2/3},q=q+{-1,-1/3}]]&/@(X=Characters)@#];z=If[(h=#&@@r)==0,r=r+1,If[h==1,r=r+{1,2/3},r=r+{1,1/3}]];s[[##]]&@@K@z)&  
J42161217
fuente
¡Fijo! Funciona para todos los casos de prueba.
J42161217