Encontre a média de uma palavra

8

Inspirado por esta mensagem de bate-papo

Sua tarefa será pegar uma palavra e encontrar a posição média de suas letras no teclado como uma letra.

Layout do teclado

Como os layouts variam de teclado para teclado, usaremos um padrão baseado no meu próprio teclado nesta pergunta.

O teclado possui 3 linhas, a linha superior da esquerda para a direita contém as teclas

QWERTYUIOP

A segunda linha contém as letras

ASDFGHJKL

A linha final contém

ZXCVBNM

Cada letra tem 1 unidade na horizontal do vizinho para a esquerda. Isso significa que Westá 1 de distância Qe E1 de distância We assim por diante.

As teclas no início de cada linha têm as posições:

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

Isso significa que as linhas são separadas uma unidade verticalmente e as duas linhas inferiores são deslocadas em um terço da linha acima delas.


Você deve usar uma palavra como entrada e produzir a letra mais próxima da posição média das letras em sua palavra. A média de um conjunto de vetores é

(average x value, average y value)

Quando duas teclas estão equidistantes da média, você pode exibir a tecla "mais próxima".

Isso é então as respostas serão pontuadas em bytes, com menos bytes sendo melhores.

Solução de exemplo

Vamos calcular a média de APL.

Convertemos cada letra em um vetor

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

Nós adicionamos esses três vetores para obter (17 2/3, 2). Em seguida, dividimos cada coordenada por 3 (o número de letras da palavra) para obter (5 8/9, 2/3).

A letra mais próxima de (5 8/9, 2/3)está Jem, (6 1/3,1)portanto, nosso resultado é J.

Casos de teste

APL  -> J
TEXT -> R
PPCG -> J
QQQQ -> Q
ZZZZ -> Z
PPPP -> P
MMMM -> M
QQSS -> A or W
Caçador Ad Hoc Garf
fonte

Respostas:

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)];}

Experimente online!

Pouco sidenote: Este saídas Fpara TEXT, uma vez que era a saída desejada originais.
A saída em Rvez de Ffoi alterada após esta resposta ter sido publicada.

Ian H.
fonte
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>

6 bytes podem ser salvos mudando para o ES7. A solução anterior de 131 bytes usou uma verificação de distância simplista, que não é mais aceitável.

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

Experimente online!

d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)}constrói o mapeamento de letras para pontos (representados como números complexos (x+y*1j)).

Quanto ao corpo lambda, sum(map(d.get,w))/len(w)calcula a posição média da palavra we, ao colocá-lo, min(d,key=lambda c:abs(d[c]-…))encontra a letra mais próxima dessa posição. (Para números complexos, abs(A-B)corresponde à distância euclidiana entre (A.real, A.imag)e (B.real, B.imag).)

Lynn
fonte
2

Java, 257243242 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 salvos - a distância da melhor chave será menor que 3 unidades

Tahg
fonte
1

Geléia , 37 bytes

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

Experimente online!

lol muito tempo

Explicação

Ø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
HyperNeutrino
fonte
@ downvoter o problema com o caso de teste foi corrigido; remova sua downvote ou explicar por que você deseja downvote minha resposta
HyperNeutrino
Eu acho que discorda de novo? Fnão parece ser uma saída mais permitidos ...
Erik o Outgolfer
@EriktheOutgolfer Ah bem, eu não atualizar essa observação após FCM corrigido o caso de teste
HyperNeutrino
1

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

Algo para começar a jogar golfe

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

Experimente online!

Roberto Graham
fonte
Dá-me o resultado errado para TEXT.
Ian H.
@IanH. Dá-me 'R' que é o OP pediu
Roberto Graham
Não vi que isso foi alterado na tarefa, meu mal.
Ian H.
1
431 bytes .
Jonathan Frech 24/09
Eu não tinha visto essa resposta quando publiquei a minha, deveria ter sugerido a minha como comentário ou há várias respostas para o mesmo idioma, ok?
Tahg 24/09
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
fonte
Fixo! funciona para todos os casos de teste.
J42161217