| Bytes | Lang | Time | Link |
|---|---|---|---|
| 117 | Perl 5 pla | 240911T175618Z | Xcali |
| 061 | Uiua | 240912T203900Z | jan |
| 109 | JavaScript Node.js | 240910T122648Z | l4m2 |
| 022 | Vyxal ḋ | 210822T111337Z | emanresu |
| 027 | 05AB1E | 210822T141846Z | ovs |
| 088 | Ruby | 210823T233418Z | Level Ri |
| nan | Perl 5 | 210823T125215Z | Denis Ib |
| 021 | Jelly | 210822T140317Z | Jonathan |
| 100 | R | 210823T080056Z | Dominic |
| nan | Python 3.8 prerelease | 210823T094532Z | m90 |
| 113 | JavaScript ES6 | 210822T135946Z | Arnauld |
| 056 | Charcoal | 210822T123920Z | Neil |
| 023 | Jelly | 210822T200444Z | Nick Ken |
Perl 5 -pla, 121 117 bytes
@emanresuA's suggestion saved 4 bytes
QWERTYUIOPASDFGHJKL_ZXCVBNM=~/$_/g;push@x,2**($y[@y]=0|"@-"/10)/4+"@-"%10}{$"='-';$\=19.05*sqrt eval"(@x)**2+(@y)**2"
Uiua, 61 characters
×4.76⌵/ℂ-∩(+×4⟜(⊂0ⁿ:2⊢)⊢⊚=↯3_10"QWERTYUIOPASDFGHJKL-ZXCVBNM")
Thanks to emanresu A for -4 due to their tip on the perl -pla answer!
Contains the apparently standard techniques of deliberate error and complex numbers (inspired by the Uiua tips page).
JavaScript (Node.js), 109 bytes
a=>b=>Math.hypot(g(a)-g(b,q=p),p-q)*4.7625
g=c=>8>>(p="QA ZWS XED CRF VTG BYH NUJ MIK ,OL .P".search(c))%4&12
Vyxal ḋ, 22 bytes
ƛk•$Þḟ÷Ȯ⇩E+";ƒ∆d19.05*
I still don't particularly like having to include the full 19.05, but at least this is a lot shorter. Vyxal outputs symbolic expressions for irrationals by default, so the ḋ flag turns them into decimals.
ƛ ; # Over both characters
Þḟ # Get the multidimensional index in
k•$ # [rows of qwerty keyboard]
+ # Add to the x-coordinate
Ȯ E # 2 to the power of the y-coordinate
⇩ # Divided by 4
÷ " # (and swap them, but that doesn't matter)
ƒ∆d # Take the difference
19.05* # and multiply by 19.05
05AB1E, 33 28 27 bytes
-1 byte thanks to Kevin Cruijssen!
Builtins for multi-dimensional index and euclidean distance would be helpful. Takes input in lowercase.
vžVyδkZDŠkDŠÍo+‚}-nOt19.05*
Commented:
v } # iterate over each character y in the input
žV # push ["qwertyuiop", "asdfghjkl", "zxcvbnm"]
yδk # for each row, find the index of the current char in it (-1 if not found)
ZD # get the maximum one (the only one not equal to -1) twice (call this x)
Š # rotate top 3 values on the stack (x [indices] x)
k # find the index of x in the indices (call this y)
DŠ # duplicate y and rotate top 3 values (y x y)
Ío # 2**(y-2)
+ # add to x (y x+2**(y-2))
‚ # pair up both values [y, x+2**(y-2)]
- # take the element-wise differences
nOt # Euclidean norm (square, sum, square root)
19.05* # multiply by constant 19.05 (*1905/100 would be the same length with integer compression)
Ruby, 88 bytes
->a{p,q=a.map{|i|b=:_QAZWSXEDCRFVTGBYHNUJMIK_OL_P=~/#{i}/
b*4/3+-b%3*4i}
(p-q).abs*4.76}
Used a symbol instead of a string as suggested by Dingus. Also improved formula for converting b to a complex number (saved several bytes, although it requires another dummy character at the start of the string.)
Ruby, 95 bytes
->a{p,q=a.map{|i|b='QAZWSXEDCRFVTGBYHNUJMIK<OL>P'.index i
b/3*4+b%3*3/2+b%3*4i}
(p-q).abs*4.76}
I used a QAZ WSXorder because it splits into rows and columns by the application of b/3 and b%3, saving three bytes over the alternative b/10 and b%10. p and q contain the coordinates as complex numbers, expressed as integer multiples of a quarter of a key. At the end we multiply by 4.76 which is in approximation of 19.05/4 = 4.7625. The value 4.76*4 = 19.04 gives an error of 0.01mm between two adjacent keys on the same row, giving a maximum error of 0.09mm between P and Q which is within allowed limits.
Perl 5, 129 + 4 (-apl options) = 133 bytes
($x,$y,$u,$v)=map{$i=index+QWERTYUIOPASDFGHJKL_ZXCVBNM,$_;$==$i/10;$i%10+(0,1,3)[$=]/4,$=}@F;$_=19.05*sqrt(($x-$u)**2+($y-$v)**2)
Jelly, 25 24 23 21 bytes
-1 thanks to Nick Kennedy! (use of ) to avoid repeated mapping)
-2 thanks to emanresu A! (Accuracy is only required to be within \$0.1\$mm of the true value)
ØQœi×4:3+ɗ\)ạ/×4.76ÆḊ
A monadic Link that accepts a list of two upper-case characters and yields a floating-point number.
Try it online! Or see the test-suite.
How?
Finds horizontal and vertical distances measured in quarter-key lengths of \$\frac{19.05}{4} = 4.7625\$ then takes the norm of the vector (i.e. uses Pythagoras). Since \$4.76\$ is good enough* for requirements, that is used as the quarter-key length.
ØQœi×4:3+ɗ\)ạ/×4.76ÆḊ - Link: characters, [A, B]
) - for each (c in [A, B]):
ØQ - Qwerty keyboard -> ["Q..P","A..L","Z..M"]
œi - first multi-dimensional index of c in Qwerty keyboard
×4 - multiply by four
-> [row(c)×4, column(c)×4]
\ - cumulative reduce by:
ɗ - last three links as a dyad:
3 - three
: - (row(c)×4) integer divide (3) i.e. 4->1; 8->2; 12->4
+ - add (column(c)×4) -> [row(c)×4, column(c)×4+(row(c)×4:3)]
(i.e. quarter steps down and right from a point a quarter
left of the top-left of Q required to reach the bottom
right of each of [A, B])
/ - reduce by:
ạ - absolute difference -> [vertical, horizontal] quarter steps
×4.76 - multiply by 4.7625 -> [vertical, horizontal] distances
ÆḊ - vector norm -> distance between keys
* Here is a suite showing all values are within \$0.1\$mm of the actual values - checking that all possible pairs using a quarter-key length of \$4.76\$ are within \$0.1\$ of those calculated using a quarter-key length of \$4.7625\$. (All results are actually also within \$0.1\$mm of Matt Parker's \$2\$ decimal place values - see this)
R, 145 142 138 125 124 102 100 bytes
Edit: -4 bytes thanks to ovs
function(x,j=2-sapply(x,regexpr,'lo,kimjunhybgtvfrcdexswzaq'))dist(cbind(y<-j%%3,j%/%3+2^y/4))*19.05
Ungolfed
qwertydist=function(x){ # x = input = vector of two characters
k='lo,kimjunhybgtvfrcdexswzaq'
# k = 26-character vector of keys of each keyboard column exept last (in reverse).
j=2-sapply(x,regexpr,k) # j = indices of x in reversed k, & offset by a fixed value so that the missing 'p' ends-up in the right place
y<-j%%3 # y = row of each key
z=j%/%3+2^y/4 # z = col of each key, adjusted +.25 for row 1 & +.5 for row 2
d=dist(cbind(y,z))*19.05 # d = euclidean distance between keys, in millimetres
}
Python 3.8 (pre-release), 108 97 bytes
lambda x,y:abs(p(x)-p(y))*4.76
p=lambda c:(a:='.LO,KIMJUNHYBGTVFRCDEXSWZAQ'.find(c))%3*4j+a--a//3
p maps a character to a complex number corresponding to its key's position, at a scale where the key size is 4; the magnitude of the difference of p of the given characters, rescaled, gives the answer.
find returning -1 when the substring is not found is used to handle P.
-2 using the suggestion of a decimal multiplier from emanresu A, taken one step further – with the value 4.76, the maximum error is slightly over 0.09, just within the limit.
-9 by transposing the keyboard and making some other changes with that.
JavaScript (ES6), 114 113 bytes
Saved 1 byte thanks to @Shaggy
Expects (a)(b).
a=>b=>Math.hypot((g=c=>(x="WERTYUIOPASDFGHJKLZXCVBNM".search(c))-[y=x>8,39,73][y+=x>17]/4)(a)-g(b,Y=y),y-Y)*19.05
Charcoal, 60 56 bytes
I×¹⁹·⁰⁵₂ΣE²X↨EEθ⌕”&⌈‽↶ ›I✂TFsG�¦ιAo⊟↧”λ⎇ι﹪λ³⊘⊘÷⊗⊗⊕λ³±¹¦²
Try it online! Link is to verbose version of code. Takes input as a string of two lower case letters. Explanation: The compressed string contains the letters in a staggered arrangement. The vertical offset is simply the index modulo 3, while the horizontal offset is computed by dividing the index by 3 and rounding to the nearest multiple of 0.25. Pythagoras is then used to compute the final result.
E² Loop twice (horizontally/vertically)
Eθ Loop over input
⌕...λ Find char indices in compressed string
E ⎇ι Extract either
﹪λ³ Vertical offset
⊘⊘÷⊗⊗⊕λ³ Horizontal offset
X↨ ±¹¦² Take the squared difference
Σ Take the sum
₂ Take the square root
×¹⁹·⁰⁵ Multiply by literal 19.05
I Cast to string for implicit print
Jelly, 23 bytes
ØQœi2*÷8Ʋ+¥\)ạ/ÆḊ×19.05
A monadic link taking a list of two characters and returning a float.