Solve equations with substitution method

Revision as of 12:16, 10 November 2021 by Petelomax (talk | contribs) (→‎{{header|Phix}}: added translation of Raku version)


Let given equations:
3x + y = -1 and 2x - 3y = -19
Solve it with substitution method.

Solve equations with substitution method is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task


See related



Julia

<lang julia>function parselinear(s)

   ab, c = strip.(split(s, "="))
   a, by = strip.(split(ab, "x"))
   b = replace(by, r"[\sy]" => "")
   b[end] in "-+" && (b *= "1")
   b = replace(b, "--" => "")
   return map(x -> parse(Float64, x == "" ? "1" : x), [a, b, c])

end

function solvetwolinear(s1, s2)

   a1, b1, c1 = parselinear(s1)
   a2, b2, c2 = parselinear(s2)
   x = (b2 * c1 - b1 * c2) / (b2 * a1 - b1 * a2)
   y = (a1 * x - c1 ) / -b1
   return x, y

end

@show solvetwolinear("3x + y = -1", "2x - 3y = -19") # solvetwolinear("3x + y = -1", "2x - 3y = -19") = (-2.0, 5.0) </lang>

Phix

Slightly modified copy of solveN() from Solving_coin_problems#Phix, admittedly a tad overkill for this task, as it takes any number of rules and any number of variables.

with javascript_semantics
procedure solve(sequence rules, unknowns)
--
-- Based on https://mathcs.clarku.edu/~djoyce/ma105/simultaneous.html
--  aka the ancient Chinese Jiuzhang suanshu ~100 B.C. (!!)
--
-- Example:
--  rules = {{18,1,1},{38,1,5}}, ie 18==p+n, 38==p+5*n
--  unknowns = {"pennies","nickels"}
--
--  In the elimination phase, both p have multipliers of 1, so we can
--  ignore those two sq_mul and just do (38=p+5n)-(18=p+n)==>(20=4n).
--  Obviously therefore n is 5 and substituting backwards p is 13.
--
    string res
    sequence sentences = rules, ri, rj
    integer l = length(rules), rii, rji
    rules = deep_copy(rules)
    for i=1 to l do
        -- successively eliminate (grow lower left triangle of 0s)
        ri = rules[i]
        if length(ri)!=l+1 then ?9/0 end if
        rii = ri[i+1]
        if rii=0 then ?9/0 end if
        for j=i+1 to l do
            rj = rules[j]
            rji = rj[i+1]
            if rji!=0 then
                rj = sq_sub(sq_mul(rj,rii),sq_mul(ri,rji))
                if rj[i+1]!=0 then ?9/0 end if -- (job done)
                rules[j] = rj
            end if
        end for 
    end for 
    for i=l to 1 by -1 do
        -- then substitute each backwards
        ri = rules[i]
        rii = ri[1]/ri[i+1] -- (all else should be 0)
        rules[i] = sprintf("%s = %d",{unknowns[i],rii})
        for j=i-1 to 1 by -1 do
            rj = rules[j]
            rji = rj[i+1]
            if rji!=0 then
                rules[j] = 0
                rj[1] -= rji*rii
                rj[i+1] = 0
                rules[j] = rj
            end if
        end for
    end for 
    res = join(rules,", ")
    printf(1,"%v ==> %s\n",{sentences,res})
end procedure

--for 3x + y = -1 and 2x - 3y = -19:
solve({{-1,3,1},{-19,2,-3}},{"x","y"})
Output:
{{-1,3,1},{-19,2,-3}} ==> x = -2, y = 5

Alternatively, since I'm staring right at it, here's a

Translation of: Raku
with javascript_semantics
function solve2(sequence e1,e2)
    atom {a1,b1,c1} = e1,
         {a2,b2,c2} = e2,
         x = (b2*c1 - b1*c2)
           / (b2*a1 - b1*a2),
         y = (a1*x - c1)/-b1;
    return {x, y}
end function
printf(1,"x = %d, y = %d\n",solve2({3,1,-1},{2,-3,-19}))
Output:
x = -2, y = 5

Raku

<lang perl6>sub solve-system-of-two-linear-equations ( [ \a1, \b1, \c1 ], [ \a2, \b2, \c2 ] ) {

   my \X = ( b2 * c1   -   b1 * c2 )
         / ( b2 * a1   -   b1 * a2 );
   my \Y = ( a1 * X    -   c1 ) / -b1;
   return X, Y;

} say solve-system-of-two-linear-equations( (3,1,-1), (2,-3,-19) );</lang>

Output:
(-2 5)

Ring

<lang ring> firstEquation = [3.0,1.0,-1.0] secondEquation = [2.0,-3.0,-19.0] getCrossingPoint(firstEquation,secondEquation)

func getCrossingPoint(firstEquation,secondEquation)

    x1 = firstEquation[1] y1 = firstEquation[2] r1 = firstEquation[3] x2 = secondEquation[1] y2 = secondEquation[2] r2 = secondEquation[3]
    temp = []
    add(temp,x1) add(temp,-y1) add(temp,r1)
    resultY = ((temp[1]* r2) - (x2 * temp[3])) / ((x2 * temp[2]) + (temp[1]*y2)) resultX = (r1 - (y1*resultY)) / x1 
    see "x = " + resultX + nl + "y = " + resultY + nl

</lang>

Output:
x = -2
y = 5

Wren

<lang ecmascript>var solve = Fn.new { |e1, e2|

   e2 = e2.toList
   for (i in 1..2) e2[i] = e2[i] * e1[0] / e2[0]
   var y = (e2[2] - e1[2]) / (e2[1] - e1[1])
   var x = (e1[2] - e1[1] * y) / e1[0]
   return [x, y]

}

var e1 = [3, 1, -1] var e2 = [2, -3, -19] var sol = solve.call(e1, e2) System.print("x = %(sol[0]), y = %(sol[1])")</lang>

Output:
x = -2, y = 5

XPL0

This shows the vector routines from xpllib.xpl. <lang XPL0>func real VSub(A, B, C); \Subtract two 3D vectors real A, B, C; \A:= B - C [A(0):= B(0) - C(0); \VSub(A, A, C) => A:= A - C

A(1):= B(1) - C(1);
A(2):= B(2) - C(2);

return A; ]; \VSub

func real VMul(A, B, S); \Multiply 3D vector by a scalar real A, B, S; \A:= B * S [A(0):= B(0) * S; \VMul(A, A, S) => A:= A * S

A(1):= B(1) * S;
A(2):= B(2) * S;

return A; ]; \VMul

real E1, E2, X1, X2, X, Y; [E1:= [3., 1., -1.];

E2:= [2., -3., -19.];

X1:= E1(0); X2:= E2(0); VMul(E1, E1, X2); VMul(E2, E2, X1); VSub(E1, E1, E2); Y:= E1(2)/E1(1); E2(1):= E2(1)*Y; E2(2):= E2(2)-E2(1); X:= E2(2)/E2(0); Text(0, "x = "); RlOut(0, X); CrLf(0); Text(0, "y = "); RlOut(0, Y); CrLf(0); ]</lang>

Output:
x =    -2.00000
y =     5.00000