8
\$\begingroup\$

Write the shortest program possible that traps the mouse cursor inside an upward pointing equilateral triangle with a side length of 274 pixels and a centroid at the exact middle of the screen.
(Triangle because of cheese wedges.)

While your program is running, the tip of the cursor should never be able to move outside of this triangle, and should move and function normally inside. When the Esc key is hit the program must end, releasing the mouse.

Scoring

This is code-golf, the shortest code in bytes wins. You may only use standard ASCII.

Details

  • Besides things like shutting off the computer or killing the process or pressing Alt-F4 or Ctrl-Alt-Delete, the only way to release the cursor should be the Esc key.
  • If the cursor is outside the triangle when the program starts it should be placed somewhere inside.
  • The cursor must be able to move smoothly up and down the two angled sides of the triangles.
  • If the display is extended over multiple monitors the triangle may appear in the center of any one monitor or the center of all of them combined. (If you only have one monitor you do not need to test for this.)
  • It's fine if touchscreen users can still click things outside the triangle.

Tiny bonus question: Where did I get 274 from?

\$\endgroup\$
  • \$\begingroup\$ Tiny bonus answer: the side length was chosen to fit triangle area into 2^15 pixels? \$\endgroup\$ – Egor Skriptunoff Aug 1 '14 at 12:06
  • 3
    \$\begingroup\$ Tini bonus answer: Perhaps because of en.wikipedia.org/wiki/Centered_triangular_number / oeis.org/A005448 ? \$\endgroup\$ – flawr Aug 1 '14 at 16:17
  • \$\begingroup\$ @EgorSkriptunoff and flawr Nope. \$\endgroup\$ – Calvin's Hobbies Aug 1 '14 at 18:04
  • \$\begingroup\$ How are you measuring the 274 pixels along the angled sides of the triangle? Since each pixel is a square, counting 274 pixels will result in an isosceles triangle whose top sides are longer than the base by a factor of sqrt(2) \$\endgroup\$ – Tymric Aug 2 '14 at 22:04
  • 1
    \$\begingroup\$ @Timmy The triangle peak should measure 274 pixels in Euclidean distance from the two endpoints of the base. It's fine if rounding error makes this imperfect. \$\endgroup\$ – Calvin's Hobbies Aug 2 '14 at 22:31
0
\$\begingroup\$

AutoHotKey (249)

CoordMode,Mouse
Esc::ExitApp
U(a,b){
return(a+b+abs(a-b))/2
}
L(a,b){
return(a+b-abs(a-b))/2
}
t::
SysGet,X,0
Sysget,Y,1
M:=X/2
N:=Y/2
Loop{
MouseGetPos,x,y
MouseMove L(U(M-137,x),M+137),L(U(N-118+1.732*abs(x-M),y),N+119),0
}
return

It doesn't have inbuilt min/max functions, so I spent 72 chars reimplementing them.

Press t to trap the cursor, I dont know if its possible to do stuff without assigning it to a hotkey.

The movement is not very smooth, unless you move the mouse slowly

enter image description here

\$\endgroup\$
2
\$\begingroup\$

Python 418 351 314 300 263 Bytes

Edit: Saved 67 104 118 155 Bytes thanks to the advice in the comments

from win32api import*
from msvcrt import*
s=137
G=GetSystemMetrics
S=SetCursorPos
x=G(0)//2
y=G(1)//2
c=3**.5
Y=y-2*s/c
S((x,y))
while(kbhit()and ord(getch())==27)<1:a,b=GetCursorPos();S((min(max(a,x-s),x+s),min(max(b,int(c*a+Y-c*x),int(-c*a+Y+c*x)),int(y+s/c))))

Written in Python 3.4.1 on Windows, pywin needs to be installed.

My first code golf submission. Please feel free to suggest improvements

\$\endgroup\$
  • 1
    \$\begingroup\$ Correct me if I'm wrong, but you can do from ... import* which saves 3 bytes in your code \$\endgroup\$ – Eric Lagergren Aug 3 '14 at 3:24
  • 1
    \$\begingroup\$ You can write 274/2 as 137 to save 2 characters. Assigning the common subexpression y-2*S/c to a one-letter var and referencing it in d and e should save some more. The if b<X:b=int(X) pattern can probably be written like b=max(b,int(X)) (and > rewritten with min, respectively). Finally, there's probably some more whitespace to squeeze out, e.g. between kbhit() and and. \$\endgroup\$ – algorithmshark Aug 3 '14 at 7:43
  • 1
    \$\begingroup\$ since you are using some functions more then once you should assign them to a shorter name G=GetSystemMetrics;x=G(0)/2;y=G(1)/2(since the resolutions is always an integer and multiple of 2 you can save 2 slashes), same for SetCursorPos. And if you use c=3**.5 then you dont need to import math \$\endgroup\$ – DenDenDo Aug 4 '14 at 14:35
  • 1
    \$\begingroup\$ You can save another 3bytes by using map: b=min(max(b,*map(int,[c*a+d,-c*a+e,y+s/c]))). You also don't need the parens around a and b: a,b=GetCursorPos() which saves 2bytes. You ALSO don't need to recalculate and store a and b. Simply put the calculations into the call to S: S((min(max(a,x-s),x+s),min(max(b,int(c*a+d),int(-c*a+e)),int(y+s/c)))) which saves 4bytes. \$\endgroup\$ – BeetDemGuise Aug 4 '14 at 17:25
  • 1
    \$\begingroup\$ If you don't need the short circuit behaviour of and, you can replace kbhit()and ord(getch())==27 with kbhit()*ord(getch())==27 to save 3 characters, because True is cast to 1 and False is cast to 0 in Python. Also, you can put the first and second lines of the while loop on the same line, separated by a semicolon, to save another character. Finally, you only use d and e once each, so there is no point in defining them as variable. Just put Y-c*x and Y+c*x in the proper locations. \$\endgroup\$ – isaacg Aug 4 '14 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.