Back to Go Examples

Learning Go With Algebra Equations

Six classic algebra problems, each solved the standard way by hand and then again with a short Go program — so you learn the math and the code together.

How to use this page

Named after physicist Richard Feynman: if you can't explain an idea in plain words, you don't fully understand it yet. For each problem, work these four steps:

  1. Read the by-hand solution and follow every step until it clicks.
  2. Read the Go version and match each line of code to a step you just did by hand.
  3. Answer the 💡 Explain it simply prompt out loud, in your own words, before revealing the answer.
  4. Run the code yourself (copy it with the button), change a number, and predict the new answer before you press run.
Every Go program here uses decimals like 2.0 instead of 2. That forces Go to use floating-point math — otherwise 7 / 2 would be 3 (integer division), not 3.5, and your algebra answers would be wrong. The %g verb in Printf prints a number without trailing zeros, so 4.0 shows as 4.

The problems

  1. A one-step-at-a-time linear equation
  2. Variables on both sides
  3. Clearing a fraction
  4. A system of two equations
  5. A quadratic equation
  6. The equation of a line

Problem 1 — Solve a linear equation

2x + 3 = 11

The goal of algebra is almost always the same: get the unknown letter alone on one side of the =. Whatever x is, it must make the left side equal 11.

By hand Solve it the standard way
  1. Start with 2x + 3 = 11.
  2. Subtract 3 from both sides to undo the + 3:  2x = 8.
  3. Divide both sides by 2 to undo the :  x = 4.
Answer: x = 4
In Go Solve it with code

We rewrite the equation in the general form ax + b = c, then the by-hand steps become one line: x = (c - b) / a. The program also checks its answer by plugging x back in.

package main

import "fmt"

func main() {
    // 2x + 3 = 11   →   ax + b = c
    a, b, c := 2.0, 3.0, 11.0
    x := (c - b) / a
    fmt.Printf("x = %g\n", x)
    fmt.Printf("check: 2*%g + 3 = %g\n", x, a*x+b)
}
Output
x = 4
check: 2*4 + 3 = 11
Explain it simply

Why are you allowed to "subtract 3 from both sides" — why doesn't that change the answer?

Reveal a plain-language answer

Think of the = as a balance scale that's perfectly level. If you take the same weight off both pans, it stays level. Subtracting 3 from each side keeps the two sides equal, so the value of x that balanced it before still balances it now — you've just made it easier to read.

Problem 2 — Variables on both sides

5x − 4 = 3x + 8

Now x appears on both sides. The plan: gather all the x terms on one side and all the plain numbers on the other, then finish like Problem 1.

By hand Solve it the standard way
  1. Start with 5x − 4 = 3x + 8.
  2. Subtract 3x from both sides to collect the x's on the left:  2x − 4 = 8.
  3. Add 4 to both sides:  2x = 12.
  4. Divide both sides by 2:  x = 6.
Answer: x = 6
In Go Solve it with code

In the general form ax + b = cx + d, moving terms gives (a − c)x = d − b, so x = (d - b) / (a - c).

package main

import "fmt"

func main() {
    // 5x - 4 = 3x + 8   →   ax + b = cx + d
    a, b, c, d := 5.0, -4.0, 3.0, 8.0
    x := (d - b) / (a - c)
    fmt.Printf("x = %g\n", x)
    fmt.Printf("check: LHS = %g, RHS = %g\n", a*x+b, c*x+d)
}
Output
x = 6
check: LHS = 26, RHS = 26
Explain it simply

Why do we bother moving all the x terms to one side and all the numbers to the other?

Reveal a plain-language answer

Because you can only divide out x once it's alone. Gathering like things together turns a messy equation into the tidy shape (a number) · x = (a number). From there, one division sets x free. The check confirms it: both sides equal 26 when x = 6.

Problem 3 — Clearing a fraction

(x + 2) ÷ 4 = 5

A fraction just means "divided by." Undo the division first, then solve the simple equation that's left.

By hand Solve it the standard way
  1. Start with (x + 2) / 4 = 5.
  2. Multiply both sides by 4 to cancel the ÷ 4:  x + 2 = 20.
  3. Subtract 2 from both sides:  x = 18.
Answer: x = 18
In Go Solve it with code

In the form (x + n) / d = r, the two steps collapse to x = r*d - n.

package main

import "fmt"

func main() {
    // (x + 2) / 4 = 5   →   (x + n) / d = r
    n, d, r := 2.0, 4.0, 5.0
    x := r*d - n
    fmt.Printf("x = %g\n", x)
    fmt.Printf("check: (%g + 2)/4 = %g\n", x, (x+n)/d)
}
Output
x = 18
check: (18 + 2)/4 = 5
Explain it simply

Why does multiplying both sides by 4 make the fraction disappear?

Reveal a plain-language answer

Multiplying is the exact opposite of dividing. The left side was divided by 4; multiplying it by 4 undoes that and leaves it whole. You have to do the same to the right side to keep the balance, which turns the 5 into 20. Inverse operations always cancel each other.

