A menor distância entre dois pontos é uma linha


27

Codifique um programa ou função para construir uma tela interativa na tela com pelo menos 400 pixels x 400 pixels de tamanho. A tela pode ser da cor que você desejar, com ou sem borda, com ou sem uma barra de título, etc., apenas alguma forma de tela óbvia.

O usuário clicará em duas áreas distintas da tela e o programa deverá gerar a distância euclidiana (em pixels) entre esses dois cliques de alguma forma (STDOUT, exibindo um alerta etc.). Os dois cliques podem ser apenas cliques à esquerda, apenas cliques com o botão direito, um clique com o botão esquerdo no primeiro e clique com o botão direito no segundo, dois cliques com o duplo esquerdo, etc., qualquer combinação é aceitável. Nota especial: Clicar e arrastar (por exemplo, usando MOUSEUP como o segundo ponto) não é especificamente permitido; eles devem ser dois cliques distintos.

O usuário deve ser capaz de fazer isso várias vezes e deve obter uma saída a cada vez, até que o programa seja fechado / forçado a sair / interrompido / etc. Você pode escolher o método de fechamento (clicando em um X, ctrl-C, etc.), independentemente do seu código.

Regras

  • Um programa completo ou uma função são aceitáveis. Se uma função, no entanto, você ainda deve exibir a saída para o usuário de alguma forma (simplesmente retornar o valor não é aceitável).
  • A saída pode ser no console, exibida como um alerta, preenchida na tela, etc.
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.

Podemos produzir resultados exatos (que podem conter raízes quadradas) ou precisam ser decimais?
Martin Ender

@MartinEnder Ou /. A formatação de saída não é a parte interessante desse desafio.
AdmBorkBork #

1
A solução HTML / JS, a partir do segundo clique, gera a distância desse clique até o clique anterior. (portanto, se o usuário clicar nvezes, em n-1vez de floor(n/2)números serem impressos) Isso é permitido?
precisa saber é o seguinte

@ user202729 Está um pouco fora do que eu estava imaginando, mas posso ver como ele está em conformidade com as regras que escrevi acima, então permitirei.
AdmBorkBork #

1
Podemos usar um tamanho de tela menor se nosso idioma não suportar uma tela de 400 x 400?
21875 Scott Milner #

Respostas:


8

LOGO ( FMSLogo ), 54 52 bytes

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

Infelizmente, não consigo encontrar nenhum mouse on-line com suporte para intérpretes de logotipo, como o FMSLogo.

Este é um "modelo de slot explícito", que é semelhante ao lambda em outras linguagens de programação. Clique com o botão esquerdo do mouse no primeiro ponto e o botão direito no segundo ponto (distância de impressão).

Explicação: (O logotipo é uma linguagem de programação gráfica de tartaruga)

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

A "é uma palavra vazia. Normalmente, espera-se que o modelo seja uma lista (onde [], uma lista vazia, não faz nada), passar uma palavra é aceitável (é agrupado em uma lista) e, nesse caso, salva 2 bytes.

Corre:

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

A applyé uma maneira de executar modelo no Logo, a []lista de argumentos, para o qual o modelo receber nenhum é.


Como isso garante a tela mínima de 400x400?
David Mulder

1
O @DavidMulder FMSLogo, por padrão (sem linha de comando adicional), começa com a tela 1000 × 1000.
precisa saber é o seguinte

7

Mathematica, 94 bytes

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

A tela é uma imagem aleatória em escala de cinza, o primeiro clique deve ser o botão esquerdo e o segundo, o botão direito. O comportamento exato é que o clique com o botão direito do mouse imprime a distância até o último clique (esquerda ou direita); portanto, se você clicar com o botão direito repetidamente, também poderá obter distâncias consecutivas.

Os resultados são exatos, portanto, eles podem conter uma raiz quadrada.

Se a resolução da sua webcam for de pelo menos 400x400, você poderá usar em CurrentImage[]vez da 1~RandomImage~400tela, economizando 3 bytes.


@Jenny_mathy versão Mathematica, talvez? Eu testei isso no 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);}}

Seria mais curto com o AWT, mas nunca o usei.


Eu acho que truepoderia ser 0<1.
precisa

Além disso, main(String args[])não pode ser main(String[]Z)?
Jonathan Frech

Eu acho que {F f=new F();}pode ser {new F();}.
Jonathan Frech

setVisible(0<1);pode ser removido e você pode adicionar .show()ao quadro; printlnpode ser print.
11557 Kevin Murrijssen #

1
@KevinCruijssen Eu não sei como OP quer a saída para vários 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();}};}}

Eu não posso testar isso agora; se alguém pudesse me dizer se há algum erro de compilador que seria ótimo.

