来自两个点(x,y)的线性函数求解器


10

任务

编写一个函数L(),该函数采用两个(x,y)形式的两个Tuple参数作为坐标,并以(a,c)形式返回它们各自的线性函数,其中a是x项和c的系数是y截距。

您可以假定输入将不是垂直于x轴的线,并且两个输入是单独的点。

计分 

这就是Code Golf:最短的程序获胜。

请注意:除了基本运算符(+,-,/,*)外,请勿使用任何数学函数。

这是我在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)

输出:

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

4
L( (0,0) , (0,1) )
霍华德

1
您可以假定输入不是平行于X轴的线。
哈里·比德尔2014年

2
您可以假定输入不是平行于X轴的线。您是说Y轴吗?
霍华德

抱歉,帖子上的编辑是正确的,垂直于X轴。
哈里·比德尔2014年

2
L((0,0),(0,0))
user12205 2014年

Answers:


1

J-23个字符

非常坦率的。定义L要用作的二元动词(x1,y1) L (x2,y2)

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

说明:

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

例子:

   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

7

GNU dc30 24字节

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

定义一个宏,以便在调用之前L(x 1,y 1,x 2,y 2)应按此顺序推入堆栈,在调用之后L,(a,c)可以从堆栈中弹出(顺序与之相反)当然-这是一个堆栈)。

测试用例(另存为“ linear.dc”并运行dc linear.dc):

[sysxly-rlx- / dlx * lyr-] sL#定义L宏

10#将x1推入堆栈
22.5#将y1推入堆栈
5#将x2推入堆栈
12.5#将y2推入堆栈

lLx#调用L宏
f#转储堆栈

输出为:

$ dc linear.dc 
2.5
2
$ 

L宏的说明:

  • sy弹出y 2进行y注册
  • sx弹出x 2进行x注册
  • lyy寄存器(y 2
  • -从y 1减去y 2
  • r交换(y 1 -y 2)和x 1在堆栈上
  • lx推入x寄存器(x 2
  • -从x 1减去x 2
  • /将(y 1 -y 2)除以(x 1 -x 2)得到梯度
  • d 重复渐变
  • lx推入x寄存器(x 2
  • *将(x 2)乘以梯度
  • lyy寄存器(y 2
  • r在堆栈上交换(y 2)和(x 2 *渐变)
  • -从(y 2)减去(x 2 *梯度)

1
谢谢,还不错。我承认遭到殴打。;)
Martin Ender 2014年

1
@ m.buettner重新搜索并重新解释。
Digital Trauma 2014年

5

Haskell,41个字符

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

在这里打高尔夫球不是很多。通常,这是您要写的减去空白的内容。


4

Mathematica,55 38字节

这是令人惊讶的长(那些讨厌的长函数名...) 编辑:更改了轴截距的方法(从OP自己的答案中获得了一些启发)。事实证明,直接计算并不是最聪明的主意。

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

使用方式

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

借助Mathematica,您还可以获得以下一般结果:

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

(最后一个示例显示了我最初是如何实现的。)

仅作记录

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

从技术上讲这是正确的。


啊,太棒了,我有点头脑黑了,我把这归咎于我的疲倦
哈里·比德尔2014年

1
+1。为什么ComplexInfinity又不老Infinity呢?(我不知道Mathematica)
数字创伤2014年

3
@DigitalTrauma我认为这是因为,在没有明确告知Mathematica可以在实数中工作的情况下,它总是假设所讨论的空间为复数,以免丢弃实方程的复杂解。
马丁·恩德

2

JavaScript,62 48

感谢@Michael用ES 6打高尔夫球。

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

旧版:

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

输入样例:

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

样本输出:

[0.14285714285714285, 0]

作为记录:

L([0,0],[0,1])
[Infinity, NaN]

46使用ES6:L=(a,b)=>[g=(p=a[1]-b[1])/(q=a[0]-b[0]),p-g*q]
Michael M.

@迈克尔酷 我有点像JS新手,所以我不知道您能做到。谢谢。
user12205 2014年

@ m.buettner你说得对...已修复
user12205 2014年

1
现在,所有答案都恰好相隔十个字符。:D
马丁·恩德

1
Awww。兔子变了!
贾斯汀

2

Python3(51)

def L(p,q):x,y=p;X,Y=q;m=(Y-y)/(X-x);return m,y-x*m

2

C#105字节

这不仅是功能,而且可以完全自己编译。我已经LSystem名称空间中放入了简短的用法,但是最好完全限定名称并节省使用名称空间的时间。保存了括号。还可以节省return new z[]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]};}}

(c*a[0])必要吗?您不能消除这些括号并节省2个字节吗?
Kyle Kanos 2014年

@KyleKanos是的,谢谢。尽管c#不使用BODMAS,但乘法将首先完成(我认为)。
内森·库珀

我想说您必须包括该namespace声明,或将其更改为System.Single,此解决方案才有效。
Tim S.

1

Lua 5.1.4:66 64字节

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

用法示例:

> 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

1

C ++ 88(原为106)

改进:感谢您的评论。

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;}

打高尔夫球:

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;}

资源

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;
}

我看到一个不必要的空间;)
马丁·恩德

1
如果是C ++,为什么typedef
dyp

另外,我认为您可以摆脱zu.x=(v.y-u.y)/(v.x-u.x); u.y=v.y-z.x*v.x; return u;
dyp 2014年

1

苹果Swift 95 86

这可能是PCG.SE上的第一个Swift条目?

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

我认为该语言不会对Code Golf社区产生太大的影响。


0

Golfscript:25个字节

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

由于该函数需要命名为“ L”,因此我在本地将其另存为“ L.gs”。

@Dennis在这篇文章中解释的问题是,我们需要欺骗Golfscript使用有理数而不是整数。因此,如果您愿意接受golfscript表示法的输入X1 Y1 X2 Y2 ,则此方法有效

# 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

0

Ruby-48个字符

与JavaScript答案几乎相同:

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

0

Python3 - 64个 57字节

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

如果您不使用Tuple,则可以将其降至43,这是很多人正在做的...

def L(x,y,q,w):a=(x-q)/(y-w);return a,y-a*x

return(a,q[1]-a*q[0])
user12205 2014年

@ace谢谢,这很草率
哈里·比德尔

0

PHP(75个字符)

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

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

输出:

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

(感谢@ace)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.