# Alpha-Numerical Bowtie

Output this exact text:

1                i
12              hi
123            ghi
1234          fghi
12345        efghi
123456      defghi
1234567    cdefghi
12345678  bcdefghi
123456789abcdefghi
12345678  bcdefghi
1234567    cdefghi
123456      defghi
12345        efghi
1234          fghi
123            ghi
12              hi
1                i


A single trailing newline is acceptable, but no other formatting changes are allowed.

### Rules and I/O

• No input
• Output can be given by any convenient method.
• Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
• Standard loopholes are forbidden.
• This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
• Can we use the uppercase alphabet instead? Commented Jun 25, 2018 at 15:47
• @Cowsquack That would be a rule change. It says Output this exact text. Commented Jun 25, 2018 at 15:52
• @Cowsquack Nope - lowercase is required. Commented Jun 25, 2018 at 15:57

# C, 878581 80 bytes

j;main(i){for(;++i<19;)for(j=19;j--;)putchar(j?j<i^j<20-i?32:106-j-j/10*39:10);}


Try it online!

### Explanation

j; // same as int j;
main(i){ // same as int main(int i){, where i = argc (1 with no arguments)
for(;++i<19;) // loop over rows, i = 2..18
for(j=19;j--;) // loop over chars, j = 19..0
putchar(j?j<i^j<20-i?32:106-j-j/10*39:10); // output characters:
//      j?                           :10 // on last char (j=0), output \n
//        j<i                            // check for top/left half
//            j<20-i                     // check for bottom/left half
//           ^                           // 1 if only one half matched
//                  ?32:                 // if so, output space
//                      106              // char code for j
//                         -j            // get desired letter
//                           -j/10*39    // subtract 39 for j>9 (numbers)
}

• I'm amazed ^ has lower precedence than <… what a pretty answer!
– lynn
Commented Jun 26, 2018 at 13:12
• @Lynn The bitwise operators in C (and even Java/JS and such) all have a lower precedence than comparisons. This is both nice for code golf and a really nice source of errors (think if (x & 2 == 0), which always evaluates to 0) Commented Jun 26, 2018 at 21:57

# Python 2, 73 bytes

i=9
exec"i-=1;a=abs(i);print'123456789'[:9-a]+'  '*a+'abcdefghi'[a:];"*17


Try it online!

# R, 64 bytes

for(i in abs(8:-8))cat(intToUtf8(c(57-8:i,32*!!-i:i,97+i:8,13)))


Try it online!

• -3 bytes thanks to @Giuseppe
• -5 bytes thanks to @J.Doe
• 67 bytes with intToUtf8 Commented Sep 7, 2018 at 16:10
• cat for one byte? Commented Sep 7, 2018 at 19:26
• 64 bytes building on your solution, using @Giuseppe's shortcut to rep plus the feature of intToUtf8 that a 0 turns into a "". Commented Sep 7, 2018 at 21:34
• @J.Doe great trick! Commented Sep 8, 2018 at 0:22
• @J.Doe : Awesome, thanks ! Commented Sep 8, 2018 at 9:39

# 05AB1E (legacy), 15 bytes

A9£Sāì9LÂì×ζRû»


Try it online!

-2 thanks to Kevin Cruijssen.

• 16 bytes by changing žh¦A9£«S9L to 9L©A9£S«® (or 9LA9£S«9L or 9LDA9£S«s). Commented Aug 31, 2018 at 9:05
• 15 bytes by changing it to A9£Sāì9L instead. Commented Nov 7, 2022 at 11:12

# Python 2, 80 bytes

j=i=1
exec"print'123456789'[:i]+'  '*(9-i)+'abcdefghi'[-i:];i+=j;j-=2*(i>8);"*17


Try it online!

• 77 bytes
– ovs
Commented Jun 25, 2018 at 15:27
• @ovs it would converge into Lynn's answer, so I'll leave this one as is
– Rod
Commented Jun 25, 2018 at 16:14

# QBasic, 72 bytes

Based on Taylor Scott's submission.

FOR y=-8TO 8
z=ABS(y)
?"123456789abcdefghi";
LOCATE,10-z
?SPC(2*z)"
NEXT


### Basic explanation

