两点之间的最短距离是一条线


27

对程序或函数进行编码,以在屏幕上构造至少400像素x 400像素的交互式画布。画布可以是您想要的任何颜色,有边框或无边框,有或没有标题栏等,仅是某种形式的显而易见的画布。

用户将单击画布的两个不同区域,并且程序必须以某种方式(STDOUT,显示警报等)输出两次单击之间的欧几里得距离(以像素为单位)。两次单击只能是左键单击,只能是右键单击,第一次单击是左键单击,第二次单击是右键,两次双击都以此类推,可以接受任何组合。特别说明:明确不允许单击和拖动(例如,使用MOUSEUP作为第二点);它们必须是两次不同的点击。

用户必须能够多次执行此操作,并且每次都必须获得输出,直到程序关闭/强制退出/被杀死/等等。您可以选择关闭的方法(单击X,Ctrl-C等),无论哪种代码适合您。

规则

  • 完整的程序或功能都是可以接受的。但是,如果是函数,则仍必须以某种方式向用户显示输出(仅返回值是不可接受的)。
  • 输出可以发送到控制台,显示为警报,填充到画布等。
  • 禁止出现标准漏洞
  • 这是因此所有常用的高尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

我们可以输出精确的结果(可能包含平方根)还是必须是小数?
Martin Ender

@ / MartinEnder或者。输出格式并不是此挑战的有趣部分。
AdmBorkBork

1
HTML / JS解决方案从第二次单击开始,输出从该次单击到上次单击的距离。(因此,如果用户单击了n时间,n-1而不是floor(n/2)打印了数字)是否可以?
user202729

@ user202729这有点超出我的预期,但是我可以看到它如何符合我上面编写的规则,所以我允许它。
AdmBorkBork

1
如果我们的语言无法支持400 x 400的画布,我们可以使用较小的画布尺寸吗?
Scott Milner

Answers:


8

LOGO(FMSLogo),54 52字节

[mouseon[setpos mousepos]"[pr distance mousepos]"[]]

不幸的是,我找不到像FMSLogo这样的在线徽标解释器支持鼠标处理功能。

这是一个“显式插槽模板”,与其他编程语言中的lambda相似。单击鼠标左键选择第一个点,鼠标右键单击第二个点(打印距离)。

说明:(徽标是Turtle图形编程语言)

mouseon                  Turn on mouse handling, with the following action:
[setpos mousepos]        Set the turtle to `mousepos` (the position of the mouse) on left mouse down
"                        Do nothing on left mouse up
[pr distance mousepos]   Print the distance from turtle position (`distance` is Logo builtin for that purpose) to `mousepos` on right mouse down
"                        Do nothing on right mouse up
[]                       Do nothing on mouse movement

"是一句空话。通常,模板应该是一个列表(其中[],一个空列表,不执行任何操作),可以传递一个单词(它包装在列表中)是可以接受的,在这种情况下,它节省了2个字节。

跑:

apply [... <put the code here> ...] []

apply是在徽标中运行模板的一种方法,即[]is参数列表,模板对此模板不会接收任何参数。


如何保证最小的400x400画布?
David Mulder

1
@DavidMulder FMSLogo默认情况下(不带附加命令行)以画布1000×1000开始。
user202729

7

Mathematica,94个字节

e="MouseDown";m:=x=MousePosition[];1~RandomImage~400~EventHandler~{e:>m,{e,2}:>Echo@Norm[x-m]}

画布是随机的灰度图像,第一次单击应该是左键单击,第二次单击应该是右键单击。确切的行为实际上是右键单击可显示到最后一次单击的距离(左右),因此,如果重复使用右键单击,还可以获得连续的距离。

结果是准确的,因此它们可能包含平方根。

如果网络摄像头的分辨率至少为400x400,则可以使用CurrentImage[]来代替1~RandomImage~400画布,节省3个字节。


@Jenny_mathy Mathematica版本?我在11.1上进行了测试。
Martin Ender

6

Java的8,469 389 388 385 380个 357 348 325字节

import java.awt.event.*;interface F{static void main(String[]a){new java.awt.Frame(){{setSize(400,400);double[]a={-1,0};addMouseListener(new MouseAdapter(){public void mouseClicked(MouseEvent e){if(a[0]<0){a[0]=e.getX();a[1]=e.getY();}else{System.out.println(Math.hypot(e.getX()-a[0],e.getY()-a[1]));a[0]=-1;}}});}}.show();}}

