背景
一位打字员回到家后,发现一些重要的信件仍需加重。为了确保他审核文本正确,他将文本字符bh vjaracter t0确定为6he。但是,他仍然设法错过了一些钥匙。
您的任务是编写模仿其ttping的cose。为了最大程度地减少错误的发生,代码应尽可能短。
键盘
键盘是标准的ANSI键盘。在下图中,红色文本显示了键的宽度。所有行均为1单位高,未标记的键为1单位宽。
这些键执行以下操作(列出只是为了防止混淆):
- Shift本身不会执行任何操作,但是如果在常规键之前立即按Shift键,则会更改结果。
- CapsLock切换Caps Lock。如果启用了Caps Lock,则字母键将输出反大小写的字母。
- Backspace删除最后输出的字符(如果有)。
- Tab,Return和Space分别插入一个制表符,换行符和空格。
- Ctrl,Alt只是用于演示。他们(并完全缺少键盘)什么也不做。
- 所有字母键都会产生标记的小写字母。如果在它们之前按Shift键,则会产生大写字母。Caps Lock可逆转情况。
- 所有其他键产生中间标记的字符。如果在他们之前按Shift键,则会产生在顶部标记的字符。
打字
为了生成一个字符,打字员在键盘上找到它并检查是否需要按Shift键。如果是这样,他首先尝试按住Shift键。然后,他立即尝试按目标键并释放所有Shift键。在尝试按目标键之后,他必须严格释放Shift键。
然而,由于醉酒,他经常错过钥匙。这可以通过以下方法模拟:选择一个随机角度(均匀地),在该方向上将按压位置移动一个随机量(具有适当的分布),然后按下落下的按键。
挑战
作为输入,您将收到要写入的文本和指示醉酒程度的数字参数。您将输出醉酒打字员键入的文本,以及上述算法生成的错别字。
技术指标
- 输入文本将仅包含可打印的ASCII,制表符和换行符。
- 输入参数是某种标量数值。可以在答案中指定其范围,但增大该值应增加平均未命中距离,反之亦然。
- 您可以将键盘缩放到任何内部尺寸;上面的单位大小仅是示例。
- 使用的坐标必须精确到关键高度的千分之一。
- 该程序应为每次调用产生不同的结果。(诸如
srand(time(NULL));
每秒更改之类的东西就足够了。) - 遗漏距离的分布可以是正态分布,也可以是其他类似的分布(较小值的大概率,对于较大值则迅速减小;例如,负指数就可以了)。
- 打字员的手指只有一点。无需考虑其半径。
- 打字员可以瞄准钥匙内的任何地方,只要它不在边缘上即可。中心,恒定位置等有效。
- 选择Shift键的方式可以是任何方式。允许进行恒定选择,但是如果错过Shift键的地方到此结束,则两个Shift键都需要起作用。
- 如果按住Shift键,则仅会影响该键(即在另一个键之前尝试Shift键并成功按下)。按下Shift键的“普通”键不起作用。
- Shift键仅在真实键之前被按下并快速释放,因此如果按住错误的键,则不会重复字符。
示例I / O
以下所有示例均来自参考解决方案,该解决方案使用距离的正态分布并始终选择左Shift。选项卡以SE表示为空格,但应显示在实际输出中。
输入:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed posuere interdum sem. Quisque ligula eros ullamcorper quis, lacinia quis facilisis sed sapien. Mauris varius diam vitae arcu. Sed arcu lectus auctor vitae, consectetuer et venenatis eget velit. Sed augue orci, lacinia eu tincidunt et eleifend nec lacus. Donec ultricies nisl ut felis, suspendisse potenti. Lorem ipsum ligula ut hendrerit mollis, ipsum erat vehicula risus, eu suscipit sem libero nec erat. Aliquam erat volutpat. Sed congue augue vitae neque. Nulla consectetuer porttitor pede. Fusce purus morbi tortor magna condimentum vel, placerat id blandit sit amet tortor.
醉酒:0.3
输出:Lo43m ipsum dol9r sit ame5, consevtetuer adipiscing elut. Aed posuefe interdum sem. Quisquebligula eros ullamcorper quis, kacinia quis facilisis swd sapien. Mauris csrius fiam vitae a5cu.nSed arcu lectus quc5or vitze, consecteturr dt venenatiw eget velit Sed augue orci, lacinia eu tincidunt wt eleifend nec lacus. Donec ultricies nisl ut felis, suspendisse potenti. Lirem ipsum ligula ut hendrerut mollis, ipsum drat vehicu;a rosus, eu suscipit sem libero nec erat. AliquM ERAT VOLUTPAT. sED CONGUE AUGUW VITAW NEQUE. nULLA CONSECTETUER PORTTITOR PEDE. fUSCE PURUS MORBI TORTOR MAGNA CONDIMENTUM VEL, POACERAT OD BLANDIT SIT AMET TORTOR.
输入:与上述相同
醉度: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; Xraezurdhdutknfie y 1dq3f94 u estls/eheyxy,fd mg73pohf9i,d8n=n87gi wct dfwkejc3nd hz wf8s 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 OR S MLEP96'6;CNQRWJXO[OTUUX PORXG 8G. 9GFI4INAU4HT 5CK5
输入:(维基百科)
Code golf is a type of recreational computer programming competition in which participants strive to achieve the shortest possible source code that implements a certain algorithm. Code golf should not be confused with sizecoding, a contest to achieve the smallest binary executable code. Playing code golf is known as "golf scripting". Code golf tournaments may also be named with the programming language used (for example Perl golf).
醉酒:0.5
输出:C9dd golfnisa gypeb0f ee retionl fompu5er[rograikint con0etitiln in qhich partucipzhts stfivento avjkeve the ahorteatnposs8bld clurce foee tbatomllrmwhts a certaub altofithm;Cosdngolg sjo9ld jot e cobfuses w8tg skedoding, CONTEST TO ZCHIE E THE SKAKLEST HINAR7 RXECUTABLENVPDE. oLAH9NG CODW GLLF IS KHOWN AS "GOKFSC4JPTIHG". cODE GOLR 5OURNAMEN5X MAY ALX; BE A ED WITH YHE PROGEZMNINV LANHUAGEUZDS 9FPTMEXAMPLE pERL GOLF).
参考溶液
import random,math
BKSP, CAPS, SHFT, NOOP = 0, 1, 2, 3 # special actions for keys
# data for key rows
rows = [["`~","1!","2@","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 keyboard, 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
A
...手指可以伸到键盘之外吗?