Output the Goodstein sequence

Haskell, 77 bytes

(&2) is an anonymous function taking an Integer and returning a (potentially very long) list of Integers, use as (&2) 13.

n&b|n<0=[]|let _?0=0;e?n=(e+1)?div n b+mod n b*(b+1)^0?e=n:(0?n-1)&(b+1)

Try it online! (cuts off at 10^25.)

How it works

  • (&2) starts the sequence with base 2.
  • n&b calculates the subsequence starting with the number n and base b.
    • It halts with an empty list if n<0, which generally happens the step after n==0.
    • Otherwise, it prepends n to the list returned recursively by the expression (0?n-1)&(b+1).
  • ? is a local function operator. 0?n gives the result of converting n to hereditary base b, then incrementing the base everywhere.
    • The conversion recurses with the variable e keeping track of the current exponent. e?n converts the number n*b^e.
    • The recursion halts with 0 when n==0.
    • Otherwise, it divides n by the base b.
      • (e+1)?div n b handles the recursion for the quotient and next higher exponent.
      • mod n b*(b+1)^0?e handles the remainder (which is the digit corresponding to the current exponent e), the increment of base, and converting the current exponent hereditarily with 0?e.

Pyth, 28 26 bytes


The trailing newline is significant.

Try it online! (This link includes an extra Q not needed by the current version of Pyth.)

How it works

.V2                          for b in [2, 3, 4, ...]:
   Jb                          assign J = b
     L                         def y(b):
      &b                         b and
                   jbJ             convert b to base J
                  _                reverse
         .e                        enumerated map for values b and indices k:
             hJ                      J + 1
            ^  yk                    to the power y(k)
           *     b                   times b
(newline)                      print Q (autoinitialized to the input)
                        y      y(Q)
                       t       subtract 1
                      =        assign back to Q

It’s important that y is redefined in each loop iteration to prevent memoization across changes to the global variable J.