Чи перетинаються кола?


21

Враховуючи координати центрів та радіуси 2-х кіл, виведіть просте значення того, чи вони перетинаються, чи не перетинаються.

Вхідні дані

  • Введення може прийматися через STDIN або еквівалентні аргументи функції, але не як змінна. Ви можете приймати їх як єдину змінну (список, рядок тощо) або як декілька входів / аргументів у будь-якому порядку.

  • Вхід складе шість плавців. Ці поплавці матимуть до 3 знаків після коми. Координати можуть бути позитивними чи негативними. Радіуси будуть позитивними.

Вихідні дані

  • Вихід може бути через STDOUT або повернення функції.

  • У програмі повинно бути рівно два різних виходи - один для значення True (кола не перекриваються) і один для False output (вони не перетинаються).

Тестові кейси

(Введення подано у вигляді списку кортежів [(x1, y1, r1), (x2, y2, r2)]для тестових випадків; ви можете взяти дані у будь-якому форматі)

Правда

[(5.86, 3.92, 1.670), (11.8, 2.98, 4.571)]
[(8.26, -2.72, 2.488), (4.59, -2.97, 1.345)]
[(9.32, -7.77, 2.8), (6.21, -8.51, 0.4)]

помилковий

[(4.59, -2.97, 1.345), (11.8, 2.98, 4.571)]
[(9.32, -7.77, 2.8), (4.59, -2.97, 1.345)]
[(5.86, 3.92, 1.670), (6.21, -8.51, 0.4)]

Це Код Гольф, найкоротша відповідь у виграші байтів.


4
Що нам потрібно повернути, якщо два кола торкаються зовні?
JungHwan Min

6
Технічний термін "дотику, але не перекриття" є "дотичним", і це геометрія, якщо ніде більше.
dmckee

2
Захоплення плавців здається досить жорсткою вимогою. Не могли б ви розслабити це для більш загального уявлення? Я хотів би вирішити це в Brain-Flak, але я навряд чи знайду час для впровадження IEEE поплавців, і якби я це зробив, це все одно складе 90% від кількості байтів, тож я просто би займався реалізацією поплавків.
Пшеничний майстер

4
Я також хотів би зазначити, що поплавці не є точними до "трьох знаків після коми" у багатьох випадках. Я не впевнений, що саме ти хочеш відповісти, але це зараз трохи заплутано.
Пшеничний майстер

2
Я думаю, у вас може виникнути принципове непорозуміння того, як працюють поплавки. Оскільки вони мають фіксований розмір, оскільки значення збільшуються, точність стає нижчою. Існує точка, за якою поплавок не може точно представити всі значення в межах 3 десяткових знаків. Також редагування виклику для видалення зайвого обмеження не перешкоджає.
Мего

Відповіді:


18

Желе , 5 байт

IA<S}

В якості першого аргументу береться два складних числа (центри), а два дійсні числа (радіуси) як другий аргумент.

Спробуйте в Інтернеті!

Як це працює

IA<S}  Main link.
       Left argument:  [x1 + iy1, x2 + iy2]
       Right argument: [r1, r2]

I      Increments; yield (x2 - x1) + i(y2 - y1).
 A     Absolute value; yield √((x2 - x1)² + (y2 - y1)²).
   S}  Take the sum of the right argument, yielding r1 + r2.
  <    Compare the results.

Чорт, я забув про використання складних чисел для координат. Хороший! : D
HyperNeutrino

Нецікавим, чи Aслід вважати результатом тут норму вектору рядків "центри"? ( ÆḊсама помилка зі складним змістом.)
Джонатан Аллан

1
@JonathanAllan Так, Aобчислює відстані центрів як норму їх різницького вектора.
Денніс

11

JavaScript (ES6), 38 байт

Приймає вхід як 6 різних змінних x1 , y1 , r1 , x2 , y2 , r2 .

(x,y,r,X,Y,R)=>Math.hypot(x-X,y-Y)<r+R

Тестові кейси


Для тих, хто раніше не здався Math.hypot .
Pureferret


@ V.Courtois Спосіб передачі параметрів не відповідає декларації методу. Це повинно бути a:Double,x:Double,b:Double,y:Double,r:Double,q:Double.
Арнольд

