10
\$\begingroup\$

The Task

Write a function L() that takes two Tuple arguments of coordinates in the form (x, y), and returns their respective linear function in the form (a, c), where a is the co-efficent of the x term and c is the y-intercept.

You can assume that the input will not be a line perpendicular the the x axis, and that the two inputs are separate points.

Scoring 

This is Code Golf: shortest program wins.

Please Note: No use of any mathematical functions apart from basic operators (+,-,/,*).

Example

Here is my un-golfed solution in Python.

def L(Point1, Point2):
    x = 0
    y = 1
    Gradient = (float(Point1[y]) - float(Point2[y])) / (float(Point1[x]) - float(Point2[x]))
    YIntercept = Point1[y] - Gradient * Point1[x] 
    return (Gradient, YIntercept)

Output:

>>> L( (0,0) , (1,1) )
(1.0, 0.0)

>>> L( (0,0) , (2,1) )
(0.5, 0.0)

>>> L( (0,0) , (7,1) )
(0.14285714285714285, 0.0)

>>> L( (10,22.5) , (5,12.5) )
(2.0, 2.5)
\$\endgroup\$
8
  • 4
    \$\begingroup\$ L( (0,0) , (0,1) )? \$\endgroup\$
    – Howard
    May 12, 2014 at 12:57
  • 1
    \$\begingroup\$ You can assume that the input is not a line parallel to the X axis. \$\endgroup\$ May 12, 2014 at 13:25
  • 2
    \$\begingroup\$ You can assume that the input is not a line parallel to the X axis. Do you mean Y axis? \$\endgroup\$
    – Howard
    May 12, 2014 at 13:53
  • \$\begingroup\$ Sorry, the edit on the post was correct, perpendicular to the X axis. \$\endgroup\$ May 12, 2014 at 13:55
  • 2
    \$\begingroup\$ L((0,0),(0,0))? \$\endgroup\$
    – user12205
    May 12, 2014 at 13:58

14 Answers 14

7
\$\begingroup\$

GNU dc, 30 24 bytes

[sysxly-rlx-/dlx*lyr-]sL

Defines a macro L such that (x1, y1, x2, y2) should be pushed to the stack in that order before calling, and after calling L, (a, c) may be popped from the stack (in reverse order of course - it is a stack).

Testcase (save as "linear.dc" and run dc linear.dc):

[sysxly-rlx-/dlx*lyr-]sL   # Define L macro

10                         # Push x1 to the stack
22.5                       # Push y1 to the stack
5                          # Push x2 to the stack
12.5                       # Push y2 to the stack

lLx                        # Call L macro
f                          # Dump the stack

Output is:

$ dc linear.dc 
2.5
2
$ 

Explanation of L macro:

  • sy pop y2 to y register
  • sx pop x2 to x register
  • ly push y register (y2)
  • - subtract y2 from y1
  • r swap (y1 - y2) and x1 on stack
  • lx push x register (x2)
  • - subtract x2 from x1
  • / divide (y1 - y2) by (x1 - x2) to get gradient
  • d duplicate gradient
  • lx push x register (x2)
  • * multiply (x2) by gradient
  • ly push y register (y2)
  • r swap (y2) and (x2 * gradient) on stack
  • - subtract (x2 * gradient) from (y2)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Thanks, not bad. I admit to being beaten. ;) \$\endgroup\$ May 12, 2014 at 18:11
  • 1
    \$\begingroup\$ @m.buettner Re-golfed and re-explained. \$\endgroup\$ May 12, 2014 at 22:27
5
\$\begingroup\$

Haskell, 41 characters

f(x,y)(u,v)=(a,y-a*x)where a=(y-v)/(x-u)

Not a lot to golf here. It's pretty much what you'd write normally minus whitespace.

\$\endgroup\$
4
\$\begingroup\$

Mathematica, 55 38 bytes