Problem 4 — A system of two equations

2x + y = 8
x − y = 1

Two unknowns, two equations. The elimination method cancels one variable so you can solve for the other, then back-substitutes.

By hand Solve it the standard way
  1. Line up the equations: 2x + y = 8 and x − y = 1.
  2. Add the two equations. The +y and −y cancel:  3x = 9.
  3. Divide by 3:  x = 3.
  4. Substitute x = 3 into x − y = 1:  3 − y = 1, so y = 2.
Answer: x = 3, y = 2
In Go Solve it with code

For any system a₁x + b₁y = c₁ and a₂x + b₂y = c₂, there's a general formula (Cramer's rule). It's just the elimination method written once for all cases.

package main

import "fmt"

func main() {
    // 2x + y = 8
    //  x - y = 1
    a1, b1, c1 := 2.0, 1.0, 8.0
    a2, b2, c2 := 1.0, -1.0, 1.0

    det := a1*b2 - a2*b1
    x := (c1*b2 - c2*b1) / det
    y := (a1*c2 - a2*c1) / det
    fmt.Printf("x = %g, y = %g\n", x, y)
    fmt.Printf("check: 2x+y = %g, x-y = %g\n", 2*x+y, x-y)
}
Output
x = 3, y = 2
check: 2x+y = 8, x-y = 1
Explain it simply

When you add the two equations, why does the y vanish?

Reveal a plain-language answer

One equation has +y and the other has −y. Adding them stacks +y + (−y), which is 0 — the y cancels itself out. That's the whole trick of elimination: line the equations up so one variable adds to zero, leaving a single equation you can solve.

Problem 5 — A quadratic equation

x² − 5x + 6 = 0

The makes this a quadratic. It can have two solutions. You can often factor it; the quadratic formula always works.

By hand Solve it by factoring
  1. Find two numbers that multiply to 6 and add to −5. They are −2 and −3.
  2. Rewrite as a product: (x − 2)(x − 3) = 0.
  3. A product is 0 only if a factor is 0: x − 2 = 0 or x − 3 = 0.
  4. Solve each: x = 2 or x = 3.
Answer: x = 2 or x = 3
In Go Solve it with the quadratic formula

For ax² + bx + c = 0, the quadratic formula is x = (−b ± √(b² − 4ac)) / 2a. The ± is why there are two answers. Go's math.Sqrt handles the square root.

package main

import (
    "fmt"
    "math"
)

func main() {
    // x^2 - 5x + 6 = 0   →   ax^2 + bx + c = 0
    a, b, c := 1.0, -5.0, 6.0
    disc := b*b - 4*a*c   // the discriminant
    root := math.Sqrt(disc)
    x1 := (-b + root) / (2 * a)
    x2 := (-b - root) / (2 * a)
    fmt.Printf("discriminant = %g\n", disc)
    fmt.Printf("x = %g or x = %g\n", x1, x2)
}
Output
discriminant = 1
x = 3 or x = 2
Explain it simply

The part under the square root, b² − 4ac, is called the discriminant. What can it tell you before you finish solving?

Reveal a plain-language answer

Its sign counts the real answers. Positive (like our 1) means two different solutions; exactly 0 means one repeated solution; negative means no real solutions at all (you can't take the real square root of a negative). So a quick glance at the discriminant tells you what to expect before you do the rest.

Problem 6 — The equation of a line

line through (1, 2) and (3, 8)

Two points fix a straight line. We want it in the familiar form y = mx + b, where m is the slope and b is where it crosses the y-axis.

By hand Solve it the standard way
  1. Slope is rise over run: m = (y₂ − y₁) / (x₂ − x₁) = (8 − 2) / (3 − 1) = 3.
  2. Put a known point into y = mx + b to find b. Using (1, 2): 2 = 3·1 + b.
  3. Solve for b: b = −1.
Answer: y = 3x − 1
In Go Solve it with code

The two hand steps are two lines of Go. The small if at the end just prints a tidy − 1 instead of + -1.

package main

import "fmt"

func main() {
    // line through (1, 2) and (3, 8)
    x1, y1 := 1.0, 2.0
    x2, y2 := 3.0, 8.0
    m := (y2 - y1) / (x2 - x1)
    b := y1 - m*x1

    sign, bb := "+", b
    if b < 0 {
        sign, bb = "-", -b
    }
    fmt.Printf("slope m = %g\n", m)
    fmt.Printf("y = %gx %s %g\n", m, sign, bb)
}
Output
slope m = 3
y = 3x - 1
Explain it simply

Why is the slope "rise over run," and what does b actually represent on the graph?

Reveal a plain-language answer

Slope measures steepness: how far the line climbs (rise, the change in y) for each step it moves sideways (run, the change in x). A slope of 3 means "up 3 for every 1 across." And b is the line's height when x = 0 — the exact spot where it crosses the vertical y-axis.

Want more? Change the numbers at the top of any program, predict the new answer by hand first, then run it to check yourself — that back-and-forth is the fastest way to make both the algebra and the Go stick.