On each line, we print the full string 123456789abcdefghi. Then we go back and overwrite part of it with spaces.

### Full explanation

With code slightly ungolfed:

FOR y = -8 TO 8           ' Loop for 17 rows
z = ABS(y)               ' z runs from 8 to 0 and back to 8
? "123456789abcdefghi";  ' Print the full string and stay on the same line (important!)
LOCATE , 10-z            ' Go back to column 10-z on that line
? SPC(2*z); ""           ' Print 2*z spaces
' (SPC keeps the cursor on the same line unlesss you print
' something after it, so we'll use the empty string)
NEXT                      ' Go to the next y value

• That's a really clever use of the Locate command Commented Jul 9, 2018 at 18:42

# T-SQL, 108 bytes

DECLARE @ INT=8a:
PRINT STUFF('123456789abcdefghi',10-abs(@),2*abs(@),SPACE(2*abs(@)))
SET @-=1IF @>-9GOTO a


Tried lots of other variations, including number tables, this was the shortest.

# 05AB1E, 20 bytes

9LJη.BA9£.sí.Bí)øJû»


Try it online!

# Canvas, 13 bytes

９Ｒ［］ｚ９ｍ±［］±＋─


Try it here!

# Japt, 20 bytes

9Æ9Ç>YÃê1 Ë?S:°EsH
ê


Japt Interpreter

Output as an array of arrays of characters. The -R flag isn't necessary to work, it just makes the output look nicer.

Explanation:

9Æ9Ç                    create a 9x9 2D array
>YÃ                 fill bottom left triangle with "false", upper right with "true"
ê1               mirror horizontally
Ë?S           replaces "true" with a space
:°EsH      replaces "false" with the horizontal index + 1 converted to base 32
\n    Store the result in U (saves bytes by not closing braces)
ê   palindromize vertically


# PowerShell 5.1, 706964 57 Bytes

Thanks Mazzy for -7 bytes

1..9+8..1|%{-join(1..$_+' '*(9-$_)+' ihgfedcba'[$_..1])}  Turns out gluing it together manually saves a byte. Making it all one mega-join also saves 5 more. Also works by turning a range of ints into a char[] to get the a-i. Using a range over the actual letters is 5 bytes better. • try this: 1..9+8..1|%{-join(1..$_+' '*(9-$_)+' ihgfedcba'[$_..1])}. Note ' '*(9-$_) contains 2 space symbols Commented Sep 5, 2018 at 14:05 • @mazzy ooof, missing that double space trick. I was thinking of a variety of math statements but the obvious solution never occurred to me. Commented Sep 5, 2018 at 20:51 # Julia 1.0, 73 bytes [1:9;8:-1:1].|>i->println(join(1:9)[1:i]*" "^(18-2i)*"abcdefghi"[10-i:9])  Try it online! # MATL, 47 bytes 9l$lRtH2$PhO18Y"yPvv1=49:57 97:105h19T3$X"32b(c


Try it online!

# Vyxal, 14 bytes

9ʀṘǔmkrf*ꜝøṗ↵§


Try it online!

Explanation

A transposition approach.

9ʀ             # range from 0 to 9 inclusive
Ṙ            #  reversed
ǔ           #  rotated right (last item goes to first)
m          #  and concatenated with its reverse
kr        # string of digits, lowercase alphabet, and uppercase alphabet
f       #  into a list of characters
*      # repeat (vectorises)
ꜝ     # remove empty strings in the list
øṗ   # palindromise each item, center, and join by newlines
↵  # split on newlines
§ # vertically join

• wow, that's much better than what I had (17-18 bytes)! Very cool answer! Commented Nov 8, 2022 at 11:38

# Japt, 24 19 bytes

Returns an array of lines

9õ Ôê1 Ëç°TsH)êÃû y


Test it

9õ Ôê1 Ëç°TsH)êÃû y
9õ                      :Range [1,9]
Ô                    :Reverse
ê1                  :Mirror
Ë                :Map
ç               :  Repeat
°T             :    Prefix increment T (initially 0)
s            :    Convert to base
H           :    32
)          :  End repeat
ê         :  Palindromise
Ã        :End map
û       :Centre pad each with spaces to the length of the longest
y     :Transpose

