Code Golf Asked by Mukundan314 on October 27, 2021
Write a program/function that when given three 2d points in cartesian coordinates as input outputs a truthy value if they are collinear otherwise a falsey value
Three points are said to be collinear if there exists a straight line that passes through all the points
You may assume that the coordinates of the three points are integers and that the three points are distinct.
This is code-golf so shortest bytes wins
(1, 1), (2, 2), (3, 3) -> Truthy
(1, 1), (2, 2), (10, 10) -> Truthy
(10, 1), (10, 2), (10, 3) -> Truthy
(1, 10), (2, 10), (3, 10) -> Truthy
(1, 1), (2, 2), (3, 4) -> Falsey
(1, 1), (2, 0), (2, 2) -> Falsey
(-5, 70), (2, 0), (-1, 30) -> Truthy
(460, 2363), (1127, 2392), (-1334, 2285) -> Truthy
(-789, -215), (-753, -110), (518, -780) -> Falsey
(227816082, 4430300), (121709952, 3976855), (127369710, 4001042) -> Truthy
(641027, 3459466), (475989, 3458761), (-675960, 3453838) -> Falsey
Answered by Razetime on October 27, 2021
{print!($2*$3+$4*$5+$6*$1-$1*$4-$2*$5-$3*$6)}
Near-identical to Rich Farmbrough's Perl answer, but the syntax seemed better-suited to AWK than Perl. Thanks Rich!
Answered by Dominic van Essen on October 27, 2021
sub d{($a,$b,$c,$d,$e,$f)=@_;$b*($c-$e)+$d*($e-$a)+$f*($a-$c)}
I've put the wrapping on as explained in the comments, and golfed the original "guts" down by picking out some common factors
$b*($c-$e)+$d*($e-$a)+$f*($a-$c)
(--First attempt --)
$b*$c+$d*$e+$f*$a-$a*$d-$c*$f-$e*$b
Answered by Rich Farmbrough on October 27, 2021
Answered by Conor James Thomas Warford Hen on October 27, 2021
Answered by Conor James Thomas Warford Hen on October 27, 2021
(a,A,b,B,c,C)=>(b-a)/(B-A)==(c-a)/(C-A)
Answered by Netråm on October 27, 2021
function(x)lm(1:3~x)$d
Finally a challenge which calls for lm
!
The function lm
performs linear regression. Here, we are using the input x
as covariates, and 1 2 3
as observations (any vector of length 3 would do).
The output is an object with many components; of interest here is df.residual
(which can be accessed with the unambiguous abbreviation $d
), the residual degrees of freedom. This number corresponds to the number of observations minus the number of parameters being estimated. Now:
df.residual == 0
.NA
), so df.residual == 1
.Note that the final test case fails due to numerical precision issues.
Answered by Robin Ryder on October 27, 2021
NθNηNζ⁼×⁻ηN⁻θN×⁻ηN⁻θζ
Try it online! Link is to verbose version of code. Takes input as six integers and outputs a Charcoal boolean, i.e. -
for collinear, nothing if not. Uses @SurculoseSputum's original formula. Explanation:
Nθ Input `a`
Nη Input `A`
Nζ Input `b`
η `A`
⁻ Minus
N Input `B`
× Multiplied by
θ `a`
⁻ Minus
N Input `c`
⁼ Equals
η `A`
⁻ Minus
N Input `C`
× Multiplied by
θ `a`
⁻ Minus
ζ `b`
Implicitly print
Answered by Neil on October 27, 2021
0=-/ .*
Uses the determinant. J's generalized determinant u .v
is defined for non-square matrices, still multiplying (*
) each x value with the difference of the other two y values (-/
), finally reducing that result (-/
). -/ .*
calculates the determinant, check if it is 0=
.
Answered by xash on October 27, 2021
Answered by Kirill L. on October 27, 2021
function(p,q=p-p[,1])q[1,3]*q[2,2]==q[2,3]*q[1,2]
How?
Edit:
function(p)!det(p[,-1]-p[,1])
Answered by Dominic van Essen on October 27, 2021
_ÆḊ¬
Takes the differences [(a-b), (a-c)]
via automatic vectorization of a-[b-c]
then checks if the determinant (ÆḊ
) is 0 (¬
).
Answered by fireflame241 on October 27, 2021
Answered by att on October 27, 2021
{!im [/] $^a X-@_:}
Takes input as three complex numbers and returns a boolean. Note that if the last and first points are identical (which is disallowed in the challenge spec), then the division operation would return NaN for dividing by zero, which boolifies to True for some reason, so this would fail.
Answered by Jo King on October 27, 2021
Answered by alephalpha on October 27, 2021
0=11○÷.-
-1 byte thanks to @Jo King.
Takes one complex number (A) on the left, and two complex numbers (B and C) on the right. APL automatically maps scalars, so A - B C
gives (A-B)(A-C)
. Then divide between the two ÷.
, and check if the result's imaginary part 11○
is zero 0=
.
Uses ⎕DIV←1
, so if division by zero would occur (because A=C
), ÷
returns 0 instead, which obviously has imaginary part of zero, giving truthy as a result.
Answered by Bubbler on October 27, 2021
-Dн_iIн¹нQë`s/Uн¹н-X*¹θ+IθQ
-1 byte due to remembering implicit input exists and that variable assignment pops values
+10 due to bug fix regarding vertical lines :-(
-6 thanks to the wonderful @Kevin, who always manages to golf my 05AB1E answers! :D. Go and upvote his posts!
Before we even begin to look at the program, let's take a look at the maths needed to see if three points are collinear. Let our first point have co-ordinates $(x_1, y_1)$, our second point have co-ordinates $(x_2, y_2)$ and our third point have co-ordinates $(x_3, y_3)$.
If the three points are collinear, then point three will lie on the line formed by joining points one and two. In other words, $x_3$, when plugged into the equation formed by the line joining points 1 and 2, gives $y_3$.
"But what's the line between point 1 and 2?" I hear you ask. Well, we use the good old "point-graident" method to find the line's equation:
$$ y - y_1 = m(x - x_1), m = frac{y_2 - y_1}{x_2 - x_1}\ y - y_1 = frac{y_2 - y_1}{x_2 - x_1}(x - x_1) $$
Now, we add $y_1$ to both sides to get an equation where plugging in an x
value gives a single y
value:
$$ y = frac{y_2 - y_1}{x_2 - x_1}(x - x_1) + y_1 $$
Substituting $x$ for $x_3$ and $y$ for $y_3$ gives an equality that determines if three points are collinear.
Alright, time for the code (as explained by Kevin).
- "[x2-x1, y2-y1]"
V "pop and store it in variable `Y`"
¹- "[x3-x1, y3-y1]"
н "Pop and leave only x3-x1"
Yн_i "If x2-x1 from variable `Y` == 0:"
_ " Check if the x3-x1 at the top == 0"
ë "Else:"
Y`s/ " Divide (y2-y1) by (x2-x1) from variable `Y`"
* " Multiply it by the x3-x1 at the top"
¹θ+ " Add x1"
Q " Check [x3 == this value, y3 == this value] with the implicit third input"
θ " And only keep the last one: y3 == this value"
Answered by lyxal on October 27, 2021
lambda a,b,c:(a-b)*(a-c-(a-c)%1*2)%1==0
Input: the 3 points as 3 complex numbers
Output: True or False.
How
Let the 3 points be $(a,A), (b,B), (c,C)$
The 3 points are colinear iff $(a-b)*(A-C)=(A-B)*(a-c)$. Note that this formula doesn't have division, and thus won't have floating point issue. Consider the following complex multiplication: $$ big((a-b)+(A-B)ibig) * big((a-c)-(A-C)ibig)$$ The imaginary part of the result is: $$(a-c)(A-B)-(a-b)(A-C)$$ which must be $0$ for the 3 points to be colinear.
Let a
, b
, c
be the complex representation of the 3 points, then the condition above is equivalent to:
t = (a-b) * (a-c).conjugate()
t.imag == 0
Instead of using imag
and conjugate
, we can take advantage of the fact that all points are integers. For a complex number t
where both the real and imaginary parts are integers, t%1
gives the imaginary part of t
. Thus:
t % 1 == t.imag * 1j
t - t % 1 * 2 == t.conjugate()
Old solution that doesn't use complex number
lambda a,A,b,B,c,C:(a-b)*(A-C)==(A-B)*(a-c)
Input: the 2 coordinates of the first point, then the 2nd point, then the 3rd point.
Output: True or False.
This should work theoretically, but doesn't because of floating point imprecision:
lambda a,b,c:((a-b)/(a-c)).imag==0
Input: 3 points, each represented by a complex number
Output: True or False.
Answered by Surculose Sputum on October 27, 2021
(a,b,c,d,e,f)=>a*d+c*f+e*b==b*c+d*e+f*a
Accepts input as (x1, y1, x2, y2, x3, y3)
. Uses the shoelace formula to determine if the enclosed area is 0.
The shoelace formula states that, the area of a polygon can be calculated using the coordinates of its vertices. Specifically, assuming the vertices are $P_1, P_2, cdots, P_n$ so that $P_1P_2, P_2P_3, cdots, P_{n-1}P_n, P_nP_1$ are the edges of the polygon, then the area $A$ can be calculated with
$$A=frac{1}{2}left|(x_1y_2+x_2 y_3+cdots+x_{n-1}y_n+x_ny_1)-(y_1x_2+y_2x_3 +cdots+y_{n-1}x_n+y_nx_1)right|$$
where $(x_n,y_n)$ are the coordinates of $P_n$.
Taking $n=3$, we have the formula for the area of a triangle with coordinates $(x_1,y_1)$, $(x_2,y_2)$ and $(x_3,y_3)$:
$$A=frac{1}{2}left|(x_1y_2+x_2y_3+x_3y_1)-(y_1x_2+y_2x_3+y_3x_1)right|$$
Three points are collinear if and only if the triangle constructed by these points has a zero area (otherwise, one of the points lies away from the line segment between the other two points, giving a non-zero area to the triangle). Since we only need to check whether the area is 0, the 1/2 and the absolute can be ignored. This boils down to checking whether
$$(x_1y_2+x_2y_3+x_3y_1)-(y_1x_2+y_2x_3+y_3x_1)=0$$
or after rearranging terms
$$x_1y_2+x_2y_3+x_3y_1=y_1x_2+y_2x_3+y_3x_1$$
Answered by Shieru Asakoto on October 27, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP