酔っているタイピスト

バックグラウンド

タイピストは家に帰って酔っ払っています。そして、輸入された手紙は依然として必要です。彼がテキストを正しく吟味するために、彼はテキスト文字bh
vjaracter t0を書いて6heを確実に書いています。しかし、彼はキーのいくつかを逃してしまった。

Youtの仕事は彼のttpingをシミュレートするコスを書くことです。私は間違いの可能性を最小限に抑えるために、コードは短くしなければなりません。

キーボード

The キーボード is a standard ANSI キーボード. In the below image, red text
shows the width of the key. All rows are 1 unit high and unmarked
keys are 1 unit wide.

Reference キーボード

これらのキーは、次の操作を実行します(混乱を避けるためにリストされています)。

  • Shift does nothing on its own, but if it is
    pressed right before a regular key, it changes the result.
  • CapsLock toggles Caps Lock. If Caps Lock is
    on, letter keys output the inverse cased letters.
  • Backspace deletes the last outputted
    character, if any.
  • Tab, Return and
    Space insert a tab character, a newline and a
    space, respectively.
  • Ctrl, Alt are just for
    presentation. They (and missing the キーボード altogether) do
    nothing.
  • All the letter keys produce the marked lowercase letter. If
    Shift is pressed just before them, they produce
    the uppercase letter. Caps Lock reverses the case.
  • All other keys produce the character marked in the middle. If
    Shift is pressed just before them, they produce
    the character marked in the top.

タイピング

In order to generate a character, the typist finds it on the
キーボード and checks if the Shift key needs to be
pressed. If so, he first tries to press and hold a
Shift key. Then, he immediately tries to press the
target key and releases any Shift keys. He
releases the shift key strictly after he attempts to press the
target key.

しかし、酔っ払いのために、彼は頻繁にキーを逃す。これは、ランダムな角度を(一様に)拾い、プレス位置をその方向にランダムな量(適切な分布で)移動させ、そのキーを押すことでシミュレートされます。

チャレンジ

入力として、書き込むテキストと酔っ払いのレベルを示す数値パラメータを受け取ります。上記のアルゴリズムで生成されたタイプミスで、酔っぱらったタイピストが入力したテキストを出力します。

仕様

  • The input text will only contain printable ASCII, tabs and
    newlines.
  • The input parameter is some kind of scalar numeric value. Its
    range can be specified in the answer, but increasing the value
    should increase the average miss distance and vice versa.
  • You may scale the キーボード to any internal size; the unit sizes
    above are just examples.
  • Coordinates used must be accurate to a thousandth of the key
    height.
  • The program should produce different results for every
    invocation. (Things like srand(time(NULL));, i.e.
    changing every second, are good enough.)
  • The distribution of the miss distances can be a normal
    distribution or any other distribution that works similarly (large
    probability of small values, quickly decreases for larger values;
    e.g. negative exponential would be fine).
  • The typist’s finger is a single point. No need to think about
    its radius.
  • The typist can aim anywhere inside a key, as long as it’s not
    on the edge. Center, constant position, etc. are valid.
  • The way you pick Shift keys can be anything. Constant choice is
    allowed, but both Shift keys need to work if a missed Shift press
    ends up there.
  • Shift only affects a key if it is being held (i.e. Shift press
    attempted before another key and succeeded). “Normal” key presses
    that land on Shift do nothing.
  • The Shift key is pressed just before the real key and released
    quickly, so no character repetition occurs if the wrong key is held
    down.

I/Oの例

以下のすべての例は、距離の正規分布を使用し、常に左シフトを選択する参照解からのものです。タブはSEによってスペースとして表示されますが、実際の出力に現れます。

入力: Lorem ipsum dolle amet、consectetuer
adipiscing elit。 Sed posuere interdum sem。クスクス舌炎症候群、ラキニア症候群治療薬。
Mauris varius diam vitae arcu。 Sed arcu lectuus
auctor、コンソーシアム、ベネナティス・エイト・ベイト。 Sed augue orci、lacinia eu
tincidunt、eleifend nec lacusなどがあります。ドンケルの超音速は、中断することができます。 Lorem
ipsum ligula ut heritrerit mollis、ipsum erat vehicula risus、se
suscipit sem libero necat。アリクマは、volutpatをeratします。セドのコグエーはオーケー。
Nulla consectetuer porttitor
pede。鳥インフルエンザの兆候は、鳥インフルエンザに感染している。

  酔っ払い: 0.3
  出力: Lo43m ipsum
