La distancia más corta entre dos puntos es una línea.


27

Codifique un programa o función para construir un lienzo interactivo en la pantalla de al menos 400 píxeles x 400 píxeles de tamaño. El lienzo puede ser del color que desee, con o sin bordes, con o sin barra de título, etc., solo alguna forma de lienzo obvio.

El usuario hará clic en dos áreas distintas del lienzo y el programa debe generar la distancia euclidiana (en píxeles) entre esos dos clics de alguna manera (STDOUT, mostrar una alerta, etc.). Los dos clics pueden ser solo clics izquierdos, solo clics derechos, un clic izquierdo para el primer y derecho para el segundo, dos clics dobles, etc., cualquier combinación es aceptable. Nota especial: Hacer clic y arrastrar (por ejemplo, usar MOUSEUP como el segundo punto) no está específicamente permitido; deben ser dos clics distintos.

El usuario debe poder hacer esto varias veces, y debe obtener una salida cada vez, hasta que el programa se cierre / force-quit / kill / etc. Puede elegir el método de cierre (haciendo clic en una X, Ctrl-C, etc.), lo que sea más apropiado para su código.

Reglas

  • Un programa completo o una función son aceptables. Sin embargo, si se trata de una función, aún debe mostrar la salida al usuario de alguna manera (simplemente no es aceptable devolver el valor).
  • La salida puede ser a la consola, mostrada como una alerta, poblada en el lienzo, etc.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

¿Podemos generar resultados exactos (que pueden contener raíces cuadradas) o tienen que ser decimales?
Martin Ender el

@MartinEnder O / o. El formato de salida no es la parte interesante de este desafío.
AdmBorkBork

1
La solución HTML / JS, desde el segundo clic, genera la distancia desde ese clic hasta el clic anterior. (así que si el usuario hace clic en los ntiempos, en n-1lugar de floor(n/2)imprimir los números) ¿Está permitido?
user202729

@ user202729 Está un poco fuera de lo que estaba imaginando, pero puedo ver cómo cumple con las reglas que he escrito anteriormente, así que lo permitiré.
AdmBorkBork

1
¿Podemos usar un tamaño de lienzo más pequeño si nuestro idioma no puede admitir un lienzo de 400 x 400?
Scott Milner el

Respuestas:


8

LOGOTIPO ( FMSLogo ), 54 52 bytes

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

Desafortunadamente, no puedo encontrar ningún soporte para el manejo de mouse en línea de intérprete de Logo como FMSLogo.

Esta es una "plantilla de ranura explícita", que es similar a lambda en otros lenguajes de programación. Haga clic con el mouse izquierdo para el primer punto y el mouse derecho para el segundo punto (distancia de impresión).

Explicación: (El logotipo es un lenguaje de programación de gráficos de tortuga)

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

El "es una palabra vacía. Normalmente se espera que la plantilla sea una lista (donde [], una lista vacía, no hace nada), pasar una palabra es aceptable (está envuelto en una lista), y en este caso ahorra 2 bytes.

Correr:

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

Esta applyes una forma de ejecutar la plantilla en Logo, []es la lista de argumentos, para la cual la plantilla no recibe ninguno.


¿Cómo garantiza esto el lienzo mínimo de 400x400?
David Mulder

1
@DavidMulder FMSLogo por defecto (sin línea de comando adicional) comienza con el lienzo 1000 × 1000.
user202729

7

Mathematica, 94 bytes

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

El lienzo es una imagen aleatoria en escala de grises, el primer clic debe ser izquierdo y el segundo, derecho. El comportamiento exacto es que el clic derecho imprime la distancia hasta el último clic (izquierdo o derecho), por lo que si usa el botón derecho repetidamente, también puede obtener distancias consecutivas.

Los resultados son exactos, por lo que pueden contener una raíz cuadrada.

Si la resolución de su cámara web es de al menos 400x400, puede usarla en CurrentImage[]lugar de 1~RandomImage~400su lienzo, ahorrando 3 bytes.


@Jenny_mathy ¿Versión de Mathematica tal vez? Probé esto en 11.1.
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);}}

Sería más corto con AWT, pero nunca lo he usado.


Creo que truepodría ser 0<1.
Jonathan Frech el

Además, main(String args[])no puede ser main(String[]Z)?
Jonathan Frech el

Creo que {F f=new F();}puede ser {new F();}.
Jonathan Frech el

setVisible(0<1);se puede eliminar y puede agregar .show()al Marco; printlnpuede ser print.
Kevin Cruijssen

1
@KevinCruijssen No sé cómo OP quiere la salida para múltiples resultados
Roberto Graham

5

Java (OpenJDK 8) , 282 bytes

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

No puedo probar esto ahora mismo; si alguien pudiera decirme si hay algún error de compilación que sería genial.