1
@Arnauld ooh ~ спасибі! Чи слід публікувати його окремо?
В. Куртуа

@ V.Courtois Sure. Дій!
Арнольд


7

MATL , 5 байт

ZPis<

Формат введення:

[x1, y1]
[x2, y2]
[r1, r2]

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Як це працює

ZP   % Take two vectors as input. Push their Euclidean distance
i    % Input the vector of radii
s    % Sum of vector
<    % Less than?

Не впевнений, чи це я, але коли я використовую ваше пробне посилання та натискаю запуск, я отримую "Помилка Відповідь сервера не вдалося розшифрувати" - Також не впевнений, чи допомагає це, але ви думали про (аби) використання складних чисел у відповіді Желе?
Денніс Джахеруддін

@DennisJaheruddin Ей, приємно бачити тебе знову тут! (1) Мабуть, звинувачуйте кешування. Ви спробували жорстке оновлення? (2) Я, але думаю, що це також 5байти ( -|замість ZP)
Луїс Мендо

Я припускаю, що це брандмауер. Тепер мені цікаво, чи допоможе формат введення з чимось на зразок -r2замість того r2, що тоді вам знадобляться три відмінності, а не 2 відмінності та доповнення ... Я б краще пробігти, перш ніж я затягнуться занадто глибоко!
Денніс Джахеруддін

Я не вважаю, що заперечення одного вводу є прийнятним як формат введення. Якщо у вас виникли проблеми із послугою "Спробуйте онлайн", ви можете повідомити тут ?
Луїс Мендо

6

R , 39 байт

function(k,r)dist(matrix(k,2,2))<sum(r)

приймає вхід k=c(x1,x2,y1,y2) і r=c(r1,r2); повертаєFALSE для дотичних кіл.

Спробуйте в Інтернеті!

27 байт:

function(m,r)dist(m)<sum(r)

Вводиться як матриця з центрами кіл, заданими у вигляді рядків та вектора радіусів.

Спробуйте в Інтернеті!


-2 байтfunction(k,r)dist(matrix(k,2))<sum(r)
djhurio

Про що dist(matrix(scan(),2))<sum(scan())?
djhurio

6

Пітон , 40 байт

lambda x,y,r,X,Y,R:abs(x-X+(y-Y)*1j)<r+R

Спробуйте в Інтернеті!

Використовує складну арифметику Пітона для обчислення відстані між двома центрами. Я припускаю, що ми не можемо приймати точки введення безпосередньо як складні числа, тому код виражає їх як x+y*1j.





4

APL (Dyalog) , 10 байт

Підказки для центрів кіл як список двох складних чисел, потім для радіусів як список двох чисел

(+/⎕)>|-/

Спробуйте в Інтернеті!

(+/⎕) [є] сума радіусів

> більше, ніж, величніше ніж, крутіший за

| величина

-/⎕ різниця центрів


3

Математика, 16 байт

Norm[#-#2]<+##3&

Вхід: [{x1, y1}, {x2, y2}, r1, r2]


У Mathematica є RegionIntersectionвбудований, але один лише 18 байт ...

Вбудована версія:

RegionIntersection@##==EmptyRegion@2&

Бере 2 Diskоб’єкти. [Disk[{x1, y1}, r1], Disk[{x2, y2}, r2]].



3

Желе , 12 байт

I²+⁴I²¤<⁵S²¤

Спробуйте в Інтернеті!

-2 байти завдяки Деннісу


Не створили б нове посилання з ạ/²тими ж байтами?
caird coinheringaahing

@cairdcoinheringaahing?
HyperNeutrino

Неважливо, я отримав 14 байт, роблячи це
caird coinheringaahing

Ви можете використовувати Iзамість зменшення на абсолютну різницю.
Денніс

@Dennis Ooh дякую
HyperNeutrino


3

Java 8, 41 38 байт

(x,y,r,X,Y,R)->Math.hypot(x-X,y-Y)<r+R

Спробуйте тут.

Мабуть, у Java також є Math.hypot, що на 3 байти коротше.

EDIT: Щойно зрозумів, що ця відповідь зараз точно така ж, як і відповідь Java 8 @ OlivierGrégoire , тому, будь ласка, підкажіть його замість мене, якщо вам подобається відповідь на 38 байтів.

Стара відповідь (41 байт) :

(x,y,r,X,Y,R)->(x-=X)*x+(y-=Y)*y<(r+=R)*r

Спробуйте тут.


1
Ой! Тож тому я сьогодні отримав 3 оновлення, але 0, коли було опубліковано виклик? ^^ Мені було цікаво, що спричинило цю дивну поведінку;) Оскільки мені подобається моя відповідь, і ви опублікували те саме, ви отримуєте +1 також! : p
Олів’є Грегоар