• I'm wondering now if building this horizontally might not have led to a shorter solution! :\ Commented Jun 25, 2018 at 16:56

# Stax, 18 bytes

â4+╤jo♂▐▀3bkWíæß╝╖


Run and debug it

Explanation:

9R$|[|<Va17T|]r|>\|pm Full program 9R$                   Produce "123456789"
|[|<               Left-aligned prefixes (["1        ", "12       ", ...])
Va17T          Produce "abcdefghi"
|]        Suffixes (["abcdefghi", "bcdefghi", ...])
r|>     Reverse and left-align (["        i", "       hi", ...])
\    Zip both arrays (["1                i", "12              hi", ...])
|p  Palindromize array
m Map over array, printing each with a newline


# JavaScript (ES6), 76 bytes

f=(x=y=0)=>y<17?(x>y^x++<17-y?x.toString(36)+[
[x%=18]]:' ')+f(x||!++y):''


Try it online!

# APL (Dyalog Unicode), 30 bytes

(⊢⍪1↓⊖)(↑,\1↓⎕d),⌽↑,\⌽819⌶9↑⎕a


Try it online!

↑ convert to a matrix (auto pads with spaces)

• ,\ the prefixes of

• 1↓ the first element dropped from

• ⎕d this string '0123456789'

• This gives the character matrix

1
12
123
1234
12345
123456
1234567
12345678
123456789


, concatenated with

• ⌽ the reversed

• ↑ matrixified

• ,\ prefixes of

• ⌽ the reversed

• 819⌶ and lowercased

• 9↑ first 9 elements of

• ⎕a this string 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

• This gives the character matrix

        i
hi
ghi
fghi
efghi
defghi
cdefghi
bcdefghi
abcdefghi


and on this result

1                i
12              hi
123            ghi
1234          fghi
12345        efghi
123456      defghi
1234567    cdefghi
12345678  bcdefghi
123456789abcdefghi


perform the following train (⊢⍪1↓⊖)

⊢ the right argument

⍪ concatenated vertically with

1↓ the first row dropped from (this avoids the repeating of the middle row)

⊖ the right argument reversed vertically

Other solutions

### 33 bytes

(⊢⍪1↓⊖)(↑,\⍕¨q),⌽↑,\⎕ucs 106-q←⍳9


Try it online!

### 33 bytes

(⊢⍪1↓⊖)(↑,\⍕¨q),⌽↑,\⌽⎕ucs 96+q←⍳9


Try it online!

# Charcoal, 22 17 bytes

Ｇ↗↓←⁹β←Ｇ↖↓⁹⭆χι‖Ｏ↓


Try it online! Link is to verbose version of code. Explanation:

Ｇ↗↓←⁹β


Draw a lower right triangle and fill it using the lowercase alphabet. (The fill is based on tiling the plane with the alphabet and then copying the drawn area.)

←


Move left to draw the numeric triangle.

Ｇ↖↓⁹⭆χι


Draw a lower left triangle and fill it using the digits. (Since the triangle is drawn to the left of the origin, the digits are taken right-justified, so only the digits 1 to 9 get used.)

‖Ｏ↓


Reflect to complete the bottom half.

# V, 25, 21 bytes

¬19¬ai8ñHÄ/á
r ge.YGp


Try it online!

2-4 bytes saved thanks to nmjcman101!

Hexdump:

00000000: ac31 39ac 6169 38f1 48c4 2fe1 0a72 2067  .19.ai8.H./..r g
00000010: 652e 5947 70                             e.YGp

• I know all I'm doing is stalking your answers today but I think this works for 23: Try it online! Commented Jun 25, 2018 at 21:38
• @nmjcman101 For whatever reason, I can't comprehend how that version works. But I figured out an even shorter one, so thanks! Commented Jun 25, 2018 at 21:52
• It went to the end of a /\d* search Commented Jun 25, 2018 at 22:43

# J, 44 bytes