AWT probablemente sería más corto, pero necesito un IDE real para eso jajaja. Nunca he usado AWT antes, pero podría hacerlo funcionar si tuviera un IDE. Podría usar los documentos, pero eso es realmente difícil jajaja

-10 bytes usando AWT gracias a Kevin Cruijssen
-44 bytes usando un bloque inicializador; desarrollado independientemente de Roberto Graham aunque ahora veo que hicieron lo mismo, creo que
-6 bytes combinando algunas declaraciones gracias a Kevin
-11 bytes usando un interfacegracias a Kevin
-35 bytes eliminando algunas variables innecesarias gracias a la eliminación de mellamokb
-9 bytes la importación innecesaria y el uso de un nombre calificado gracias a mellamokb
-44 bytes gracias a mellamokb y aditsu


4

TI-Basic (TI-84 Plus CE), 49 bytes (45 tokens) (posiblemente no compite)

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

-7 bytes con sugerencias de kamoroso94

El usuario no hace "clic" per se, sino que se mueve alrededor de un cursor en la pantalla del gráfico con las teclas de flecha y enterpulsa para seleccionar un punto, y el movimiento más pequeño es ~ 1.5 para xy ~ 2.4 para y.

Explicación:

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
Dado que el tamaño solo tiene que ser al menos 400, puede jugar golf de manera constante a algo como que es mayor que 400 pero un byte menos.
kamoroso94

1
También puede reducir la Displínea en dos bytes con {X-A,Y-B:Disp √(sum(Ans²(los dos puntos o la nueva línea funcionan obviamente).
kamoroso94

@ kamoroso94 Mi TI-BASIC está oxidado, pero ¿no sería 8^2el mismo número de bytes?
Todd Sewell el

@ToddSewell no, 8^2(8 al cuadrado) es 64 y menos de 400. Dije (8 al cubo) que es mayor que 400 y usa dos tokens, un byte cada uno: 8y ³.
kamoroso94

1
@ToddSewell: Seguro que hay (MATH → 3).
Nick Matteo

4

JavaScript (ES6) + HTML, 58 bytes

La página web en sí misma sirve como el "lienzo" en cuestión; Creo que es bastante seguro asumir que la ventana del navegador tendrá al menos 400x400 píxeles.

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


JavaScript (ES6) + HTML, 51 bytes

Podemos guardar 7 bytes si ignoramos la NaNsalida en el primer clic. ( @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 bytes

Editar : con 13 bytes adicionales de CSS, podemos asegurarnos de que el área de desplazamiento sea lo suficientemente grande como para ajustarse al requisito de 400x400.

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


2

Procesamiento / Java, 149 bytes

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

Bastante sencillo, utiliza 2 variables globales y 3 funciones integradas para hacer todo.

  • Configuración: solo inicializa la ventana a 400x400
  • Dibujar: vacío, pero debe existir para que el procesamiento sea interactivo durante> 1 fotograma
  • Presionado con el mouse: si hace clic con el botón izquierdo, guarde las coordenadas del mouse en los enteros ay b. Si hace clic con el botón derecho, mida la distancia desde el punto (a, b) a la posición actual e imprima en la consola.

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

Pitón 2, 144

Imprime la distancia entre los últimos clics (el primero imprime la distancia desde 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 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

Se podría pensar que un lenguaje creado específicamente para capturar y simular acciones de teclado y mouse sería más eficiente en este desafío ...

Esto crea una ventana con un cuadro de texto de 400 x 400 píxeles con un borde para que sea obvio. Sin el borde, hay un espacio alrededor del borde que está en la ventana pero fuera del cuadro de texto y no se nota. Agregar un borde era la forma más corta de diferenciarlos. La gCopción hace que ejecute la subrutina Ccada vez que hace clic en el cuadro de texto. La secuencia de comandos es, por lo tanto, clic izquierdo seguido de un clic izquierdo diferente.

Encontré otra solución que tiene 144 bytes, pero permite clics en toda la pantalla en lugar de solo en el "lienzo obvio". También es molesto terminar porque se capturan los clics izquierdo y derecho y no termina cuando cierra la 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 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 viene con un tamaño predeterminado de lienzo de tamaño (800x, 600y).

Esto genera una imagen temporal de tortuga por cada punto de "inicio" en el que se hace clic, que desaparece después de seleccionar el siguiente punto de "inicio". Este comportamiento es aprobado por el OP.


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

Utiliza la pantalla táctil para la entrada.


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

Aquí hay una solución Java que utiliza un método AWT en desuso mouseDownque tendría que profundizar en la API para encontrarlo. Solo lo sé por el curso de programación que tomé como estudiante de secundaria y uno de los proyectos fue hacer un pequeño programa de pintura usando eso y métodos similares. Nunca pensé que tendría una buena razón para usarlo hasta ahora.


0

Tcl / Tk, 94104

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

ingrese la descripción de la imagen aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.