Jelly, 18 bytes
PÆfQ0;ðṛW+ḍ€⁸;"o⁶GPÆfQ0;ðḍ€+W}⁸;"o⁶G
Uses 1
instead of *
, as allowed by the rules.
How it works
PÆfQ0;ðḍ€+W}⁸;"o⁶G Main link. Argument: A (array of integers greater than 1)
P Take the product of the integers in A.
Æf Compute all prime factors (with multiplicity) of the product.
Q Unique; deduplicate the prime factors.
0; Prepend a 0. Let's call the result P.
ð Begin a new, dyadic chain. Left argument: P. Right argument: A
ḍ€ Divisible each; for each p in P, test all integers in A for
divisibility by P. Yields one row of the shape of A for each p.
Note that the first element of P is 0, so the first row of the
resulting matrix contains only zeroes.
W} Wrap right; yield [A].
+ Add the results to both sides. Because of how Jelly's auto-
vectorization works, this adds the first row of [A] (just A) to
the first row of the divisibility matrix (all zeroes) and
leaves the other rows untouched.
⁸;" Prepend the elements of P to the corresponding rows of the
previous result.
o⁶ OR space; replace all zeroes with spaces.
G Grid; format the matrix as requested in the challenge spec.