Der kürzeste Abstand zwischen zwei Punkten ist eine Linie

27

Codieren Sie ein Programm oder eine Funktion, um eine interaktive Leinwand mit einer Größe von mindestens 400 x 400 Pixel auf dem Bildschirm zu erstellen. Die Leinwand kann eine beliebige Farbe haben, umrandet oder randlos, mit oder ohne Titelleiste usw., nur irgendeine Form von offensichtlicher Leinwand.

Der Benutzer klickt auf zwei verschiedene Bereiche der Zeichenfläche und das Programm muss den euklidischen Abstand (in Pixel) zwischen diesen beiden Klicks auf irgendeine Weise ausgeben (STDOUT, Anzeigen einer Warnung usw.). Die zwei Klicks können nur Linksklicks, nur Rechtsklicks, ein Linksklick für den ersten und ein Rechtsklick für den zweiten, zwei Doppel-Linksklicks usw. sein, jede Kombination ist akzeptabel. Besonderer Hinweis: Klicken und Ziehen (z. B. mit MOUSEUP als zweitem Punkt) ist ausdrücklich nicht zulässig. Es müssen zwei unterschiedliche Klicks sein.

Der Benutzer muss dies mehrere Male tun können und jedes Mal eine Ausgabe erhalten, bis das Programm geschlossen / beendet / beendet / etc. Wird. Sie können die Schließmethode auswählen (Klicken auf ein X, Strg-C usw.), je nachdem, was für Ihren Code besser geeignet ist.

Regeln

  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig. Wenn jedoch eine Funktion vorhanden ist, müssen Sie die Ausgabe dem Benutzer trotzdem irgendwie anzeigen (eine einfache Rückgabe des Werts ist nicht akzeptabel).
  • Die Ausgabe kann auf der Konsole erfolgen, als Warnung angezeigt, auf der Zeichenfläche angezeigt werden usw.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.
AdmBorkBork
quelle
Können wir exakte Ergebnisse ausgeben (die Quadratwurzeln enthalten können) oder müssen es Dezimalzahlen sein?
Martin Ender
@MartinEnder Entweder / oder. Die Ausgabeformatierung ist nicht der interessante Teil dieser Herausforderung.
AdmBorkBork
1
Die HTML / JS-Lösung gibt ab dem zweiten Klick die Entfernung von diesem Klick zum vorherigen Klick aus. (also wenn der benutzer nmal klickt , werden n-1statt floor(n/2)zahlen gedruckt) Ist das erlaubt?
user202729
@ user202729 Es liegt etwas außerhalb meiner Vorstellung, aber ich kann sehen, wie es mit den Regeln übereinstimmt, die ich oben geschrieben habe, also werde ich es zulassen.
AdmBorkBork
1
Können wir eine kleinere Leinwandgröße verwenden, wenn unsere Sprache eine Leinwandgröße von 400 x 400 nicht unterstützt?
Scott Milner

Antworten:

8

LOGO ( FMSLogo ), 54 52 Bytes

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

Leider kann ich keine Online-Unterstützung für Logo-Interpreter-Mäuse wie FMSLogo finden.

Dies ist eine "Explicit-Slot-Vorlage", die Lambda in anderen Programmiersprachen ähnelt. Klicken Sie mit der linken Maustaste für den ersten Punkt und mit der rechten Maustaste für den zweiten Punkt (Druckabstand).

Erklärung: (Logo ist eine Programmiersprache für Schildkrötengrafiken)

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

Das "ist ein leeres Wort. Normalerweise wird erwartet, dass die Vorlage eine Liste ist (wobei []eine leere Liste nichts bewirkt). Das Übergeben eines Wortes ist akzeptabel (es wird in eine Liste eingeschlossen) und in diesem Fall werden 2 Bytes gespart.

Lauf:

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

Dies applyist eine Möglichkeit, eine Vorlage in Logo auszuführen. Dies ist die []Argumentliste, für die die Vorlage keine empfängt.

user202729
quelle
Wie garantiert dies die Mindestgröße von 400 x 400 Zeichen?
David Mulder
1
@DavidMulder FMSLogo beginnt standardmäßig (ohne zusätzliche Befehlszeile) mit Canvas 1000 × 1000.
User202729
7

