Solveur de fonction linéaire à partir de deux points (x, y)

10

La tâche

Écrivez une fonction L () qui prend deux arguments Tuple de coordonnées sous la forme (x, y), et retourne leur fonction linéaire respective sous la forme (a, c), où a est le coefficient du terme x et c est l'ordonnée à l'origine.

Vous pouvez supposer que l'entrée ne sera pas une ligne perpendiculaire à l'axe x et que les deux entrées sont des points distincts.

Notation 

C'est Code Golf: le programme le plus court gagne.

Remarque: aucune utilisation de fonctions mathématiques en dehors des opérateurs de base (+, -, /, *).

Exemple

Voici ma solution non-golfée en 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)

Production:

>>> 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
la source
4
L( (0,0) , (0,1) )?
Howard
1
Vous pouvez supposer que l'entrée n'est pas une ligne parallèle à l'axe X.
Harry Beadle
2
Vous pouvez supposer que l'entrée n'est pas une ligne parallèle à l'axe X. Voulez-vous dire l'axe Y?
Howard
Désolé, l'édition sur le post était correcte, perpendiculaire à l'axe X.
Harry Beadle
2
L((0,0),(0,0))?
user12205

Réponses:

1

J - 23 caractères

Assez simple. Définit un verbe dyadique Là utiliser comme (x1,y1) L (x2,y2).

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

Explication:

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

Exemples:

   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
algorithmshark
la source
7

GNU dc , 30 24 octets

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

Définit une macro Ltelle que (x 1 , y 1 , x 2 , y 2 ) doit être poussé vers la pile dans cet ordre avant d'appeler, et après l'appel L, (a, c) peut être extrait de la pile (dans l'ordre inverse de bien sûr - c'est une pile).

Testcase (enregistrer sous "linear.dc" et exécuter dc linear.dc):

[sysxly-rlx- / dlx * lyr-] sL # Définit la macro L

10 # Poussez x1 dans la pile
22.5 # Poussez y1 vers la pile
5 # Poussez x2 dans la pile
12.5 # Poussez y2 vers la pile

lLx # Appeler la macro L
f # Vider la pile

La sortie est:

$ dc linear.dc 
2.5
2
$ 

Explication de la macro L:

  • sypop y 2 pour vous yinscrire
  • sxpop x 2 pour vous xinscrire
  • lyyregistre poussoir (y 2 )
  • -soustraire y 2 de y 1
  • rswap (y 1 - y 2 ) et x 1 sur la pile
  • lxxregistre poussoir (x 2 )
  • -soustraire x 2 de x 1
  • /diviser (y 1 - y 2 ) par (x 1 - x 2 ) pour obtenir un gradient
  • d gradient en double
  • lxxregistre poussoir (x 2 )
  • *multiplier (x 2 ) par gradient
  • lyyregistre poussoir (y 2 )
  • rpermuter (y 2 ) et ( dégradé x 2 *) sur la pile
  • -soustraire ( gradient x 2 *) de (y 2 )
Traumatisme numérique
la source
1
Merci, pas mal. J'avoue avoir été battu. ;)
Martin Ender
1
@ m.buettner Re-golfé et re-expliqué.
Digital Trauma
5

Haskell, 41 caractères

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

Pas beaucoup de golf ici. C'est à peu près ce que vous écririez normalement moins les espaces blancs.

hammar
la source
4

Mathematica, 55 38 octets

