I tend to attack these kind of problems differently - not better, necessarily - by generalizing the steps and using simple math where possible:
- calculate the leading spaces
- print the spaces
- print the characters
Looking at your problems, I came up with this generalization:
// each line begins with 2 spaces * total lines to be printed less
// 2 spaces * the current row being printed
For the above, if 15 lines are to be printed, 28 leading spaces will be printed for line 1, and 0 leading spaces will be printed for line 15. As you've already discovered, it's a bit more complicated than that, so the rest of my generalization is:
// if the total number of lines to be printed is greater than 9,
// an extra space must be added to the single-digit lines for each
// of the double-digit lines
// if the current row being printed is > 9 and < the total number of
// lines, reduce leading spaces by 1 for each row > 9 except the last
// print the leading spaces
// print the required numbers
// add a linefeed