O AWT provavelmente seria mais curto, mas eu preciso de um IDE real para isso, lol. Eu nunca usei o AWT antes, mas poderia fazê-lo funcionar se tivesse um IDE. Eu poderia usar os documentos, mas isso é realmente difícil lol

-10 bytes usando AWT graças a Kevin Cruijssen
-44 bytes usando um bloco inicializador; desenvolvido independentemente de Roberto Graham, mas agora vejo que eles fizeram a mesma coisa, acho que
-6 bytes combinando algumas declarações graças a Kevin
-11 bytes usando interfaceagradecimentos a Kevin
-35 bytes eliminando algumas variáveis ​​desnecessárias graças à remoção de mellamokb
-9 bytes a importação desnecessária e o uso de um nome qualificado, graças a mellamokb
-44 bytes, graças a mellamokb e aditsu


4

TI-Basic (TI-84 Plus CE), 49 bytes (45 tokens) (possivelmente não concorrente)

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

-7 bytes com sugestões de kamoroso94

O usuário não 'clica' em si, mas move o cursor na tela do gráfico com as teclas de seta e enterpressiona para selecionar um ponto, e o menor movimento é ~ 1,5 para xe ~ 2,4 para y.

Explicação:

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
Como o tamanho só precisa ser de pelo menos 400, você pode jogar golfe nessa constante para algo como algo maior que 400, mas um byte a menos.
precisa saber é o seguinte

1
Além disso, você pode reduzir a Displinha em dois bytes com {X-A,Y-B:Disp √(sum(Ans²(dois pontos ou nova linha funciona obviamente).
precisa saber é o seguinte

@ kamoroso94 Meu TI-BASIC está enferrujado, mas não seria 8^2, o mesmo número de bytes?
Todd Sewell

@ToddSewell não, 8^2(8 ao quadrado) é 64 e menos que 400. Eu disse (8 em cubos) que é maior que 400 e usa dois tokens, um byte cada: 8e ³.
precisa saber é o seguinte

1
@ToddSewell: Com certeza existe (MATH → 3).
Nick Matteo

4

JavaScript (ES6) + HTML, 58 bytes

A própria página da web serve como a "tela" em questão; Eu acho que é bastante seguro supor que a janela do navegador terá pelo menos 400x400 pixels.

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


JavaScript (ES6) + HTML, 51 bytes

Podemos economizar 7 bytes se ignorarmos a NaNsaída no primeiro clique. ( @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

Edit : Com 13 bytes adicionais de CSS, podemos garantir que a área de rolagem seja suficientemente grande para atender ao requisito de 400x400.

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


2

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

Bem simples, usa 2 variáveis ​​globais e 3 funções internas para fazer tudo.

  • Instalação: apenas inicializa a janela para 400x400
  • Draw: vazio, mas deve existir para o Processing ser interativo para> 1 quadro
  • MousePressed: se clicar com o botão esquerdo, salve as coordenadas do mouse nos números inteiros a e b. Se clicar com o botão direito, meça a distância do ponto (a, b) à posição atual e imprima no console.

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

Imprime a distância entre os últimos cliques (o primeiro imprime a distância de 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

Você pensaria que uma linguagem criada especificamente para capturar e simular ações de teclado e mouse seria mais eficiente nesse desafio ...

Isso cria uma janela com uma caixa de texto de 400 x 400 pixels com uma borda para torná-la óbvia. Sem a borda, há um espaço ao redor da borda que está na janela, mas fora da caixa de texto e você não sabe. Adicionar uma borda era a maneira mais curta de diferenciá-las. A gCopção permite executar a sub-rotina Csempre que você clica na caixa de texto. A sequência de comandos é, portanto, clique esquerdo, seguida por um clique esquerdo diferente.

Encontrei outra solução com 144 bytes, mas que permite cliques em toda a tela, em vez de apenas na "tela óbvia". Também é irritante terminar porque os cliques esquerdo e direito são capturados e não terminam quando você fecha a 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)

O TigerJython vem com um tamanho padrão de tela (800x, 600y).

Isso gera uma imagem temporária de tartaruga para cada ponto de 'início' clicado, que desaparece após o próximo ponto de 'início' ser selecionado. Esse comportamento é aprovado pelo 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

Usa a tela de toque para 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();}}

Aqui está uma solução Java que usa um método AWT descontinuado mouseDownque você precisaria pesquisar profundamente na API para encontrar. Eu só sei disso por causa do curso de programação que fiz no segundo ano do ensino médio, e um dos projetos era fazer um pequeno programa de pintura usando esse método e métodos similares. Eu nunca pensei que teria um bom motivo para usá-lo até agora.


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}

insira a descrição da imagem aqui

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.