Знайдіть середнє значення слова

Funky Computer Man 09/24/2017. 7 answers, 530 views
code-golf string keyboard

Inspired by this chat message

Ваше завдання полягає в тому, щоб прийняти слово і знайти середню позицію своїх літер на клавіатурі як букву.

Макет клавіатури

Оскільки макети відрізняються від клавіатури до клавіатури, ми будемо використовувати стандартний на основі моєї власної клавіатури в цьому питанні.

Клавіатура має 3 рядки, а верхній рядок зліва направо містить ключі

QWERTYUIOP 

Другий рядок містить букви

ASDFGHJKL 

Останній рядок містить

ZXCVBNM 

Кожна буква 1 горизонтальна від сусідки ліворуч. Це означає, що W знаходиться на відстані 1 від Q а E - 1 від W і так далі.

Ключі на початку кожного рядка мають позиції:

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

Це означає, що рядки відокремлені один від одного вертикально, а нижні два рядки зміщуються на третину від ряду над ними.


Ви повинні прийняти слово як введення та вивести букву, яка є найближчою до середньої позиції букв у своєму слові. Середнє набору векторів становить

(average x value, average y value) 

Коли дві клавіші рівномірно від середнього, ви можете вивести їх як "найближчий" ключ.

Це тому відповіді будуть оцінені в байтах, де краще байтів.

Приклад рішення

Давайте обчислимо середнє значення APL .

Ми конвертуємо кожну букву в вектор

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

Додаємо ці три вектори, щоб отримати (17 2/3, 2) . Потім ми розділимо кожну координату на 3 (кількість букв у слово), щоб отримати (5 8/9, 2/3) .

Найближчим листом до (5 8/9, 2/3) є J при (6 1/3,1) тому наш результат є J

Тестові випадки

APL  -> J
TEXT -> R
PPCG -> J
QQQQ -> Q
ZZZZ -> Z
PPPP -> P
MMMM -> M
QQSS -> A or W 
5 Comments
1 Funky Computer Man 09/24/2017
@ cairdcoinheringaahing 1) Це насправді не має значення, тому що математика працює так довго, як його постійна. 2) Можна з технічної точки зору зробити висновок, що це 1, оскільки ключі QAZ знаходяться на відстані 1 одиниці від одного, але я все одно додам його до питання. :)
4 caird coinheringaahing 09/24/2017
Я прочитав це питання кілька разів і до сих пір не розумію позиціонування листів по відношенню один до одного і як це відповідає середній позиції. Саме з цієї причини я проголосував, щоб закрити незрозумілим.
4 Jenny_mathy 09/24/2017
Я думаю, ви повинні розглянути можливість використання пісочниці. Ми не можемо зрозуміти лише деякі тривіальні тестові випадки. Ви повинні визначити середню позицію і навести детальні приклади
2 Misha Lavrov 09/24/2017
Здається, прямо для мене. Якщо у вас є точка А (0.333,1) і точка Р (9,0) і точка L при (8.333, 1), то їх середнє значення (5.889, 0.667) найближче до J при (6.333, 1).
2 Funky Computer Man 09/24/2017
@ Jenny_mathy Я розглянув використання пісочниці. Фактично я використовував пісочницю десятки разів. Я виявив, що він стає непотрібним і іноді контрпродуктивним. Я не розумію, чому люди не можуть поважати моє рішення не використовувати entirely optional пісочницю.

7 Answers


Ian H. 09/24/2017.

C # (.NET Core) , 250 + 13 байт

+13 байт для 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)];} 

Спробуйте онлайн!

Маленька sidenote: ці виводи F для TEXT , оскільки це було оригінальним бажаним результатом.
Вивід R замість F змінено після того, як була опублікована відповідь.


Lynn 09/24/2017.

Пітон 3 , 130 байт

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

Спробуйте онлайн!

d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)} конструює відображення від букв до точок (представлений як складні числа, (x+y*1j) ).

Що стосується тіла лямбда, то sum(map(d.get,w))/len(w) обчислює середню позицію слова w і ставить його в min(d,key=lambda c:abs(d[c]-…)) знаходить найближчий лист до цієї позиції. (Для складних чисел abs(A-B) відповідає евклідової відстані між (A.real, A.imag) і (B.real, B.imag) .)


Tahg 09/24/2017.

Java 257 243 242 237 байт

char h(String s){int l=s.length(),i=l+28;s="QAZWSXEDCRFVTGBYHNUJMIK
    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))

Збережено 14 байтів - відстань від кращого ключа буде менше 3 одиниць


HyperNeutrino 09/24/2017.

Желе , 37 байт

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

Спробуйте онлайн!

Lol занадто довго

Пояснення

Ø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 
3 comments
HyperNeutrino 09/24/2017
@downvoter виправлено проблему з тестовим клопотом; будь ласка, вилучіть вашу низхідну або пояснити, чому ви хочете знизити мою відповідь
Erik the Outgolfer 09/24/2017
Я думаю, що знову з цим не згоден? F , здається, не є дозволеним виходом більше ...
HyperNeutrino 09/24/2017
@EriktheOutgolfer Ах, добре, я не оновив це зауваження після того, як FCM виправив тестовий випадок

Neil 09/24/2017.

JavaScript (ES6), 166 байт

 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) 
 
 

6 байтів можна було зберегти, переключившись на ES7. Попередній 131-байтовий розчин використовував спрощену перевірку відстані, яка вже не є прийнятною.

 f=
s=>([...s].map(c=>(h+=c=s.search(c),v+=c%3,l++),h=v=l=0,s='QAZWSXEDCRFVTGBYHNUJMIKKOLLP'),v=(v/l+.5|0),h=((h/l-v)/3+.5|0),s[h*3+v]) 
 
 


Jenny_mathy 09/24/2017.

Mathematica, 234 байти

(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)& 
1 comments
Jenny_mathy 09/24/2017
Виправлено! працює для всіх тестів.

Roberto Graham 09/25/2017.

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

Щось для початку гольфу

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

Спробуйте онлайн!

5 comments
Ian H. 09/24/2017
Дає мені неправильний результат для TEXT .
Roberto Graham 09/24/2017
@IanH Це дає мені "R", про що О.П. запитував
Ian H. 09/24/2017
Не бачив, що це було змінено у завданні, мій поганий.
Tahg 09/24/2017
Я не бачив цієї відповіді, коли я опублікував мою, чи повинен я запропонувати мій як коментар або чи є кілька відповідей на одну і ту ж мову добре?

Related questions

Hot questions

Language

Popular Tags