This was surprisingly long (those pesky long function names...) EDIT: Changed the approach for the axis intercept (taking some inspiration from the OP's own answer). It turns out calculating it directly wasn't the most clever idea.

L={g=1/Divide@@(#2-#),#[[2]]-g#[[1]]}&

Use like

L[{10,22.5},{5,12.5}]
> {2., 2.5}

Thanks to Mathematica you can also obtain the general result:

L[{r,s},{p,q}]
> {(p - r)/(q - s), (q r - p s)/(q - s)}

(This last example shows how I had originally implemented this.)

Just for the record

L[{0,0},{0,1}]
> {ComplexInfinity, Indeterminate}

which is technically correct.

\$\endgroup\$
3
  • \$\begingroup\$ Ahh, Awesome, I had a bit of a mind black figuring that out, I'll blame it on my tiredness \$\endgroup\$ May 12, 2014 at 13:40
  • 1
    \$\begingroup\$ +1. Why ComplexInfinity and not plain old Infinity? (I don't know Mathematica) \$\endgroup\$ May 12, 2014 at 23:39
  • 3
    \$\begingroup\$ @DigitalTrauma I think it's because, without explicitly telling Mathematica that it can work in reals, it always assumes the the space in question to be complex numbers, so as not to throw away complex solutions of real equations. \$\endgroup\$ May 13, 2014 at 0:08
2
\$\begingroup\$

JavaScript, 62 48

Thanks to @Michael for golfing it down with ES 6.

L=(a,b)=>[s=(b[1]-a[1])/(b[0]-a[0]),a[1]-s*a[0]]

Old version:

function L(a,b){return[s=(b[1]-a[1])/(b[0]-a[0]),a[1]-s*a[0]]}

Sample input:

L([0,0],[7,1])

Sample output:

[0.14285714285714285, 0]

For the record:

L([0,0],[0,1])
[Infinity, NaN]
\$\endgroup\$
5
  • \$\begingroup\$ 46 using ES6 : L=(a,b)=>[g=(p=a[1]-b[1])/(q=a[0]-b[0]),p-g*q] \$\endgroup\$
    – Michael M.
    May 12, 2014 at 14:37
  • \$\begingroup\$ @Michael Cool. I am sort of a JS newbie, so I didn't know you could do that. Thanks. \$\endgroup\$
    – user12205
    May 12, 2014 at 15:03
  • \$\begingroup\$ @m.buettner You're right... Fixed \$\endgroup\$
    – user12205
    May 12, 2014 at 15:33
  • 1
    \$\begingroup\$ Now all answers are exactly ten characters apart. :D \$\endgroup\$ May 12, 2014 at 15:35
  • 1
    \$\begingroup\$ Awww. The bunny changed! \$\endgroup\$
    – Justin
    May 12, 2014 at 16:56
2
\$\begingroup\$

Python3 (51)

def L(p,q):x,y=p;X,Y=q;m=(Y-y)/(X-x);return m,y-x*m
\$\endgroup\$
2
\$\begingroup\$

C# 105 bytes

This is isn't just the function and will compile completely on it's own. I had put L in the System namespace to shorting the using, but it's better to fully qualify and save on using a namespace. Saved the brackets. Also a saving from return new z[] into return new[]

using z=System.Single;class P{z[] L(z[]a,z[]b){z c=(a[1]-b[1])/(a[0]-b[0]);return new[]{c,a[1]-c*a[0]};}}
\$\endgroup\$
3
  • \$\begingroup\$ Is (c*a[0]) necessary? Can't you eliminate those parenthesis and save 2 bytes? \$\endgroup\$
    – Kyle Kanos
    May 12, 2014 at 16:16
  • \$\begingroup\$ @KyleKanos Yes, thanks. While c# doesn't use BODMAS the multiplication will be done first (I think). \$\endgroup\$
    – Nathan
    May 12, 2014 at 16:19
  • \$\begingroup\$ I'd say you have to include the namespace declaration, or change it to System.Single, for this solution to be valid. \$\endgroup\$
    – Tim S.
    May 12, 2014 at 20:03
1
\$\begingroup\$

J - 23 char

Fairly straightforward. Defines a dyadic verb L to be used as (x1,y1) L (x2,y2).

L=:%~/@:-,-/@(*|.)%-&{.

Explanation:

L=:%~/@:-,-/@(*|.)%-&{.  NB. the function L
                    &{.  NB. x coord of both points
                   -     NB. left x minus right x
             ( |.)       NB. flip right argument: (y2,x2)
              *          NB. pointwise multiplication of (x1,y1) and (y2,x2)
          -/@            NB. subtract the two results: (x1*y2)-(y1*x2)
                  %      NB. divide: (x1*y2 - y1*x2)/(x1-x2)
        -                NB. pointwise subtraction
   %~/@:                 NB. divide y difference by x diff: (y1-y2)/(x1-x2)
         ,               NB. append results together
L=:                      NB. assign function to L

Examples:

   L=:%~/@:-,-/@(*|.)%-&{.
   0 0 L 1 1
1 0
   0 0 L 2 1
0.5 0
   0 0 L 7 1
0.142857 0
   10 22.5 L 5 12.5
2 2.5
   0 0 L 0 1  NB. __ is negative infinity
__ 0
\$\endgroup\$
1
\$\begingroup\$

Lua 5.1.4: 66 64 bytes

function L(q,w)a=(q[2]-w[2])/(q[1]-w[1])return a,q[2]-a*q[1];end

Example Usage:

> print(L( {0,0}, {1,0} ))
-0   0
> print(L( {0,0}, {1,1} ))
1    0
> print(L( {0,0}, {7,1} ))
0.14285714285714    0
> print(L( {0,0}, {0,1} ))
-inf   -nan
> print(L( {0,0}, {0,0} ))
-nan   -nan
\$\endgroup\$
1
\$\begingroup\$

C++ 88 (was 106)

Improved: thanks for your comments.

struct t{double x,y;};
t L(t u, t v){u.x=(v.y-u.y)/(v.x-u.x);u.y=v.y-u.x*v.x;return u;}

Golfed:

typedef struct T{double x,y;}t;
t line(t u, t v){t z;z.x=(v.y-u.y)/(v.x-u.x);z.y=v.y-(z.x*v.x);return z;}

Source

typedef struct T{
    double x,y;
} t;

t line(t u, t v)
{
t z;
z.x=(v.y-u.y)/(v.x-u.x);
z.y=v.y-(z.x*v.x);
return z;
}
\$\endgroup\$
3
  • \$\begingroup\$ I see an unnecessary space ;) \$\endgroup\$ May 12, 2014 at 20:22
  • 1
    \$\begingroup\$ If it is C++, why the typedef? \$\endgroup\$
    – dyp
    May 12, 2014 at 22:42
  • \$\begingroup\$ Also, I think you can get rid of z: u.x=(v.y-u.y)/(v.x-u.x); u.y=v.y-z.x*v.x; return u; \$\endgroup\$
    – dyp
    May 12, 2014 at 22:45
1
\$\begingroup\$

Apple Swift 95 86

This may be the first Swift entry on PCG.SE??

func L(x:Float...)->(Float,Float){var a=(x[3]-x[1])/(x[2]-x[0]);return(a,x[1]-a*x[0])}

I don't see this language being a huge hit to the Code Golf community.

\$\endgroup\$
0
\$\begingroup\$

Golfscript: 25 bytes

~:y\:x;-\x--1?*.x-1**y+\p

Since the function needs to be named 'L', I saved it as 'L.gs' locally.

The catch, as explained by @Dennis in this post, is that we need to trick Golfscript into using rational numbers instead of integers. So this works if you're willing to accept input X1 Y1 X2 Y2 in golfscript notation

# L( (0,0) , (1,1) )
echo "0 0 1 1" | golfscript L.gs
> 1/1
> 0/1
#L( (10,22.5) , (5,12.5) )
echo "10 22 2-1?+ 5 12 2-1?+" | golfscript L.gs
> 2/1
> 5/2
\$\endgroup\$
0
\$\begingroup\$

Ruby – 48 characters

Nearly identical to the JavaScript answer:

L=->u,v{a,b,c,d=*u,*v;[s=(d-b).fdiv(c-a),b-s*a]}
\$\endgroup\$
0
\$\begingroup\$

Python3 - 64 57 Bytes

def L(q,w):a=(q[1]-w[1])/(q[0]-w[0]);return a,q[1]-a*q[0]

You can get it down to 43 if you don't use Tuple, which many people are doing...

def L(x,y,q,w):a=(x-q)/(y-w);return a,y-a*x
\$\endgroup\$
2
  • \$\begingroup\$ return(a,q[1]-a*q[0]) \$\endgroup\$
    – user12205
    May 12, 2014 at 13:42
  • \$\begingroup\$ @ace Thanks, that was sloppy \$\endgroup\$ May 12, 2014 at 13:45
0
\$\begingroup\$

PHP (75 chars)

function L($u,$v){return[$s=($v[1]-$u[1])/($v[0]-$u[0]),$v[1]-($s*$v[0])];}

test : print_r(L([0,0],[7,1]));

output :

Array
(
    [0] => 0.14285714285714
    [1] => 0
)

(thanks @ace)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.