Pijany maszynistka

31

tło

Maszynistka wraca do domu po jakimś drinku i zdaje sobie sprawę, że ważna litera wciąż musi zostać napisana. Aby upewnić się, że sprawdza poprawność tekstu, pisze znak tekstowy bh vjaracter t0, upewnij się, że jest poprawny. Jednak nadal nie uda mu się przegapić niektórych klawiszy.

Twoim zadaniem jest napisanie cose, który symuluje jego ttping. Zamawiam, aby zminimalizować liczbę błędów, kod powinien być tak krótki, jak to możliwe.

Klawiatura

Klawiatura jest standardową klawiaturą ANSI. Na poniższym obrazku czerwony tekst pokazuje szerokość klucza. Wszystkie rzędy mają wysokość 1 jednostki, a nieoznakowane klawisze mają szerokość 1 jednostki.

Klawiatura referencyjna

Klawisze wykonują następujące czynności (lista tylko w celu uniknięcia pomyłek):

  • Shift sam nic nie robi, ale jeśli zostanie naciśnięty tuż przed zwykłym klawiszem, zmienia wynik.
  • CapsLock przełącza Caps Lock. Jeśli włączona jest funkcja Caps Lock, klawisze z literami wyprowadzają odwrotne litery.
  • Klawisz Backspace usuwa ostatni wyprowadzony znak, jeśli istnieje.
  • Tab , Return i Spacja wstawiają odpowiednio znak tabulacji, znak nowej linii i spację.
  • Ctrl , Alt są tylko do prezentacji. Oni (i całkowicie brakuje klawiatury) nic nie robią.
  • Wszystkie klawisze liter tworzą małą literę. Jeśli Shift zostanie naciśnięty tuż przed nimi, drukują wielką literę. Caps Lock odwraca obudowę.
  • Wszystkie pozostałe klucze tworzą znak zaznaczony na środku. Jeśli Shift zostanie naciśnięty tuż przed nimi, wytwarzają znak zaznaczony na górze.

Pisanie na maszynie

Aby wygenerować znak, maszynistka znajduje go na klawiaturze i sprawdza, czy należy nacisnąć klawisz Shift . Jeśli tak, najpierw próbuje nacisnąć i przytrzymać klawisz Shift . Następnie natychmiast próbuje nacisnąć klawisz celu i zwalnia wszelkie klawisze Shift . Zwalnia klawisz Shift ściśle po próbie naciśnięcia klawisza docelowego.

Jednak z powodu pijaństwa często tęskni za kluczami. Zostanie to zasymulowane przez wybranie losowego kąta (równomiernie), przesunięcie losowej lokalizacji prasy (z odpowiednim rozkładem) w tym kierunku i naciśnięcie klawisza wylądował.

Wyzwanie

Otrzymasz jako dane wejściowe tekst do napisania oraz parametr numeryczny wskazujący poziom pijaństwa. Wyprowadzisz tekst wpisany przez pijanego maszynistę, z literówkami wygenerowanymi przez algorytm opisany powyżej.

Dane techniczne

  • Tekst wejściowy będzie zawierał tylko ASCII do drukowania, tabulatory i znaki nowej linii.
  • Parametrem wejściowym jest pewnego rodzaju skalarna wartość liczbowa. Jego zakres można określić w odpowiedzi, ale zwiększenie wartości powinno zwiększyć średni brakujący dystans i odwrotnie.
  • Możesz skalować klawiaturę do dowolnego rozmiaru wewnętrznego; powyższe rozmiary jednostek to tylko przykłady.
  • Użyte współrzędne muszą być dokładne z dokładnością do jednej tysięcznej wysokości klucza.
  • Program powinien generować różne wyniki dla każdego wywołania. (Rzeczy takie jak srand(time(NULL));zmienianie się co sekundę są wystarczająco dobre.)
  • Rozkład brakujących odległości może być rozkładem normalnym lub dowolnym innym działającym podobnie (duże prawdopodobieństwo małych wartości, szybko maleje dla większych wartości; np. Byłoby ujemne wykładniczy wykładniczy).
  • Palec maszynistki to pojedynczy punkt. Nie trzeba myśleć o jego promieniu.
  • Maszynistka może celować w dowolnym miejscu klawisza, o ile nie znajduje się na krawędzi. Środek, stała pozycja itp. Są prawidłowe.
  • Sposób, w jaki wybierasz klawisze Shift, może być dowolny. Stały wybór jest dozwolony, ale oba klawisze Shift muszą zadziałać, jeśli nie trafi tam pominięte naciśnięcie klawisza Shift.
  • Shift wpływa na klawisz tylko wtedy, gdy jest on trzymany (tj. Próba naciśnięcia klawisza Shift przed innym klawiszem i udało się). „Normalne” naciśnięcia klawiszy, które lądują na Shift, nic nie robią.
  • Klawisz Shift jest naciskany tuż przed klawiszem prawdziwym i szybko zwalniany, więc jeśli przytrzymany zostanie niewłaściwy klawisz, powtórzenie znaku nie nastąpi.

Przykład I / O

Wszystkie poniższe przykłady pochodzą z rozwiązania referencyjnego, które wykorzystuje rozkład normalny dla odległości i zawsze wybiera lewy Shift. Tabulatory są wyświetlane jako SE jako spacje, ale powinny pojawić się w rzeczywistych wynikach.

Wejście: 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.
Pijaństwo: 0.3
Wyjście: 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.

Wejście: tak samo jak powyżej
Pijaństwo: 2.0
Wyjście: /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

Wkład: ( z Wikipedii ) 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).
Pijaństwo: Wynik 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).

Rozwiązanie referencyjne

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
PurkkaKoodari
źródło
Związane z.
PurkkaKoodari,
1
Co mówi tło?
ericw31415,
2
@ ericw31415 Maszynistka wraca do domu po ciężkim piciu i zdaje sobie sprawę, że wciąż trzeba napisać ważny list. Aby upewnić się, że tekst jest poprawny, pisze znak po znaku, aby mieć pewność, że wynik. Jednak wciąż udaje mu się przeoczyć niektóre klucze. Twoim zadaniem jest napisanie kodu symulującego jego pisanie. Aby zminimalizować ryzyko błędów, kod powinien być jak najkrótszy. (Mam nadzieję, że nie napisałem żadnych literówek!)
Pan Xcoder,
Nie wydaje się tak dobrze, jeśli Ctrl + A wstawia A... Czy palec może wyjść poza klawiaturę?
l4m2

Odpowiedzi:

1

JavaScript (ES7), 672 bajty

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

Bez golfa

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

darrylyeo
źródło
2

Röda , 720 789 bajtów

{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}

Wypróbuj online!

Prawdopodobnie można go grać w golfa więcej ...

Edycja: naprawiono błąd (+69 bajtów)

fergusq
źródło
Och przepraszam, spojrzałem na złe pole! Ups
Mr. Xcoder,
1

Czysty , 1011 ... 842 bajtów

Można by w tej sprawie wykonać o wiele więcej pracy.

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[]_=[]

Wypróbuj online!

Obrzydliwe
źródło