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)

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

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 )

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.


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.


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]

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

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

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

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

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.


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

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

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

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)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.