(m]\u:49+i.9),.(m=.,}.@|.)]\&.(|."1)u:97+i.9


Try it online!

I tried to generate numerically a mask of 1 and zero to use for indexing, but the cost of getting rid of the extra row was high and I gave up:

   (9-.~i.18){0<:-/~(,|.)i.9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1
1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1


## Perl 5 + -M5.010, 49 bytes

say 1..9-abs,"  "x abs,(a..i)[-9+abs..-1]for-8..8


Try it online!

# QBasic, 87 bytes

An anonymous function that takes no input and outputs to the console.

For y=-8To 8:z=Abs(y):a$="123456789abcdefghi":?Mid$(a$,1,9-z)Spc(2*z)Mid$(a$,10+z):Next  This answer is technically a polyglot, and will function in VBA # Befunge-93, 314 308 bytes <p0+3*67p0+4*77p0+3*77p0-7*88p0-6*88"#v#v>" "i "11g1-21p56+1g1+56+1p28*1g1+28*1p ^ >25* " 1"92g1+82p56+2g1-56+2p28*2g1-28*2p91g00g#v_^ > "ihgfedcba "93p26*3g1-26*3p">^"88*7-0p88*7-4pv >25* "987654321 "14p26*4g1+26*4p26*4g12g#v_ ^ >:#,_@#:<  Try it online! Golfed 6 bytes by placing a > with the p instruction ## Matlab, 122 bytes function[r]=f,s=[49:57,'a':'i'];r=[];for i=1:9,r=[r;s(1:i),repmat(' ',[1,18-2*i]),s(19-i:18)];end,r=[r;flip(r(1:8,:))];end  Try it Online! # Deadfish~, 956 bytes {iiiii}dc{dd}iii{c}cccccc{{i}ddd}iiic{{d}i}dddddc{iiii}dcic{dd}ii{c}cccc{{i}ddd}iicic{{d}i}dddddc{iiii}dcicic{dd}i{c}cc{{i}ddd}icicic{{d}i}dddddc{iiii}dcicicic{dd}{c}{{i}ddd}cicicic{{d}i}dddddc{iiii}dcicicicic{dd}dcccccccc{{i}ddd}dcicicicic{{d}i}dddddc{iiii}dcicicicicic{dd}ddcccccc{{i}ddd}ddcicicicicic{{d}i}dddddc{iiii}dcicicicicicic{dd}dddcccc{{i}ddd}dddcicicicicicic{{d}i}dddddc{iiii}dcicicicicicicic{dd}ddddcc{iiiiii}iiiiiicicicicicicicic{{d}i}dddddc{iiii}dcicicicicicicicic{iiii}cicicicicicicicic{{d}i}dddddc{iiii}dcicicicicicicic{dd}ddddcc{iiiiii}iiiiiicicicicicicicic{{d}i}dddddc{iiii}dcicicicicicic{dd}dddcccc{{i}ddd}dddcicicicicicic{{d}i}dddddc{iiii}dcicicicicic{dd}ddcccccc{{i}ddd}ddcicicicicic{{d}i}dddddc{iiii}dcicicicic{dd}dcccccccc{{i}ddd}dcicicicic{{d}i}dddddc{iiii}dcicicic{dd}{c}{{i}ddd}cicicic{{d}i}dddddc{iiii}dcicic{dd}i{c}cc{{i}ddd}icicic{{d}i}dddddc{iiii}dcic{dd}ii{c}cccc{{i}ddd}iicic{{d}i}dddddc{iiii}dc{dd}iii{c}cccccc{{i}ddd}iiic  Try it online! # Haskell, 119 bytes import Data.Char main=putStr$do i<-[-8..8];[chr\$if abs j>abs i then j+96-fromEnum(j<0)*38else 32|j<-[-9..9],j/=0]++"\n"


Try it online!

# Julia 1.0, 54 bytes

[8:-1:1;0:8].|>i->print.([1:9-i;" "^2i;'a'+i:'i';"
"])


Try it online!

# Wolfram Language (Mathematica), 81 79 bytes

a=Table[" ",17,18];Do[a[[i;;-i,i]]=a[[1-i;;i-1,i]]=i~IntegerString~35,{i,18}];a


Try it online!

Throws a lot of ignorable errors.

# VBA, 75 bytes

An anonymous VBE immediate window function that takes no input and outputs to the console.

For y=-8To 8:z=Abs(y):a="123456789abcdefghi":Mid(a,10-z)=Space(2*z):?a:Next