C'était étonnamment long (ces noms de fonction longs embêtants ...) EDIT: Modification de l'approche pour l'interception d'axe (en s'inspirant de la réponse du PO). Il s'avère que le calculer directement n'était pas l'idée la plus intelligente.

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

Utilisez comme

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

Grâce à Mathematica, vous pouvez également obtenir le résultat général:

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

(Ce dernier exemple montre comment j'avais implémenté cela à l'origine.)

Juste pour info

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

ce qui est techniquement correct.

Martin Ender
la source
Ahh, génial, j'avais un peu d'esprit noir à comprendre cela, je vais le blâmer sur ma fatigue
Harry Beadle
1
+1. Pourquoi ComplexInfinityet pas simplement vieux Infinity? (Je ne connais pas Mathematica)
Digital Trauma
3
@DigitalTrauma Je pense que c'est parce que, sans dire explicitement à Mathematica qu'il peut fonctionner en réels, il suppose toujours que l'espace en question est des nombres complexes, afin de ne pas jeter les solutions complexes d'équations réelles.
Martin Ender
2

JavaScript, 62 48

Merci à @Michael d'avoir joué avec ES 6.

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

Ancienne version:

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

Exemple d'entrée:

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

Exemple de sortie:

[0.14285714285714285, 0]

Pour mémoire:

L([0,0],[0,1])
[Infinity, NaN]
user12205
la source
46 utilisant ES6:L=(a,b)=>[g=(p=a[1]-b[1])/(q=a[0]-b[0]),p-g*q]
Michael M.
@Michael Cool. Je suis une sorte de débutant JS, donc je ne savais pas que tu pouvais faire ça. Merci.
user12205
@ m.buettner Vous avez raison ... Corrigé
user12205
1
Maintenant, toutes les réponses sont exactement à dix caractères d'intervalle. : D
Martin Ender
1
Awww. Le lapin a changé!
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
la source
2

C # 105 octets

Ce n'est pas seulement la fonction et se compilera complètement d'elle-même. J'avais mis Ll' Systemespace de noms pour raccourcir l'utilisation, mais il vaut mieux se qualifier complètement et économiser sur l'utilisation d'un espace de noms. Enregistré les crochets. Aussi une économie de return new z[]enreturn 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
la source
Est (c*a[0])nécessaire? Vous ne pouvez pas éliminer ces parenthèses et économiser 2 octets?
Kyle Kanos
@KyleKanos Oui, merci. Bien que c # n'utilise pas BODMAS, la multiplication sera effectuée en premier (je pense).
Nathan Cooper
Je dirais que vous devez inclure la namespacedéclaration ou la modifier System.Singlepour que cette solution soit valide.
Tim S.
1

Lua 5.1.4: 66 64 octets

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

Exemple d'utilisation:

> 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
la source
1

C ++ 88 (au lieu de 106)

Amélioré: merci pour vos commentaires.

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

Golfé:

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

La 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;
}
bacchusbeale
la source
Je vois un espace inutile;)
Martin Ender
1
S'il s'agit de C ++, pourquoi le typedef?
dyp
Aussi, je pense que vous pouvez vous débarrasser de z:u.x=(v.y-u.y)/(v.x-u.x); u.y=v.y-z.x*v.x; return u;
dyp
1

Apple Swift 95 86

Cela peut être la première entrée Swift sur 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])}

Je ne vois pas cette langue comme un énorme succès pour la communauté Code Golf.

Harry Beadle
la source
0

Golfscript: 25 octets

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

Étant donné que la fonction doit être nommée «L», je l'ai enregistrée en tant que «L.gs» localement.

Le hic, comme expliqué par @Dennis dans ce post , est que nous devons inciter Golfscript à utiliser des nombres rationnels au lieu d'entiers. Cela fonctionne donc si vous êtes prêt à accepter une entrée X1 Y1 X2 Y2 en notation golfscript

# 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
falseu
la source
0

Ruby - 48 caractères

Presque identique à la réponse JavaScript:

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

Python3 - 64 57 octets

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

Vous pouvez le réduire à 43 si vous n'utilisez pas Tuple, ce que beaucoup de gens font ...

def L(x,y,q,w):a=(x-q)/(y-w);return a,y-a*x
Harry Beadle
la source
return(a,q[1]-a*q[0])
user12205
@ace Merci, c'était bâclé
Harry Beadle
0

PHP (75 caractères)

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

production :

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

(merci @ace)

Fabien Sa
la source