Кратчайшее расстояние между двумя точками - это линия


27

Код программы или функции для создания интерактивного холста на экране размером не менее 400 пикселей х 400 пикселей. Холст может быть любого цвета, по вашему желанию, с рамкой или без рамки, с заголовком или без него и т. Д., Только в некоторой форме очевидного холста.

Пользователь щелкает две отдельные области холста, и программа должна каким-то образом выводить евклидово расстояние (в пикселях) между этими двумя щелчками (STDOUT, отображение предупреждения и т. Д.). Два щелчка могут быть только левыми щелчками, только правыми щелчками, левым щелчком для первого и правым щелчком для второго, двумя двойными левыми щелчками и т. Д., Любая комбинация является приемлемой. Специальное примечание: клики и перетаскивания (например, с использованием MOUSEUP в качестве второй точки) специально не допускаются; они должны быть двух разных кликов.

Пользователь должен иметь возможность делать это несколько раз и каждый раз получать выходные данные, пока программа не будет закрыта / принудительно завершена / уничтожена / и т. Д. Вы можете выбрать метод закрытия (нажав X, Ctrl-C и т. Д.), Независимо от того, что лучше для вашего кода.

правила

  • Допустимы либо полная программа, либо функция. Если функция, тем не менее, вы все равно должны каким-то образом отображать вывод для пользователя (просто возвращать значение недопустимо).
  • Вывод может быть на консоль, отображаться как предупреждение, заполняться на холсте и т. Д.
  • Стандартные лазейки запрещены.
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).

Можем ли мы вывести точные результаты (которые могут содержать квадратные корни) или они должны быть десятичными?
Мартин Эндер

@MartinEnder Либо /, либо. Форматирование вывода не является интересной частью этой проблемы.
AdmBorkBork

1
Решение HTML / JS, начиная со второго клика, выводит расстояние от этого клика до предыдущего клика. (так, если пользователь щелкает nвремя n-1вместо floor(n/2)цифр) Это разрешено?
user202729

@ user202729 Это немного за пределами того, что я предполагал, но я вижу, как это соответствует правилам, которые я написал выше, поэтому я позволю это.
AdmBorkBork

1
Можем ли мы использовать меньший размер холста, если наш язык не поддерживает холст 400 x 400?
Скотт Милнер

Ответы:


8

LOGO ( 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единственный способ запустить шаблон в Logo, []это список аргументов, для которого шаблон не получает ни одного.


Как это гарантирует минимальный холст 400x400?
Дэвид Малдер

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.
Мартин Эндер

6

Ява 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 Я не знаю, как ОП хочет вывод для нескольких результатов
Роберто Грэхем

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 байтов с использованием AWT благодаря Кевину Круйссену
-44 байта с использованием блока инициализации; разработан независимо от Роберто Грэма, хотя теперь я вижу, что они делали одно и то же, я думаю, что
-6 байтов объединяют несколько объявлений благодаря
байту Kevin -11, используя байты interfaceKevin
-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чтобы выбрать точку, и наименьшее движение составляет ~ 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 no 8^2(8 в квадрате) равно 64 и меньше 400. Я сказал (8 в кубе), что больше 400 и использует два токена, по одному байту каждый: 8и ³.
kamoroso94

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 байт

Мы можем сохранить 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 байт

Изменить : с дополнительными 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
  • Draw: пусто, но должно существовать, чтобы обработка была интерактивной для> 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 х 400 пикселей с рамкой, чтобы сделать его очевидным. Без рамки есть пространство вокруг края, которое находится в окне, но за пределами текстового поля, и вы не можете сказать. Добавление границы было самым коротким способом их дифференциации. gCВариант сделать его запустить подпрограмму Cвсякий раз , когда вы щелкаете на текстовом поле. Последовательность команд, следовательно, левый щелчок, за которым следует другой левый щелчок.

Я нашел другое решение размером 144 байта, но оно позволяет щелкать по всему экрану, а не на «очевидном холсте». Конец также раздражает, потому что фиксируются как левые, так и правые щелчки, и он не заканчивается, когда вы закрываете графический интерфейс.

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).

Это порождает временное изображение черепахи для каждой точки начала нажатия, которое исчезает после выбора следующей точки начала. Такое поведение одобрено ФП.


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}

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.