3.2 Solution

My first impulse was that the ball should cost $0.1 or 10 cents. It’s the only logical solution, right?

Surprisingly, it turns out that this simple problem trips up a lot of people (if you were not one of them, congrats!).

Let’s summon primary school math to the rescue and settle this once and for all. From the task description we know that:

\[ bat + ball = 1.1 \qquad{(1)}\]

\[ bat - ball = 1 \qquad{(2)}\]

Therefore, we can rewrite the Equation 2 (move - ball to the other side and change mathematical operation to the opposite) to get:

\[ bat = 1 + ball \qquad{(3)}\]

Finally, by substituting bat from Equation 1 with bat from Equation 3 (bat = 1 + ball) we get.

\[ 1 + ball + ball = 1.1 \]

which we can simplify to

\[ 1 + 2*ball = 1.1 \]

\[ 2*ball + 1 = 1.1 \]

\[ 2*ball = 1.1 - 1 \]

\[ 2*ball = 0.1 \]

\[ ball = 0.1 / 2 \]

to finally get:

\[ ball = 0.05 \]

So it turns out that, counter-intuitively, the ball costs $0.05 or 5 cents.

That’s all very interesting, but what any of this got to do with Julia? Well, we can solve this and more complicated equations with it. For that purpose we will use matrices and their multiplications as explained in this Khan Academy’s video.

variables = [
    1 1; # 1 bat + 1 ball
    1 -1 # 1 bat - 1 ball
]
2×2 Matrix{Int64}:
 1   1
 1  -1

First we set the variables matrix where row 1 represents the left side of Equation 1 and row 2 stands for the left side of Equation 2. Column 1 contains the number of bats in each equation, whereas column 2 the number of balls.

And now for the right sides of the equations, we will place them in the prices vector.

prices = [1.1, 1.0]
[1.1, 1.0]

All that’s left to do, is to multiply the inverse (inv) of the matrix variables by the prices.

result = inv(variables) * prices
# or, shortcut
result = variables \ prices
round.(result, digits=4)
[1.05, 0.05]

Here we see the prices of bat (1.05) and ball (0.05) calculated by Julia. We rounded the results to counterbalance inexact float representation in computers (as discussed previously).

Now, if you’re new to matrix algebra, then this may look like an unnecessary hassle and some obscure alchemy. In that case you may consider using Symbolics.jl, a package with a bit friendlier and more human readable syntax.

import Symbolics as Sym

Sym.@variables bat ball
result = Sym.symbolic_linear_solve(
    [
        bat + ball ~ 1.1,
        bat - ball ~ 1
    ],
    [bat, ball]
);
round.(result, digits=4)
[1.05, 0.05]

First, we declare variables (Sym.@variables) that we will use in our equations (customarily those are x, y, z, etc.), here we opted for more human readable bat and ball names. Next we use symbolic_linear_solve function to get the solution (the calculation process may take a second or two). It takes 2 arguments (separated by coma): 1) equation(s) and 2) variable(s) for which we want to solve our equation. Since we got a set of 2 equations we place them in square brackets separated by comma. Inside the equations we use previously defined (Sym.@variables) variables (bat and ball) and ~ instead of = known from mathematics. Next, we send the variable(s) we are looking for ([bat, ball]). The number of variables should be equal to the number of equations in the first argument, and if it is greater than 1 then we place them between square braces and separate them with comas. And that’s it.

Pretty neat trick. Worth to know if your math is rusty (like mine is) and you want to confirm your pen and paper results.



CC BY-NC-SA 4.0 Bartlomiej Lukaszuk