単語の平均を見つける


8

このチャットメッセージに触発されました

あなたの仕事は、単語を取り、キーボード上のその文字の平均的な位置を文字として見つけることです。

キーボード・レイアウト

レイアウトはキーボードごとに異なるため、この質問では自分のキーボードに基づく標準を使用します。

キーボードには3つの行があり、一番上の行には左から右にキーが含まれています

QWERTYUIOP

2行目には文字が含まれています

ASDFGHJKL

最後の行には

ZXCVBNM

各文字は、隣から左に1単位水平です。この手段Wから離れて1であるQE離れてから1であるWというように。

各行の先頭のキーには、次の位置があります。

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

これは、行が垂直方向に1単位分離され、下の2行がその上の行から3分の1シフトされていることを意味します。


入力として単語を取り、その単語内の文字の平均位置に最も近い文字を出力する必要があります。ベクトルのセットの平均は

(average x value, average y value)

2つのキーが平均から等距離にある場合、「最も近い」キーとして出力できます。

これは そのため、回答はバイト単位でスコアリングされ、バイト数が少ないほど優れています。

ソリューションの例

の平均を計算してみましょうAPL

各文字をベクトルに変換します

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

これらを3つのベクトルに加算して取得し(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

回答:


3

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

オンラインでお試しください!

少し補足:これはの出力Fです。これTEXTは元の望ましい出力だったためです。この回答が投稿された後、代わりに
出力が変更されました。RF


2

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)<m&&(m=i,r=c),m=9)&&r
<input oninput=o.textContent=/^[A-Z]+$/.test(this.value)?f(this.value):``><pre id=o>

ES7に切り替えることで6バイト節約できました。以前の131バイトのソリューションでは、単純化された距離チェックが使用されていましたが、これはもはや受け入れられません。


2

Python 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)、wordの平均位置を計算しw、それを入れて、min(d,key=lambda c:abs(d[c]-…))その位置に最も近い文字を見つけます。(複素数の場合、とのabs(A-B)間のユークリッド距離に対応します。)(A.real, A.imag)(B.real, B.imag)


2

Javaの、257の243 242 237バイト

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バイトを節約-最良のキーからの距離は3ユニット未満になります


1

ゼリー、37バイト

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

オンラインでお試しください!

説明

Ø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

@downvoterテストケースの問題が修正されました。あなたの反対票を削除するか、なぜ私の回答に反対票を投じるのかを説明してください
HyperNeutrino

また違うと思いますか?Fもはや許可された出力ではないようです...
Erik the Outgolfer '24

@EriktheOutgolfer FCMがテストケースを修正した後、その発言を更新しませんでした
HyperNeutrino

1

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

オンラインでお試しください!


の結果が間違っていTEXTます。
Ian H.

@IanH。それは私にOPが求めたものである「R」を与えます
Roberto Graham

タスクで変更されたことがわかりませんでした。
Ian H.


私が投稿したときにこの回答を見たことがありませんでした。コメントとして提案した方がいいですか、それとも同じ言語の複数の回答でよろしいですか?
Tahg

0

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

修繕!すべてのテストケースで機能します。
J42161217 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.