import javafx.application.*;import javafx.scene.*;import javafx.scene.layout.*;import javafx.stage.*;public class E extends Application{double[]a={-1,0};public void start(Stage s)throws Exception{Pane p=new Pane();s.setScene(new Scene(p,400,400));s.show();p.setOnMouseClicked(e->{if(a[0]<0){a[0]=e.getX();a[1]=e.getY();}else {System.out.println(Math.sqrt(Math.pow(e.getX()-a[0],2)+Math.pow(e.getY()-a[1],2)));a[0]=-1;}});}public static void main(String[]a){launch(a);}}

AWT会更短一些,但我从未使用过。


我想true可能是0<1
乔纳森·弗雷希

此外,可以main(String args[])main(String[]Z)
乔纳森·弗雷奇

我认为{F f=new F();}可以{new F();}
乔纳森·弗雷希

setVisible(0<1);可以删除,并且可以添加.show()到框架中;println可以print
凯文·克鲁伊森

1
@KevinCruijssen我不知道OP如何希望输出多个结果
Roberto Graham

5

Java(OpenJDK 8),282字节

import java.awt.event.*;interface M{static void main(String[]a){new java.awt.Frame(){int k,x,y;{addMouseListener(new MouseAdapter(){public void mouseClicked(MouseEvent e){x=e.getX()-k*x;y=e.getY()-k*y;k^=1;if(k<1)System.out.prin‌​tln(Math.hypot(x,y))‌​;}});setSize(800,600‌​);show();}};}}

我现在无法测试。如果有人可以告诉我,是否有任何编译器错误会很棒。

AWT可能会更短一些,但我需要一个适用于此的实际IDE。我以前从未使用过AWT,但是如果有IDE,我可以使其工作。我可以使用文档,但这真的很难

凯文·克鲁伊森(Kevin Cruijssen)
使用初始化块-44 字节,因此使用AWT -10字节;由Roberto Graham独立开发,虽然我现在看到它们做了相同的事情,但我认为
-6字节结合了一些声明,这要归功于Kevin
-11字节,interface感谢Kevin
-35字节消除了不必要的变量,这是由于mellamokb
-9字节删除了得益于mellamokb
-44字节,得益于mellamokb和aditsu ,不必要的导入和使用限定名称


4

TI-Basic(TI-84 Plus CE),49字节(45个令牌)(可能不竞争)