Mathematica, 94 Bytes

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

Die Leinwand ist ein zufälliges Graustufenbild, der erste Klick sollte ein Linksklick und der zweite ein Rechtsklick sein. Das genaue Verhalten ist, dass beim Klicken mit der rechten Maustaste der Abstand zum letzten Klick (nach links oder rechts) gedruckt wird. Wenn Sie also wiederholt mit der rechten Maustaste klicken, können Sie auch aufeinanderfolgende Abstände abrufen.

Die Ergebnisse sind exakt und können eine Quadratwurzel enthalten.

Wenn die Auflösung Ihrer Webcam mindestens 400 x 400 beträgt, können Sie CurrentImage[]anstelle der 1~RandomImage~400Leinwand 3 Byte einsparen.

Martin Ender
quelle
@ Jenny_mathy Mathematica-Version vielleicht? Ich habe das am 11.1 getestet.
Martin Ender
6

Java 8, 469 389 388 385 380 357 348 325 Bytes

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

Wäre mit AWT kürzer, aber ich habe es nie benutzt.

Roberto Graham
quelle
Ich denke truekönnte sein 0<1.
Jonathan Frech
Auch kann main(String args[])nicht sein main(String[]Z)?
Jonathan Frech
Ich denke {F f=new F();}kann sein {new F();}.
Jonathan Frech
setVisible(0<1);kann entfernt und .show()dem Rahmen hinzugefügt werden ; printlnkann sein print.
Kevin Cruijssen
1
@ KevinCruijssen Ich weiß nicht, wie OP die Ausgabe für mehrere Ergebnisse will
Roberto Graham
5

Java (OpenJDK 8) , 282 Byte

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();}};}}

Ich kann das jetzt noch nicht testen. Wenn mir jemand sagen könnte, ob es Compilerfehler gibt, wäre das großartig.

AWT wäre wahrscheinlich kürzer, aber ich brauche eine tatsächliche IDE für das lol. Ich habe AWT noch nie benutzt, aber ich könnte es zum Laufen bringen, wenn ich eine IDE hätte. Ich könnte die Dokumente benutzen, aber das ist wirklich schwer, lol

-10 Bytes mit AWT dank Kevin Cruijssen
-44 Bytes mit einem Initialisierungsblock; unabhängig von Roberto Graham entwickelt, obwohl ich jetzt sehe, dass sie das gleiche getan haben, denke ich, dass
-6 Bytes ein paar Deklarationen dank Kevin
-11 Bytes kombinieren und interfacedank Kevin
-35 Bytes einige unnötige Variablen eliminieren, dank mellamokb
-9 Bytes entfernen der unnötige import und die verwendung eines qualifizierten namens dank mellamokb
-44 bytes dank mellamokb und aditsu

HyperNeutrino
quelle
4

TI-Basic (TI-84 Plus CE), 49 Byte (45 Tokens) (möglicherweise nicht konkurrierend)

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

-7 Bytes mit Vorschlägen von kamoroso94

Der Benutzer "klickt" nicht per se, sondern bewegt sich mit den Pfeiltasten und Hits um einen Cursor auf dem Graphikbildschirm enter, um einen Punkt auszuwählen, und die kleinste Bewegung beträgt ~ 1,5 für x und ~ 2,4 für y.

