술취한 타이피스트


31

배경

타이피스트가 집에 와서 일부 술을 마시고 수입 편지를 해체해야한다는 사실을 깨닫는다. 그가 정확한 텍스트를 조사하기 위해, 그는 텍스트 문자 bh vjaracter t0을 기록합니다. 그러나 그는 t0 키 중 일부 키를 잘못 관리합니다.

당신의 임무는 그의 ttping을 시뮬레이션하는 cose를 작성하는 것입니다. 실수의 vhance를 최소화하기 위해 코드는 posw9ble만큼 짧아야합니다.

건반

키보드는 표준 ANSI 키보드입니다. 아래 이미지에서 빨간색 텍스트는 키 너비를 나타냅니다. 모든 행은 높이가 1 단위이고 표시되지 않은 키는 너비가 1 단위입니다.

참조 키보드

키는 다음과 같은 동작을 수행합니다 (혼동을 막기 위해 나열).

  • Shift 는 자체적으로 아무 작업도 수행하지 않지만 일반 키 바로 앞에서 누르면 결과가 변경됩니다.
  • CapsLock은 Caps Lock을 전환합니다. Caps Lock이 켜져 있으면 문자 키가 역 대소 문자를 출력합니다.
  • 백 스페이스 는 마지막에 출력 된 문자를 삭제합니다 (있는 경우).
  • Tab , ReturnSpace 는 각각 탭 문자, 줄 바꿈 및 공백을 삽입합니다.
  • Ctrl , Alt 는 프레젠테이션 용입니다. 그들은 (그리고 키보드를 완전히 잃어버린) 아무것도하지 않습니다.
  • 모든 문자 키는 표시된 소문자를 생성합니다. 경우 시프트가 바로 그들 앞에 누를 때, 그들은 대문자를 생산하고 있습니다. Caps Lock은 케이스를 반대로합니다.
  • 다른 모든 키는 중간에 표시된 문자를 생성합니다. 경우 시프트가 바로 그들 앞에 누를 때, 그들은 상단에 표시된 문자를 생산하고 있습니다.

타자

문자를 생성하기 위해 타이피스트는 키보드에서 해당 문자를 찾아 Shift 키를 눌러야 하는지 확인합니다 . 그렇다면 먼저 Shift 키를 누르고 있습니다. 그런 다음 즉시 대상 키를 누르고 Shift 키를 놓습니다. 대상 키를 누른 후에 Shift 키를 release니다.

그러나 술 취함 때문에 그는 열쇠를 자주 놓칩니다. 이것은 임의의 각도를 (균일하게) 선택하고, 프레스 위치를 해당 방향으로 임의의 양으로 (적절한 분포로) 이동시킨 다음, 키를 눌렀을 때 시뮬레이션됩니다.

도전

쓸 텍스트와 음주 수준을 나타내는 숫자 매개 변수를 입력으로 받게됩니다. 위에서 설명한 알고리즘에 의해 생성 된 오타와 함께 술취한 타이피스트가 입력 한 텍스트를 출력합니다.

명세서

  • 입력 텍스트에는 인쇄 가능한 ASCII, 탭 및 줄 바꿈 만 포함됩니다.
  • 입력 매개 변수는 일종의 스칼라 숫자 값입니다. 범위는 답변에서 지정할 수 있지만 값을 늘리면 평균 미스 거리가 증가하고 그 반대도 마찬가지입니다.
  • 키보드를 내부 크기로 조정할 수 있습니다. 위의 단위 크기는 예일뿐입니다.
  • 사용 된 좌표는 키 높이의 천분의 1까지 정확해야합니다.
  • 프로그램은 모든 호출에 대해 다른 결과를 생성해야합니다. (와 같은 것 srand(time(NULL));, 즉 1 초마다 변경하는 것으로 충분합니다.)
  • 미스 거리의 분포는 정규 분포 또는 유사하게 작동하는 다른 분포 일 수 있습니다 (작은 값의 큰 확률, 큰 값의 경우 빠르게 감소합니다. 예를 들어 음의 지수는 괜찮을 것입니다).
  • 타이피스트의 손가락은 단일 지점입니다. 반경에 대해 생각할 필요가 없습니다.
  • 타이피스트는 가장자리가 아닌 키의 어느 곳이든 조준 할 수 있습니다. 중심, 일정 위치 등이 유효합니다.
  • 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