0→Xmin
0→Ymin
8³→Xmax
Ans→Ymax
While 1
Input 
{X,Y
Input 
Ans-{X,Y
Disp √(sum(Ans²
Pause
End

-7个字节,来自kamoroso94的建议

用户本身并不是“单击”,而是使用箭头键和击键在图形屏幕上的光标周围移动enter以选择一个点,x的最小移动为〜1.5,y的最小移动为〜2.4。

说明:

0→Xmin                # 5 bytes
0→Ymin                # 5 bytes
8³→Xmax               # 6 bytes, 
Ans→Ymax              # 5 bytes, Set up graph screen size (512x512)
While 1               # 3 bytes, Until interrupted with `on` button
Input                 # 2 bytes, Get user input as a point on the graph screen in X and Y
{X,Y                  # 5 bytes, store the list {X,Y} in Ans
Input                 # 2 bytes, Get second user input as a point on the graph screen in X and Y
Ans-{X,Y              # 7 bytes, store {X1-X2,Y1-Y2} in Ans
Disp √(sum(Ans²       # 6 bytes, Display the distance between the two points
Pause                 # 2 bytes, Let the user see it (press `enter` to continue)
End                   # 1 bytes, End while loop

1
由于大小仅必须至少为400,因此您可以将该常量打高尔夫球,使其大于400,但减少一个字节。
kamoroso94 '17

1
你也可以用减少Disp两个字节{X-A,Y-B:Disp √(sum(Ans²(显然冒号或换行符)。
kamoroso94 '17

@ kamoroso94我的TI-BASIC生锈了,但不是8^2一样的字节数吗?
托德·塞威尔

@ToddSewell不,8^2(8的平方)为64并且小于400。我说(8的立方)大于400,并使用两个令牌,每个令牌一个字节:8³
kamoroso94 '17

1
@ToddSewell:肯定有(MATH→3)。
尼克·马特奥

4

JavaScript(ES6)+ HTML,58字节

该网页本身就是相关的“画布”;我认为假设浏览器窗口至少为400x400像素是很安全的。

E=0,onclick=e=>(E&&alert(Math.hypot(E.x-e.x,E.y-e.y)),E=e)


JavaScript(ES6)+ HTML,51字节

如果忽略NaN第一次单击时的输出,则可以节省7个字节。(@Nate

E=onclick=e=>alert(Math.hypot(E.x-e.x,E.y-e.y),E=e)


JavaScript(ES6)+ HTML + CSS,58 + 0 + 13 = 71字节

编辑:使用额外的13个字节的CSS,我们可以确保滚动区域足够大以适合400x400的要求。

E=0,onclick=e=>(E&&alert(Math.hypot(E.x-e.x,E.y-e.y)),E=e)
*{padding:9in


2

处理 / Java,149字节

void setup(){size(400,400);}void draw(){}int a,b;void mousePressed(){if(mouseButton==LEFT){a=mouseX;b=mouseY;}else println(dist(a,b,mouseX,mouseY));}

非常简单,使用2个全局变量和3个内置函数来完成所有操作。

  • 设置:仅将窗口初始化为400x400
  • 绘制:空,但必须存在,以便处理> 1帧进行交互
  • MousePressed:如果单击鼠标左键,则将鼠标坐标保存为整数a和b。如果单击鼠标右键,则测量从点(a,b)到当前位置的距离,然后打印到控制台。

2

Processing.org 126

float i,d,x,y;void setup(){fullScreen();}void draw(){}void mousePressed(){d=dist(x,y,x=mouseX,y=mouseY);print(i++%2<1?" ":d);}

1

Python 2,144

打印最后一次单击之间的距离(第一个单击打印距离为400,400)。

import Tkinter as t,math
r=t.Tk()
p=[400]*2
r.minsize(*p)
def f(e):print math.hypot(p[0]-e.x,p[1]-e.y);p[:]=e.x,e.y
r.bind('<1>',f)
r.mainloop()

0

自动热键,146个字节

A=0
Gui,Add,Text,W400 H400 gC Border
Gui,Show
Return
C:
If A=0
MouseGetPos,A,B
Else{
MouseGetPos,C,D
Msgbox % Sqrt((A-C)**2+(B-D)**2)
A=0
}
Return

您可能会认为,专门为捕获和模拟键盘和鼠标动作而构建的语言在应对这一挑战时会更加高效。

这将创建一个带有边框的400 x 400像素文本框的窗口,以使其显而易见。如果没有边框,则边缘周围的空间在窗口中,但在文本框之外,您无法分辨。添加边框是区分它们的最短方法。该gC选项使它C在您单击文本框时运行子例程。因此,命令序列为“左击”,然后是另一个“左击”。

我找到了另一个144字节的解决方案,但它允许在整个屏幕上单击,而不仅仅是在“显而易见的画布”中单击。结束也很烦人,因为同时捕获了左键和右键单击,并且在关闭GUI时并没有结束。

Gui,Add,Text,W400 H400 Border
Gui,Show
Return
LButton::
MouseGetPos,A,B
Return
RButton::
MouseGetPos,C,D
Msgbox % Sqrt((A-C)**2+(B-D)**2)
Return

0

Python 2中(TigerJython),125个 123字节

from gturtle import*
n=0
def c(x,y):
 global n
 if n:print distance(x,y)
 else:setPos(x,y)
 n^=1
makeTurtle(mousePressed=c)

TigerJython带有默认大小为(800x,600y)的画布。

这会为每个单击的“开始”点生成一个临时的乌龟图像,在选择下一个“开始”点后消失。此行为已由OP批准。


0

SmileBASIC,86个字节

@L
TOUCH OUT F,X,Y
S=S-X
T=T-Y
IF!O*F*M THEN?SQR(S*S+T*T)
S=X
T=Y
M=M!=!O*F
O=F
GOTO@L

使用触摸屏进行输入。


0

Java 8,228字节

interface A{static void main(String[]a){new java.awt.Frame(){{setSize(400,400);}int i,j,t;public boolean mouseDown(java.awt.Event e,int x,int y){if(t++%2==1)System.out.println(Math.hypot(x-i,y-j));i=x;j=y;return 1>0;}}.show();}}

这是一个Java解决方案,它使用了已弃用的AWT方法mouseDown,您必须深入研究API才能找到它。我只知道这是因为我在高中二年级时参加了编程课程,而其中的一个项目是使用该方法和类似方法制作一个小型绘画程序。直到现在,我从未想过有充分的理由使用它。


0

Tcl / Tk,94 104

wm ge . 400x400
bind . <1> {if [info ex x] {puts [expr hypot(%x-$x,%y-$y)]}
set x %x
set y %y}

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.