C (gcc), 143 142 127+10=137 136+10=146 (compiler flags) bytes
-1 byte by replacing logical OR with bitwise operator.
-5 bytes thanks to Logern.
+9 bytes to fix the median line, that was output twice.
char*s="123456789abcdefghi";G{for(;j<18;++j)putchar(i>j|j>17-i?s[j]:32);puts("");}f(){int i=0,j=0;for(;i++<8;)G;g(i+1,j);for(;i-->1;)G;}
Compiler flag:
-DG=g(i,j)
This macro factorizes the occurences of g(i,j)
: function declaration and calls.
Try it online!
Different approach than Pietu1998's great answer, more straightforward (and readable), but higher score.
Entry point is function f()
; function g()
handles the printing of each consecutive line.
Could be made a full program by renaming f
to main
, but it would yet increase the score.
Pretty version, macro G
expanded:
char *s = "123456789abcdefghi";
int g(int i, int j) {
for(; j < 18; ++j)
putchar((i > j | j > 17 - i) ? s[j] : 32);
puts(""); // Break the line -- shorter than putchar(10) or printf("\n")
}
int f() {
int i = 0, j = 0; // j is constant, declared here to not have to declare and init it inside g()
for(; i++ < 8;) // Upper half of the tie
g(i, j);
g(i + 1, j); // Median line
for(; i-- > 1;) // Lower half; --i > 0 would also work for the condition
g(i, j);
}