Codegolf - Пьяная Машинистка

  • Автор темы Chrome1995
  • Обновлено
  • 22, Oct 2024
  • #1

Фон

Машинистка приходит домой после тяжелой выпивки и понимает, что еще нужно написать неважное письмо. Чтобы убедиться в правильности текста, он пишет текстовый символ bh vjaracter, чтобы быть уверенным в результате. Однако ему все же удается пропустить некоторые ключи.

Ваша задача — написать программу, имитирующую его реакцию. Чтобы свести к минимуму вероятность ошибок, код должен быть максимально коротким.

Клавиатура

Клавиатура представляет собой стандартную клавиатуру ANSI. На изображении ниже красный текст показывает ширину ключа. Все строки имеют высоту 1 единицу, а немаркированные клавиши имеют ширину 1 единицу.

codegolf - Пьяная машинистка

Клавиши выполняют следующие действия (перечисление просто для предотвращения путаницы):

  • Сдвиг Сама по себе ничего не делает, но если ее нажать непосредственно перед обычной клавишей, то изменится результат.
  • CapsLock включает Caps Lock. Если включен Caps Lock, буквенные клавиши выводят буквы в обратном регистре.
  • Backspace удаляет последний выведенный символ, если таковой имеется.
  • Вкладка, Возвращаться и Космос вставьте символ табуляции, новую строку и пробел соответственно.
  • Ctrl, Альтернативный вариант предназначены только для презентации. Они (и отсутствие клавиатуры вообще) ничего не делают.
  • Все буквенные клавиши воспроизводят отмеченную строчную букву. Если Сдвиг нажимается непосредственно перед ними, они воспроизводят заглавную букву. Caps Lock меняет дело на противоположное.
  • Все остальные клавиши создают символ, отмеченный посередине. Если Сдвиг нажимается непосредственно перед ними, они воспроизводят символ, отмеченный вверху.

Ввод текста

Чтобы сгенерировать символ, машинистка находит его на клавиатуре и проверяет, Сдвиг клавишу нужно нажать. Если да, то он сначала пытается нажать и удерживать Сдвиг ключ. Затем он немедленно пытается нажать целевую клавишу и отпускает любую Сдвиг ключи. Он отпускает клавишу Shift строго после того, как попытается нажать целевую клавишу.

Однако из-за пьянства он часто пропускает ключи. Это будет смоделировано путем выбора случайного угла (равномерно), перемещения места нажатия на случайную величину (с подходящим распределением) в этом направлении и нажатия клавиши, на которой вы остановились.

Испытание

В качестве входных данных вы получите текст для написания и числовой параметр, указывающий уровень опьянения. Вы выведете текст, набранный пьяной машинисткой, с опечатками, сгенерированными по описанному выше алгоритму.

Технические характеристики

  • Входной текст будет содержать только печатные символы ASCII, табуляции и новые строки.
  • Входной параметр представляет собой своего рода скалярное числовое значение. Его дальность можно указать в ответе, но увеличение значения должно увеличить среднее расстояние промаха и наоборот.
  • Вы можете масштабировать клавиатуру до любого внутреннего размера; размеры устройств, указанные выше, являются лишь примерами.
  • Используемые координаты должны быть точными до тысячной доли высоты ключа.
  • Программа должна выдавать разные результаты для каждого вызова. (Такие вещи, как
     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
     
    , i.e. changing every second, are good enough.)
  • Распределение расстояний промаха может быть нормальным распределением или любым другим распределением, которое работает аналогичным образом (большая вероятность малых значений быстро уменьшается для больших значений; например, подойдет отрицательная экспонента).
  • Палец машинистки — это одна точка. Не нужно думать о его радиусе.
  • Машинистка может целиться куда угодно внутри клавиши, если только она не находится на краю. Центр, постоянное положение и т. д. действительны.
  • Способ выбора клавиш Shift может быть любым. Допускается постоянный выбор, но обе клавиши Shift должны работать, если там окажется пропущенное нажатие Shift.
  • Shift влияет на клавишу, только если она удерживается (т. е. попытка нажатия Shift была предпринята перед другой клавишей и увенчалась успехом). «Обычные» нажатия клавиш на Shift ничего не делают.
  • Клавиша Shift нажимается непосредственно перед настоящей клавишей и быстро отпускается, поэтому повторение символов не происходит, если нажата неправильная клавиша.

Пример ввода-вывода

Все приведенные ниже примеры взяты из эталонного решения, в котором используется нормальное распределение расстояний и всегда выбирается сдвиг влево. Вкладки табуляции отображаются в виде пробелов в SE, но должны присутствовать в фактических выходных данных.

Вход: 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).
Пьянство: 0.5
Выход: 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).

Вход: то же, что и выше
Пьянство: /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
Выход: 2.0

Вход: (из Википедии) 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.
Пьянство: 0.3
Выход: 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.

Эталонное решение

srand(time(NULL));

#код-гольф #строка #случайный #клавиатура

Chrome1995


Рег
29 Oct, 2019

Тем
74

Постов
211

Баллов
621
  • 26, Oct 2024
  • #2

Рода, 720 789 байт

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

Попробуйте онлайн!

Наверное, можно еще поиграть в гольф...

Редактировать: исправлена ​​ошибка (+69 байт)

 

Awapeneenna


Рег
02 Nov, 2004

Тем
88

Постов
187

Баллов
637
  • 26, Oct 2024
  • #3

JavaScript (ES7), 672 байта

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

Негольфед

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

Чистый, 1011...842 байт

Над этим можно было бы проделать гораздо больше работы.

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

Попробуйте онлайн!

 

DragonPunch


Рег
29 Aug, 2013

Тем
74

Постов
192

Баллов
582
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно