Liniowy solver funkcji z dwóch punktów (x, y)

10

Zadanie

Napisz funkcję L (), która pobiera dwa argumenty Tuple o współrzędnych w postaci (x, y) i zwraca ich odpowiednią funkcję liniową w postaci (a, c), gdzie a jest współczynnikiem x składnika i c jest punktem przecięcia y.

Możesz założyć, że wejście nie będzie linią prostopadłą do osi x oraz że dwa wejścia są osobnymi punktami.

Punktacja 

To jest Code Golf: wygrywa najkrótszy program.

Uwaga: Nie używa się żadnych funkcji matematycznych oprócz podstawowych operatorów (+, -, /, *).

Przykład

Oto moje rozwiązanie bez gry w golfa w Pythonie.

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)

Wynik:

>>> 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)
Harry Beadle
źródło
4
L( (0,0) , (0,1) )?
Howard
1
Możesz założyć, że wejście nie jest linią równoległą do osi X.
Harry Beadle
2
Możesz założyć, że wejście nie jest linią równoległą do osi X. Masz na myśli oś Y?
Howard
Przepraszamy, edycja wpisu była poprawna, prostopadła do osi X.
Harry Beadle
2
L((0,0),(0,0))?
user12205

Odpowiedzi:

1

J - 23 char

Dość bezpośredni. Definiuje czasownik dynamiczny, Lktóry będzie używany jako (x1,y1) L (x2,y2).

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

Wyjaśnienie:

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

Przykłady:

   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
algorytmshark
źródło
7

GNU dc , 30 24 bajtów

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

Definiuje makro Ltakie, że (x 1 , y 1 , x 2 , y 2 ) należy wypchnąć na stos w tej kolejności przed wywołaniem, a po wywołaniu L(a, c) może zostać wyskakujący ze stosu (w odwrotnej kolejności oczywiście - jest to stos).

Testcase (zapisz jako „linear.dc” i uruchom dc linear.dc):

[sysxly-rlx- / dlx * lyr-] sL # Zdefiniuj makro L.

10 # Naciśnij x1 na stos
22,5 # Wciśnij y1 na stos
5 # Wciśnij x2 na stos
12,5 # Wciśnij y2 na stos

Makro lLx # Call L.
f # Zrzuć stos

Dane wyjściowe to:

$ dc linear.dc 
2.5
2)
$ 

Objaśnienie makra L:

  • sypop y 2, aby się yzarejestrować
  • sxpop x 2, aby się xzarejestrować
  • lyyrejestr push (y 2 )
  • -odejmij y 2 od y 1
  • rzamień (y 1 - y 2 ) i x 1 na stosie
  • lxxrejestr push (x 2 )
  • -odejmij x 2 od x 1
  • /podziel (y 1 - y 2 ) przez (x 1 - x 2 ), aby uzyskać gradient
  • d zduplikowany gradient
  • lxxrejestr push (x 2 )
  • *pomnóż (x 2 ) przez gradient
  • lyyrejestr push (y 2 )
  • rzamień (y 2 ) i (x 2 * gradient) na stosie
  • -odejmij ( gradient x 2 *) od (y 2 )
Cyfrowa trauma
źródło
1
Dzięki, nieźle. Przyznaję się do bicia. ;)
Martin Ender
1
@ m.buettner Ponownie zagrano w golfa i ponownie wyjaśniono.
Cyfrowa trauma
5

Haskell, 41 znaków

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

Tutaj nie ma wiele do golfa. Jest to w zasadzie to, co piszesz normalnie bez białych znaków.

hammar
źródło
4

Mathematica, 55 38 bajtów

To było zaskakująco długie (te nieznośne długie nazwy funkcji ...) EDYCJA: Zmieniłem podejście do przechwytywania osi (czerpiąc inspirację z własnej odpowiedzi PO). Okazuje się, że bezpośrednie obliczenie tego nie było najmądrzejszym pomysłem.

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

Użyj jak

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

Dzięki Mathematica możesz również uzyskać ogólny wynik:

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

(Ten ostatni przykład pokazuje, jak pierwotnie to zaimplementowałem).

Dla przypomnienia

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

co jest technicznie poprawne.