2

Perl 6 , 13 байт

*+*>(*-*).abs

Спробуйте в Інтернеті!

Перші два аргументи - це радіуси в будь-якому порядку. Третій і четвертий аргументи - це координати центрів, як складні числа, в будь-якому порядку.


2

Таксі , 1582 байт

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to The Babelfishery.Pickup a passenger going to Tom's Trims.Pickup a passenger going to Tom's Trims.Go to Tom's Trims:n.[a]Go to Post Office:s.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:s 1 l 1 r.Pickup a passenger going to What's The Difference.Pickup a passenger going to What's The Difference.Go to What's The Difference:n 5 l.Pickup a passenger going to Cyclone.Go to Cyclone:e 1 r.Pickup a passenger going to Multiplication Station.Pickup a passenger going to Multiplication Station.Go to Multiplication Station:s 1 l 2 r 4 l.Pickup a passenger going to Addition Alley.Go to Tom's Trims:s 1 r 3 r.Pickup a passenger going to The Babelfishery.Switch to plan "b" if no one is waiting.Switch to plan "a".[b]Go to Addition Alley:n 1 r 1 l 3 l 1 l.Pickup a passenger going to Magic Eight.Go to Post Office:n 1 r 1 r 3 r 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:s 1 l 1 r.Pickup a passenger going to Addition Alley.Pickup a passenger going to Addition Alley.Go to Addition Alley:n 5 l 1 l.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Multiplication Station.Pickup a passenger going to Multiplication Station.Go to Multiplication Station:s 1 l 2 r 4 l.Pickup a passenger going to Magic Eight.Go to Magic Eight:s 1 r.Switch to plan "c" if no one is waiting.'1' is waiting at Writer's Depot.[c]'0' is waiting at Writer's Depot.Go to Writer's Depot:w 1 l 2 l.Pickup a passenger going to Post Office.Go to Post Office:n 1 r 2 r 1 l.

Спробуйте в Інтернеті!

Виходи 1для кіл, що перекриваються.
Виводи 0для кіл, що не перекриваються (включаючи тангенціальні кола).

Недозволений / відформатований:

Go to Post Office: west 1st left 1st right 1st left.
Pickup a passenger going to The Babelfishery.
Pickup a passenger going to Tom's Trims.
Pickup a passenger going to Tom's Trims.
Go to Tom's Trims: north.
[a]
Go to Post Office: south.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: south 1st left 1st right.
Pickup a passenger going to What's The Difference.
Pickup a passenger going to What's The Difference.
Go to What's The Difference: north 5th left.
Pickup a passenger going to Cyclone.
Go to Cyclone: east 1st right.
Pickup a passenger going to Multiplication Station.
Pickup a passenger going to Multiplication Station.
Go to Multiplication Station: south 1st left 2nd right 4th left.
Pickup a passenger going to Addition Alley.
Go to Tom's Trims: south 1st right 3rd right.
Pickup a passenger going to The Babelfishery.
Switch to plan "b" if no one is waiting.
Switch to plan "a".
[b]
Go to Addition Alley: north 1st right 1st left 3rd left 1st left.
Pickup a passenger going to Magic Eight.
Go to Post Office: north 1st right 1st right 3rd right 1st left.
Pickup a passenger going to The Babelfishery.
Go to The Babelfishery: south 1st left 1st right.
Pickup a passenger going to Addition Alley.
Pickup a passenger going to Addition Alley.
Go to Addition Alley: north 5th left 1st left.
Pickup a passenger going to Cyclone.
Go to Cyclone: north 1st left 1st left.
Pickup a passenger going to Multiplication Station.
Pickup a passenger going to Multiplication Station.
Go to Multiplication Station: south 1st left 2nd right 4th left.
Pickup a passenger going to Magic Eight.
Go to Magic Eight: south 1st right.
Switch to plan "c" if no one is waiting.
'1' is waiting at Writer's Depot.
[c]
'0' is waiting at Writer's Depot.
Go to Writer's Depot: west 1st left 2nd left.
Pickup a passenger going to Post Office.
Go to Post Office: north 1st right 2nd right 1st left.

