ระยะทางที่สั้นที่สุดระหว่างสองจุดคือเส้น


27

กำหนดรหัสโปรแกรมหรือฟังก์ชั่นเพื่อสร้างผืนผ้าใบแบบโต้ตอบบนหน้าจอที่มีขนาดอย่างน้อย 400 พิกเซล x 400 พิกเซล ผ้าใบสามารถเป็นสีใดก็ได้ที่คุณต้องการขอบหรือไม่มีขอบมีหรือไม่มีแถบชื่อเรื่อง ฯลฯ เพียงผ้าใบบางรูปแบบที่ชัดเจน

ผู้ใช้จะคลิกบนพื้นที่ที่แตกต่างกันสองส่วนของผืนผ้าใบและโปรแกรมจะต้องส่งออกระยะทางแบบยุคลิด (เป็นพิกเซล) ระหว่างการคลิกสองครั้งในบางแบบ (STDOUT, การแสดงการแจ้งเตือน ฯลฯ ) การคลิกสองครั้งสามารถคลิกซ้ายได้เพียงคลิกขวาคลิกซ้ายสำหรับการคลิกครั้งแรกและคลิกขวาสำหรับการคลิกครั้งที่สองสองครั้งดับเบิลคลิกซ้าย ฯลฯ สามารถใช้ชุดค่าผสมใดก็ได้ หมายเหตุพิเศษ: ไม่อนุญาตให้คลิกและลาก (เช่นใช้ MOUSEUP เป็นจุดที่สอง) โดยเฉพาะ พวกเขาจะต้องคลิกสองครั้งที่แตกต่างกัน

ผู้ใช้จะต้องสามารถทำสิ่งนี้ได้หลายครั้งและต้องได้รับผลลัพธ์ในแต่ละครั้งจนกว่าโปรแกรมจะปิด / force-quit / kill / etc คุณสามารถเลือกวิธีการปิด (คลิก 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

คำตอบ:


8

โลโก้ ( FMSLogo ) ขนาด54 52 ไบต์

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

น่าเสียดายที่ฉันไม่พบการจัดการการสนับสนุนเม้าส์โลโก้ล่ามออนไลน์เช่น FMSLogo

นี่คือ "เท็มเพลตที่ชัดเจน" ซึ่งคล้ายกับแลมบ์ดาในภาษาการเขียนโปรแกรมอื่น ๆ คลิกเมาส์ซ้ายสำหรับจุดแรกและเมาส์ขวาสำหรับจุดที่สอง (ระยะการพิมพ์)

คำอธิบาย: (โลโก้เป็นภาษาการเขียนโปรแกรมกราฟิกเต่า)

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เป็นวิธีหนึ่งในการเรียกใช้เทมเพลตในโลโก้[]รายการของอาร์กิวเมนต์ซึ่งเทมเพลตนั้นไม่ได้รับ


สิ่งนี้รับประกันผ้าใบขั้นต่ำ 400x400 ได้อย่างไร
David Mulder

1
@DavidMulder FMSLogo โดยค่าเริ่มต้น (โดยไม่มีบรรทัดคำสั่งเพิ่มเติม) เริ่มต้นด้วย canvas 1000 × 1,000
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~400Canvas ของคุณโดยประหยัดได้ 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
Jonathan Frech

นอกจากนี้main(String args[])ไม่สามารถmain(String[]Z)?
Jonathan Frech

ผมคิดว่าอาจจะเป็น{F f=new F();} {new F();}
Jonathan Frech

setVisible(0<1);สามารถลบออกได้และคุณสามารถเพิ่ม.show()ในกรอบ; สามารถprintln print
Kevin Cruijssen

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 ฉันสามารถใช้เอกสารได้ แต่มันยากมาก ๆ

-10 bytes โดยใช้ AWT ต้องขอบคุณ Kevin Cruijssen
-44 bytes โดยใช้ initializer block; พัฒนาโดยอิสระจาก Roberto Graham แม้ว่าตอนนี้ฉันจะเห็นว่าพวกเขาทำสิ่งเดียวกันฉันคิดว่า
-6 bytes รวมการประกาศเล็กน้อยขอบคุณ Kevin
-11 bytes โดยใช้interfaceขอบคุณ Kevin
-35 bytes กำจัดตัวแปรที่ไม่จำเป็นขอบคุณ mellamokb
-9 bytes การอิมพอร์ตและการใช้ชื่อที่ไม่จำเป็นต้องขอบคุณ mellamokb
-44 bytes ขอบคุณ 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

ผู้ใช้ไม่ได้ 'คลิก' ต่อ se แต่เลื่อนเคอร์เซอร์บนหน้าจอกราฟด้วยปุ่มลูกศรและเพลงฮิตenterเพื่อเลือกจุดและการเคลื่อนไหวที่เล็กที่สุดคือ ~ 1.5 สำหรับ x และ ~ 2.4 สำหรับ y

คำอธิบาย:

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

1
นอกจากนี้คุณสามารถลดDispบรรทัดทีละสองไบต์ด้วย{X-A,Y-B:Disp √(sum(Ans²(โคลอนหรือการขึ้นบรรทัดใหม่ทำงานได้อย่างชัดเจน)
kamoroso94

@ kamoroso94 TI-BASIC ของฉันเป็นสนิม แต่จะ8^2ไม่เป็นเช่นนั้นจำนวนไบต์เท่ากัน?
ทอดด์ซีเวลล์

@ToddSewell ไม่มี8^2(8 ยกกำลังสอง) เป็น 64 และน้อยกว่า 400 ผมบอกว่า(8 cubed) ซึ่งมากกว่า 400 และการใช้สองสัญญาณหนึ่งไบต์แต่ละและ8 ³
kamoroso94

1
@ToddSewell: มีแน่นอน (MATH → 3)
Nick Matteo

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 ไบต์

เราสามารถบันทึกได้ 7 ไบต์หากไม่สนใจNaNเอาต์พุตในการคลิกครั้งแรก ( @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 ไบต์

แก้ไข : ด้วย CSS เพิ่มเติม 13 ไบต์เราสามารถมั่นใจได้ว่าพื้นที่เลื่อนจะใหญ่พอที่จะรองรับความต้องการ 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

กำลังดำเนินการ 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

Autohotkey, 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 เพื่อค้นหา ฉันรู้เรื่องนี้เพียงเพราะหลักสูตรการเขียนโปรแกรมที่ฉันเรียนเป็นนักเรียนชั้นมัธยมปลายและหนึ่งในโครงการก็คือการทำโปรแกรมระบายสีเล็ก ๆ โดยใช้วิธีนั้นและวิธีการที่คล้ายกัน ฉันไม่เคยคิดว่าฉันมีเหตุผลที่ดีที่จะใช้มันจนถึงตอนนี้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.