Erläuterung:

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
Pizzapants184
quelle
1
Da die Größe nur mindestens 400 sein muss, können Sie diese Konstante auf etwas setzen, das größer als 400 ist, aber ein Byte weniger.
Kamoroso94
1
Außerdem können Sie die DispZeile mit um zwei Bytes verkleinern {X-A,Y-B:Disp √(sum(Ans²(Doppelpunkt oder Zeilenumbruch funktionieren offensichtlich).
Kamoroso94
@ kamoroso94 Mein TI-BASIC ist verrostet, aber wäre das nicht 8^2die gleiche Anzahl von Bytes?
Todd Sewell
@ToddSewell nein, 8^2(8 Quadrat) ist 64 und kleiner als 400. Ich sagte (8 Würfel), der größer als 400 ist und zwei Token verwendet, jeweils ein Byte: 8und ³.
Kamoroso94
1
@ToddSewell: Da ist sicher (MATH → 3).
Nick Matteo
4

JavaScript (ES6) + HTML, 58 Byte

Die Webseite selbst dient als "Leinwand" in Frage; Ich denke, es ist ziemlich sicher anzunehmen, dass das Browserfenster mindestens 400x400 Pixel groß sein wird.

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


JavaScript (ES6) + HTML, 51 Byte

Wir können 7 Bytes einsparen, wenn wir die NaNAusgabe beim ersten Klick ignorieren . ( @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 Byte

Bearbeiten : Mit zusätzlichen 13 Byte CSS können wir sicherstellen, dass der Bildlaufbereich groß genug ist, um die 400 x 400-Anforderung zu erfüllen.

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

darrylyeo
quelle
2

Verarbeitung / Java, 149 Byte

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

Ziemlich einfach, verwendet 2 globale Variablen und 3 integrierte Funktionen, um alles zu tun.

  • Setup: Initialisiert das Fenster nur auf 400x400
  • Zeichnen: leer, muss jedoch vorhanden sein, damit die Verarbeitung für> 1 Frame interaktiv ist
  • MousePressed: Wenn Sie mit der linken Maustaste klicken, speichern Sie die Mauskoordinaten in den Ganzzahlen a und b. Wenn Sie mit der rechten Maustaste klicken, messen Sie den Abstand zwischen Punkt (a, b) und der aktuellen Position und drucken Sie auf der Konsole.
Cody
quelle
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);}
PrincePolka
quelle
1

Python 2, 144

Gibt den Abstand zwischen den letzten Klicks aus (der erste gibt den Abstand zwischen 400 und 400 aus).

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()
pacholik
quelle
0

Autohotkey, 146 Bytes

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

Eine Sprache, die speziell für das Erfassen und Simulieren von Tastatur- und Mausaktionen entwickelt wurde, könnte bei dieser Herausforderung effizienter sein ...

Dadurch wird ein Fenster mit einem Textfeld von 400 x 400 Pixel mit einem Rand erstellt, um dies deutlich zu machen. Ohne den Rand befindet sich ein Leerzeichen um den Rand im Fenster, aber außerhalb des Textfelds, und Sie können es nicht erkennen. Das Hinzufügen einer Grenze war der kürzeste Weg, um sie zu unterscheiden. Mit dieser gCOption wird die Unterroutine ausgeführt, Cwenn Sie auf das Textfeld klicken. Die Befehlssequenz ist daher Linksklick, gefolgt von einem anderen Linksklick.

Ich habe eine andere Lösung gefunden, die 144 Bytes umfasst, aber Klicks über den gesamten Bildschirm zulässt, anstatt nur in der "offensichtlichen Zeichenfläche". Es ist auch ärgerlich zu beenden, da sowohl Links- als auch Rechtsklicks erfasst werden und es nicht endet, wenn Sie die GUI schließen.

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
Ingenieur Toast
quelle
0

Python 2 ( TigerJython ), 125 123 Bytes

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 wird mit einer Standardgröße von (800x, 600y) Leinwand geliefert.

Dies erzeugt ein temporäres Schildkrötenbild für jeden angeklickten Startpunkt, das verschwindet, nachdem der nächste Startpunkt ausgewählt wurde. Dieses Verhalten wird vom OP genehmigt.

Yytsi
quelle
0

SmileBASIC, 86 Bytes

@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

Verwendet Touchscreen zur Eingabe.

12Me21
quelle
0

Java 8, 228 Bytes

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();}}

Im Folgenden finden Sie eine Java-Lösung, die eine veraltete AWT-Methode verwendet mouseDown, die Sie erst in die API einarbeiten müssen, um sie zu finden. Ich weiß es nur aufgrund des Programmierkurses, den ich als Gymnasiast absolvierte, und eines der Projekte bestand darin, ein kleines Malprogramm mit diesem und ähnlichen Methoden zu erstellen. Ich hätte nie gedacht, dass ich einen guten Grund haben würde, es bis jetzt zu benutzen.

TNT
quelle
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}

Bildbeschreibung hier eingeben

Sergiol
quelle