2

C #, 50 41 байт

(x,y,r,X,Y,R)=>(x-=X)*x+(y-=Y)*y<(r+=R)*r

Збережено 9 байт завдяки @KevinCruijssen.


Ви не можете зберегти кілька байт там, написавши (r+R)*2замість (r+R)+(r+R)?
Ян Х.

@IanH. Так, не знаю, як я це пропустив.
TheLethalCoder

Am I missing something or does this not work?
Ian H.

@IanH. I'd made a typo, the + on the RHS should have been a *.
TheLethalCoder

And my feedback even made that worse. Good job on the solution though!
Ian H.


1

PostgreSQL, 41 characters

prepare f(circle,circle)as select $1&&$2;

Prepared statement, takes input as 2 parameters in any circle notation.

Sample run:

Tuples only is on.
Output format is unaligned.
psql (9.6.3, server 9.4.8)
Type "help" for help.

psql=# prepare f(circle,circle)as select $1&&$2;
PREPARE

psql=# execute f('5.86, 3.92, 1.670', '11.8, 2.98, 4.571');
t

psql=# execute f('8.26, -2.72, 2.488', '4.59, -2.97, 1.345');
t

psql=# execute f('9.32, -7.77, 2.8', '6.21, -8.51, 0.4');
t

psql=# execute f('4.59, -2.97, 1.345', '11.8, 2.98, 4.571');
f

psql=# execute f('9.32, -7.77, 2.8', '4.59, -2.97, 1.345');
f

psql=# execute f('5.86, 3.92, 1.670', '6.21, -8.51, 0.4');
f

1

Java, 50 38 bytes

(x,y,r,X,Y,R)->Math.hypot(x-X,y-Y)<r+R

Using ideas in other answers, this can be shortened to 38 like so: (x,y,r,X,Y,R)->Math.hypot(x-X,y-Y)<r+R. In fact, just realised this is the exact same as Arnauld's JavaScript answer.
laszlok

Thanks... This answer was nevee intended to be golfed... i thought it was such a simple challenge there wouldn't be anything that can be golfed...
Roman Gräf

I'm afraid your answer is now exactly the same as the already posted answer by @OlivierGrégoire..
Kevin Cruijssen

1

x86 Machine Code (with SSE2), 36 bytes

; bool CirclesOverlap(double x1, double y1, double r1,
;                     double x2, double y2, double r2);
F2 0F 5C C3        subsd   xmm0, xmm3      ; x1 - x2
F2 0F 5C CC        subsd   xmm1, xmm4      ; y1 - y2
F2 0F 58 D5        addsd   xmm2, xmm5      ; r1 + r2
F2 0F 59 C0        mulsd   xmm0, xmm0      ; (x1 - x2)^2
F2 0F 59 C9        mulsd   xmm1, xmm1      ; (y1 - y2)^2
F2 0F 59 D2        mulsd   xmm2, xmm2      ; (r1 + r2)^2
F2 0F 58 C1        addsd   xmm0, xmm1      ; (x1 - x2)^2 + (y1 - y2)^2
66 0F 2F D0        comisd  xmm2, xmm0
0F 97 C0           seta    al              ; ((r1 + r2)^2) > ((x1 - x2)^2 + (y1 - y2)^2)
C3                 ret

The above function accepts descriptions of two circles (x- and y-coordinates of center point and a radius), and returns a Boolean value indicating whether or not they intersect.

It uses a vector calling convention, where the parameters are passed in SIMD registers. On x86-32 and 64-bit Windows, this is the __vectorcall calling convention. On 64-bit Unix/Linux/Gnu, this is the standard System V AMD64 calling convention.