dol9rはame5と表示され、elipを入力します。 Aed posuefe interdum sem。
Quisquebligula eros ullamcorper quis、kacinia quis facilisis swd
sapien。 Mauris csrius pham vitae
a5cu.nSedアークレクチャークイック、コンシェルジュデューティー、ヴェネツィア、ヴェネツィア、オーケー、ラシニア、ユダヤ人、エレファントネックラクス。ドンケルの超音速は、中断することができます。
Lirem ipsum ligula、hendrerut mollis、ipsum drat
vehicu;ローソス、サスペンス・リベロが必要です。 AliquM ERAT VOLUTPAT。 NEEDの婚姻交付金AUGUW
VITAW NEQUE。 nuLLAコンセントレータPORTTITOR
PEDE。モーリス・トゥルーガ・マグナ・コンデメントム・ヴェール、ポアラエット・ブランデット・アット・トゥー・トゥーアール

入力:上記と同じです。
  酔っ払い: 2.0
  出力: /KRE 8OS0H4O'LC C8V.A TT0J
J4CT6E 3D6LOA UEOR; e2 'ozhvdf 9ntfc 7; xsm 8HWCE MKVH/25DNL
[4/0VEXSUMV'A IN4Q UNV LOQYY SE2DplxbBkv81 a2ius ajwfrcu;
X線分析法は、エストロゲン/エヘキシー、fdmg73pohf9i、d8n = n87gi wct dfwkejc3ndhzwf8s
atbe ku.i5g eqjc/s; 7hvyfleg u [bdkad/pxelhi'K '、pf5h、ih8l9v yt
ee3f b7、uL TP2O4VGHUT   A NSJl5k q9si5sk5beo8nfyrt O
[A、E3GJL UAH3 fpjUD F6 FY N QJE、NU、L8
OZYFTWTKERPORUTYTOQFEE、GTYSCDまたはS MLEP96'6; CNQRWJXO [OTUUX PORXG
8G。 9GFI4INAU4HT   5CK5

入力:Wikipedia
から)コードゴルフは、参加者が特定のアルゴリズムを実装する最短のソースコードを達成しようとするレクリエーション・コンピューター・プログラミング競技の一種です。コードゴルフは最小のバイナリ実行可能コードを達成するためのコンテストであるサイジングと混同しないでください。コードゴルフをすることは
"ゴルフスクリプト"として知られています。コードゴルフトーナメントには、使用されているプログラミング言語(たとえば、Perlゴルフ)を使用して名前を付けることもできます。

  酔っ払い: 0.5
  アウトプット:
C9ddゴールデングローブは、あなたの身の回りにあった服装を着用していて、着用していない靴は着用していませんでした。
RXECUTABLENVPDE。 oLAH9NG CODW GLLFは
"GOKFSC4JPTIHG"として知られています。コード・ゴール5OURNAMEN5X MAY ALX; Y.
PROGEZMININV LANHUAGEUZDS 9FPTMEXA​​MPLE PERL GOLFとのED)

参照溶液

import random,math
BKSP, CAPS, SHFT, NOOP = 0, 1, 2, 3 # special actions for keys
# data for key rows
rows = [["`~","1!","[email protected]","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",(BKSP,2)],
        [("t",1+1/2),"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}",("\|",1+1/2)],
        [(CAPS,1+2/3),"aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'"",("n",2+1/3)],
        [(SHFT,2+1/6),"zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?",(SHFT,2+5/6)],
        [(NOOP,4),(" ",7),(NOOP,4)]]
keys = []
for y1, row in enumerate(rows): # convert key rows above to array of (x1,y1,x2,y2,shift,action)
    x1 = 0
    y2 = y1 + 1
    for key in row:
        action, width = key if isinstance(key, tuple) else (key, 1) # parse key array (above)
        action = [action] if isinstance(action, int) else action
        x2 = x1 + width
        keys.append((x1, y1, x2, y2, False, action[0])) # add unshifted version
        keys.append((x1, y1, x2, y2, True, action[-1])) # add shifted version
        x1 = x2

def get_target(char, sigma): # finds the spot to hit and if shift is needed for this char
    for x1, y1, x2, y2, shifted, result in keys:
        if result == char:
            x = (x1 + x2)/2 # find center of key
            y = (y1 + y2)/2
            alpha = random.uniform(0, 2 * math.pi) # get random angle
            r = random.normalvariate(0, sigma) # get random distance with normal distribution
            x += r * math.cos(alpha) # add miss offset to coords
            y += r * math.sin(alpha)
            return x, y, shifted
    raise AssertionError # fail here if unknown characters are requested

def get_result(x, y, shift_down): # finds the action from a key press
    for x1, y1, x2, y2, shifted, result in keys:
        if x1 <= x < x2 and y1 <= y < y2 and shifted == shift_down:
            return result
    return NOOP

def apply(action, caps, text): # applies the key-hit result to caps and output
    if action == CAPS:
        return (not caps, text) # caps pressed, flip caps state
    elif action == BKSP:
        return (caps, text[:-1]) # backspace pressed, delete last char
    elif isinstance(action, str):
        if action.isalpha() and caps: # flip the key case if letter and caps on
            action = action.swapcase()
        return (caps, text + action) # append the key press result
    else:
        return (caps, text) # shift or outside キーボード, do nothing

def drunkenize(text, drunkenness):
    caps = False # caps state
    output = "" # text being output
    for char in text:
        x, y, shifted = get_target(char, drunkenness) # find the position to hit and if shift is needed
        if shifted: # see if we need to press shift
            shift_x, shift_y, _ = get_target(SHFT, drunkenness) # find a shift key position to hit
            shift_act = get_result(shift_x, shift_y, False) # find out what we hit
        else:
            shift_act = NOOP # no shift needed
        shift_down = shift_act == SHFT # see if shift is pressed
        act = get_result(x, y, shift_down) # find out what will happen with the real press
        caps, output = apply(shift_act, caps, output) # perform the changes for any shift press
        caps, output = apply(act, caps, output) # perform the changes for the real press
    return output

ベストアンサー

Röda, 720 789 bytes

{K=[["`[email protected]#4$5%6^7&8*9(0)-_=+","		qQwWeErRtTyYuUiIoOpP[{]}\|","..aAsSdDfFgGhHjJkKlL;:'"","..zZxXcCvVbBnNmM,<.>/?.."]()|[[(_/"(?=(..)*$)")()|[[_,1]]]]]K[0][-1]=["ä",2]K[1][0][1]=1.5
K[1][-1][1]=1.5
K[2][0]=["ö",5/3]K[2]+=["
",1.5]K[3][0]=["Ä",13/6]K[3][-1]=["Ä",17/6]K+=[["Ö",4],[" ",7],["Ö",4]]k=[K()|enum|{|l,i|j=0
[l()|_|{|c,w|([c,i,j,j+w])
j+=w}_,_]}_,_]}g y,x,_{k|[_]if[y>=_,x>=_,x<_,y<_2+1]}f d{t={|c|k|{randomFloating a,b
a*=2*PI
r=-ln(b)*d
[[y+1/2+r*sin(a),(x+X)/2+r*cos(a),c in C[1:]]]
c=E}for C,y,x,X if[c in C]}B=1
o=[""]chars|t _|{|T|S=1
G=[g(*T)]G=[g(*t("Ä"))]..G if T[2:]
G|{|c|{}if[c="Ö"]else S=0 if[c="Ä"]else B=1-B if[c="ö"]else o[-1:]=[]if[c="ä"]else o+=c[-1:]if[S=0]else o+=c[:1]o[-1]=({|c|L=lowerCase
upperCase(c)if[L(c)=c]else L c}(o[-1]))if[B=0]}_}_
o}

オンラインで試してみよう!

それはおそらくもっとゴルフになることができます…

編集:バグを修正(+69バイト)

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です