Martin Ender
źródło
Ahh, Awesome, miałem trochę czarnego umysłu, zastanawiając się nad tym, winię za to moje zmęczenie
Harry Beadle
1
+1. Dlaczego ComplexInfinitynie stary Infinity? (Nie wiem Mathematica)
Cyfrowa trauma
3
@DigitalTrauma Myślę, że dzieje się tak, ponieważ bez wyraźnego mówienia Mathematica, że ​​może on działać na liczbach rzeczywistych, zawsze zakłada, że ​​omawiana przestrzeń jest liczbą zespoloną, aby nie wyrzucać złożonych rozwiązań rzeczywistych równań.
Martin Ender
2

JavaScript, 62 48

Dzięki @Michael za grę w golfa w ES 6.

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

Stara wersja:

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

Przykładowe dane wejściowe:

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

Przykładowe dane wyjściowe:

[0.14285714285714285, 0]

Dla przypomnienia:

L([0,0],[0,1])
[Infinity, NaN]
użytkownik12205
źródło
46 przy użyciu ES6:L=(a,b)=>[g=(p=a[1]-b[1])/(q=a[0]-b[0]),p-g*q]
Michael M.
@Michael Cool. Jestem trochę nowicjuszem JS, więc nie wiedziałem, że możesz to zrobić. Dzięki.
user12205
@ m.buettner Masz rację ... Naprawiono
użytkownik12205
1
Teraz wszystkie odpowiedzi mają dokładnie dziesięć znaków od siebie. : D
Martin Ender
1
Awww. Królik się zmienił!
Justin
2

Python3 (51)

def L(p,q):x,y=p;X,Y=q;m=(Y-y)/(X-x);return m,y-x*m
xnor
źródło
2

C # 105 bajtów

To nie jest tylko funkcja i skompiluje się całkowicie samodzielnie. I włożył LwSystem przestrzeni nazw skrót do użycia, ale lepiej jest w pełni się zakwalifikować i zaoszczędzić na używaniu przestrzeni nazw. Zapisano nawiasy. Także z oszczędności return new z[]wreturn 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]};}}
Nathan Cooper
źródło
Jest (c*a[0])konieczne? Nie możesz wyeliminować tych nawiasów i zaoszczędzić 2 bajty?
Kyle Kanos
@KyleKanos Tak, dziękuję. Podczas gdy c # nie używa BODMAS-a, mnożenie nastąpi najpierw (tak myślę).
Nathan Cooper
Powiedziałbym, że musisz dołączyć namespacedeklarację lub zmienić ją na System.Single, aby to rozwiązanie było ważne.
Tim S.
1

Lua 5.1.4: 66 64 bajtów

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

Przykładowe użycie:

> 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
Kyle Kanos
źródło
1

C ++ 88 (było 106)

Ulepszony: dzięki za komentarze.

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

Gra w golfa:

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

Źródło

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;
}
Bacchusbeale
źródło
Widzę niepotrzebne miejsce;)
Martin Ender
1
Jeśli jest to C ++, dlaczego typedef?
dw
Myślę też, że można się pozbyć z:u.x=(v.y-u.y)/(v.x-u.x); u.y=v.y-z.x*v.x; return u;
dw
1

Apple Swift 95 86

To może być pierwszy wpis Swift na 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])}

Nie widzę, aby ten język był wielkim hitem dla społeczności Code Golf.

Harry Beadle
źródło
0

Golfscript: 25 bajtów

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

Ponieważ funkcja musi mieć nazwę „L”, zapisałem ją lokalnie jako „L.gs”.

Złap, jak wyjaśniono w @Dennis w tym poście , polega na tym, że musimy oszukać Golfscript, aby używał liczb wymiernych zamiast liczb całkowitych. Działa to, jeśli chcesz zaakceptować dane wejściowe X1 Y1 X2 Y2 w notacji golfowej

# 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
wrongu
źródło
0

Ruby - 48 znaków

Prawie identyczna z odpowiedzią JavaScript:

L=->u,v{a,b,c,d=*u,*v;[s=(d-b).fdiv(c-a),b-s*a]}
OI
źródło
0

Python3 - 64 57 bajtów

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

Możesz zmniejszyć go do 43, jeśli nie używasz Tuple, co robi wiele osób ...

def L(x,y,q,w):a=(x-q)/(y-w);return a,y-a*x
Harry Beadle
źródło
return(a,q[1]-a*q[0])
user12205
@ace Dzięki, to było niechlujne
Harry Beadle
0

PHP (75 znaków)

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

wynik :

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

(dzięki @ace)

Fabien Sa
źródło