The return value is left in the low byte of EAX, as is standard with all x86 calling conventions.

This code works equally well on 32-bit and 64-bit x86 processors, as long as they support the SSE2 instruction set (which would be Intel Pentium 4 and later, or AMD Athlon 64 and later).

AVX version, still 36 bytes

If you were targeting AVX, you would probably want to add a VEX prefix to the instructions. This does not change the byte count; just the actual bytes used to encode the instructions:

; bool CirclesOverlap(double x1, double y1, double r1,
;                     double x2, double y2, double r2);
C5 FB 5C C3      vsubsd   xmm0, xmm0, xmm3   ; x1 - x2
C5 F3 5C CC      vsubsd   xmm1, xmm1, xmm4   ; y1 - y2
C5 EB 58 D5      vaddsd   xmm2, xmm2, xmm5   ; r1 + r2
C5 FB 59 C0      vmulsd   xmm0, xmm0, xmm0   ; (x1 - x2)^2
C5 F3 59 C9      vmulsd   xmm1, xmm1, xmm1   ; (y1 - y2)^2
C5 EB 59 D2      vmulsd   xmm2, xmm2, xmm2   ; (r1 + r2)^2
C5 FB 58 C1      vaddsd   xmm0, xmm0, xmm1   ; (x1 - x2)^2 + (y1 - y2)^2
C5 F9 2F D0      vcomisd  xmm2, xmm0
0F 97 C0         seta     al                 ; ((r1 + r2)^2) > ((x1 - x2)^2 + (y1 - y2)^2)
C3               ret

AVX instructions have the advantage of taking three operands, allowing you to do non-destructive operations, but that doesn't really help us to compact the code any here. However, mixing instructions with and without VEX prefixes can result in sub-optimal code, so you generally want to stick with all AVX instructions if you're targeting AVX, and in this case, it doesn't even hurt your byte count.



1

PHP, 66 bytes

<?php $i=$argv;echo hypot($i[1]-$i[4],$i[2]-$i[5])<$i[3]+$i[6]?:0;

Try it online!

Runs from the command line, taking input as 6 command-line parameter arguments, and prints 1 if the circles overlap, else 0.



0

Clojure, 68 bytes

#(<(+(*(- %4 %)(- %4 %))(*(- %5 %2)(- %5 %2)))(*(+ %6 %3)(+ %6 %3)))

Takes six arguments: x1, y1, r1, x2, y2, r2. Returns true or false.

Sadly, Clojure does not have a pow function of some sorts. Costs a lot of bytes.


0

Actually, 8 bytes

-)-(h@+>

Try it online!

Explanation:

-)-(h@+>  (implicit input: [y1, y2, x1, x2, r1, r2])
-         y2-y1 ([y2-y1, x1, x2, r1, r2])
 )-       move to bottom, x1-x2 ([x1-x2, r1, r2, y2-y1])
   (h     move from bottom, Euclidean norm ([sqrt((y2-y1)**2+(x2-x1)**2), r1, r2])
     @+   r1+r2 ([r1+r2, norm])
       >  is r1+r2 greater than norm?

0

R (+pryr), 31 bytes

pryr::f(sum((x-y)^2)^.5<sum(r))

Which evaluates to the function

function (x, y, z) 
sum((x - y)^2)^0.5 < sum(z)

Where x are the coordinates of circle 1, y are the coordinates of circle 2 and z the radii.

Calculates the distance between the two centers using Pythagoras and tests if that distance is smaller than the sum of the radii.

Makes use of R's vectorisation to simultaneously calculate (x1-x2)^2 and (y1-y2)^2. These are then summed and squarely rooted.


0

Go, 93 bytes

package q
import c "math/cmplx"
func o(a,b complex128,r,R float64)bool{return c.Abs(b-a)<r+R}

Fairly simple algorithm, same as several other answers, except it uses the built-in complex type and calls math/cmplx.Abs().

Taking the radii as complex numbers doesn't help, because the cast to float64 adds more bytes than the variable declaration saves (can't do float64 < complex128).

Try it online! Includes the test cases, and uses package main instead of a library.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.