Solution (source code)

= Solution

First normalize fresh copies of the two components. The following output helpers print a reduced rational with no `/1`, suppress a zero radical term, and suppress a unit radical coefficient:

``
OutRat(q):
    Out.Int(q.num)
    if q.den != 1: Out.String("/"); Out.Int(q.den)

OutIrr(x):
    r = mkRat(x.rat.num,x.rat.den)
    b = mkRat(x.irr.num,x.irr.den)
    if b.num == 0:
        OutRat(r); return
    if r.num != 0: OutRat(r)
    if b.num < 0: Out.String("-")
    else if r.num != 0: Out.String("+")
    c = mkRat(abs(b.num),b.den)
    if c.num != c.den:
        OutRat(c); Out.String("*")
    Out.String("sqrt(5)")
``

Thus the examples print \b[`1/2+1/2*sqrt(5)`] and \b[`2`]; zero prints `0`, and pure unit radicals print `sqrt(5)` or `-sqrt(5)`. The positive-denominator invariant makes the coefficient sign test reliable. Input records are not mutated.