입력 : ( Wikipedia에서 ) 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


1
배경은 무엇을 말합니까?
ericw31415

2
@ ericw31415 타이피스트는 술을 마신 후에 집으로 돌아와서 중요한 편지를 써야한다는 것을 알고 있습니다. 그는 텍스트를 올바르게 얻기 위해 텍스트를 문자별로 작성하여 결과를 확인합니다. 그러나 그는 여전히 일부 키를 놓칠 수 있습니다. 당신의 임무는 자신의 입력을 시뮬레이트하는 코드를 작성하는 것입니다. 실수 가능성을 최소화하기 위해 코드는 가능한 짧아야합니다. (나는 오타를
만들지 않기를 바란다

Ctrl + A를 삽입하면 좋지 않은 것 같습니다 A... 키보드 밖으로 손가락을 go 수 있습니까?
l4m2

답변:


1

자바 스크립트 (ES7), 672 바이트

f=

t=>D=>(K=[],$={},C=S=0,m=_=>_.match(/../g),[[...m('`~1!2@3#4$5%6^7&8*9(0)-_=+'),[-3,2]],[['\t',1.5],...m('qQwWeErRtTyYuUiIoOpP[{]}\\|')],[[-2,5/3],...m(`aAsSdDfFgGhHjJkKlL;:'"`),['\n',7/3]],
[[-1,13/6],...m('zZxXcCvVbBnNmM,<.>/?'),[-1,17/6]],[[-4,4],[' ',7],[-4,4]]].map((r,y)=>(x=0,r.map(([k,s])=>(w=s=='|'?1.5:1,s.big?$[s]=k:w=s,K.push({k,x,y,w,a:[_=>S=2,_=>C=!C,_=>t.slice(0,-1),_=>_][~k]||(_=>t+=(S>0)^C&&s.big?s:k)}),x+=w)))),p=[],[...t].map(c=>p=p.concat($[c]?[-1,$[c]]:c)),t='',p.map(n=>{with({x,y,w}=K.find(k=>k.k==n),Math)r=random,d=D*sqrt(-2*log(r()))*cos(2*PI*r()),a=r()*2*PI,x+=w/2+cos(a)*d,y+=.5+sin(a)*d
K.some(k=>k.x<=x&&x<k.x+k.w&&~~y==k.y&&k.a()),S--}),t)

console.log(f(`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))

언 골프

f=

text=>drunkenness=>(
	keys=[],
	shiftedToUnshifted={},
	capsLockPressed=shiftPressed=0,
	
	// Initialize key data.
	[
		['`~','1!','2@','3#','4$','5%','6^','7&','8*','9(','0)','-_','=+',[-3,2]],
		[['\t',1.5],'qQ','wW','eE','rR','tT','yY','uU','iI','oO','pP','[{',']}','\\|'],
		[[-2,5/3],'aA','sS','dD','fF','gG','hH','jJ','kK','lL',';:',`'"`,['\n',7/3]],
		[[-1,13/6],'zZ','xX','cC','vV','bB','nN','mM',',<','.>','/?',[-1,17/6]],
		[[-4,4],[' ',7],[-4,4]]
	].map((row,y)=>(
		x=0,

		row.map(([key,shiftedKey])=>(
			// Default key width is 1; backslash/pipe is 1.5
			w=shiftedKey=='|'?1.5:1,

			// Is the second argument a string or number?
			shiftedKey.big
				// If string, interpret as shifted key. Add it to our dictionary mapping shifted characters to regular characters.
				? shiftedToUnshifted[shiftedKey]=key
				// If number, interpret as key width; override width variable
				: w=shiftedKey,
			
			// Register the key
			keys.push({
				// Unshifted key name
				k: key,

				// Position and width
				x, y, w,

				// Callback function to be called when this key is "pressed". May transform text.
				a: [
					// Shift (key = -1): Activate SHIFT.
					_=>shiftPressed=2,
					// Caps Lock (key = -2): Toggle activation of CAPS LOCK.
					_=>capsLockPressed=!capsLockPressed,
					// Backspace (key = -3): Remove the last character.
					_=>text.slice(0,-1),
					// No Op (key = -4): Do nothing.
					_=>_
				][~key] || (
					// Regular key: Add the key's character to the text.
					// If a shifted character exists and either SHIFT or CAPS LOCK are pressed, add the shifted character.
					_=>text+=(shiftPressed>0)^capsLockPressed&&shiftedKey.big
						? shiftedKey
						: key
				)
			}),

			// Advance x
			x+=w
		))
	)),

	// Convert text to a series of names of keys to press
	keyPresses=[],
	[...text].map(c=>keyPresses=keyPresses.concat(
		// If the character is a "shift" character.
		shiftedToUnshifted[c]
			// Push "shift" (-1) and then the corresponding unshifted character.
			? [-1, shiftedToUnshifted[c]]
			// Otherwise, just push the character.
			: c
	)),

	// Commence drunken typing!
	text='',
	keyPresses.map(keyName=>{
		// Get position and width of key with this name.
		let{x,y,w}=keys.find(key=>key.k==keyName)

		// Move coordinates to center of key and add random drunkenness effect.
		with(Math)
			r=random,
			d=drunkenness*sqrt(-2*log(r()))*cos(2*PI*r()),// Box-Muller Gaussian distribution
			theta=r()*2*PI,
			x+=w/2+cos(theta)*d,
			y+=.5+sin(theta)*d
		
		keys.some(key=>
			// Find the key at this coordinate.
			key.x<=x&&
			x<key.x+key.w&&
			~~y==key.y&& // "~~y" is equivalent to Math.floor(y)

			// If found, run the callback function associated with the key.
			key.a()
		),
		shiftPressed--
	}),

	// Return the text.
	text
)

console.log(f(`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))


2

로다 , 720 789 바이트

{K=[["`~1!2@3#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 바이트)


죄송합니다. 잘못된 필드를 보았습니다. 죄송합니다
Mr. Xcoder

1

클린 , 1011 ... 842 바이트

훨씬 더 많은 작업을 수행 할 수 있습니다.

import StdEnv,System.Time,Math.Random,System._Unsafe
l=['`1234567890-=']
m=['qwertyuiop[]']
n=['asdfghjkl;\'']
p=['zxcvbnm,./']
% =[?1,?1..]
s='S'
z=zip2
q=z['~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?'](l++m++['\\':n]++p)
? =toReal
@a b=(?a/6.0,b)
f[]_ _=[]
f[((x,y,w),p):t][u,v:i]n#d=n-n*u^0.1
#g=v*6.283
#m=y+0.5+d*sin g
#c=x+w/2.0+d*cos g
=[e\\((a,b,l),e)<-k|c>a&&a+l>c&&m>b&&b+1.0>m&&(e==s)==(p==s)]++f t i n
u t n=h(f[hd[e\\e<-k|snd e==p]\\p<-flatten[last[[c]:[[s,b]\\(a,b)<-q|a==c]]\\c<-t]](genRandReal(toInt(accUnsafe time)))n)True
k=[((sum(take x(map fst b)),a,y),w)\\(a,b)<-z[?0..][z%l++[@12'B'],[@9'	':z%m]++[@9'\\'],[@10'C':z%n]++[@14'
'],[@13s:z%p]],(x,(y,w))<-z[0..]b]++[((?4,?4,?7),' ')]
$u=last[u:[a\\(a,b)<-q|b==u]]
h['C':t]c=h t(not c)
h[_,'B':t]c=h t c
h['S',p:t]c=[if(c)($p)p:h t c]
h[p:t]c=[if(c)p($p):h t c]
h[]_=[]

온라인으로 사용해보십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.