52
\$\begingroup\$

You are to print this exact text:

A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
ABCDEFGFEDCBA
ABCDEFGHGFEDCBA
ABCDEFGHIHGFEDCBA
ABCDEFGHIJIHGFEDCBA
ABCDEFGHIJKJIHGFEDCBA
ABCDEFGHIJKLKJIHGFEDCBA
ABCDEFGHIJKLMLKJIHGFEDCBA
ABCDEFGHIJKLMNMLKJIHGFEDCBA
ABCDEFGHIJKLMNONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNONMLKJIHGFEDCBA
ABCDEFGHIJKLMNMLKJIHGFEDCBA
ABCDEFGHIJKLMLKJIHGFEDCBA
ABCDEFGHIJKLKJIHGFEDCBA
ABCDEFGHIJKJIHGFEDCBA
ABCDEFGHIJIHGFEDCBA
ABCDEFGHIHGFEDCBA
ABCDEFGHGFEDCBA
ABCDEFGFEDCBA
ABCDEFEDCBA
ABCDEDCBA
ABCDCBA
ABCBA
ABA
A

Specs

  • Extra trailing newlines are allowed at the end of the output.
  • Extra trailing spaces (U+0020) are allowed at the end of each line, including the extra trailing newlines.
  • You can use all lowercase instead of all uppercase, but you cannot print partially lowercase partially uppercase.
  • You can return the text as a function output instead of printing it in a full program.

Scoring

Since this is a triangle, and a triangle has 3 sides, and 3 is a small number, your code should be small in terms of byte-count.

\$\endgroup\$
5
  • 23
    \$\begingroup\$ So many alphabets recently \$\endgroup\$ Aug 3, 2016 at 11:15
  • 1
    \$\begingroup\$ My synesthesia is going hog wild, @downrep_nation \$\endgroup\$ Aug 3, 2016 at 13:33
  • 7
    \$\begingroup\$ "Since a triangle has 3 sides and 3 is a small number, so your code should be small in terms of byte count." seems legitimate \$\endgroup\$ Aug 4, 2016 at 22:00
  • 1
    \$\begingroup\$ Squares of numbers composed only of 1 seems related: 1*1 = 1 ~= A , 11*11 = 121 ~= ABA , 111*111 = 12321 ~= ABCBA ... \$\endgroup\$
    – Caridorc
    Aug 5, 2016 at 13:28
  • 2
    \$\begingroup\$ "Since a triangle has 3 sides and..." Illuminati Confirmed. \$\endgroup\$
    – hyper-neutrino
    Oct 28, 2016 at 0:47

96 Answers 96

41
\$\begingroup\$

Vim, 37 bytes

:h<_↵↵↵YZZPP$xqqxYpGP√2G$A♥-€k$q24@qJ

enter image description here

Legend

↵ = Return
√ = Ctrl+V
♥ = Ctrl+R
€ = Escape
\$\endgroup\$
4
  • 3
    \$\begingroup\$ That's a really cool GIF. \$\endgroup\$ Aug 3, 2016 at 15:51
  • 13
    \$\begingroup\$ I will never cease to be amazed by Vim answers. \$\endgroup\$
    – DanTheMan
    Aug 4, 2016 at 5:05
  • \$\begingroup\$ Care to explain how this works for those not fluent in Vim? \$\endgroup\$
    – R. Kap
    Aug 9, 2016 at 6:30
  • 6
    \$\begingroup\$ @R.Kap I recommend you download Vim and try the solution out yourself — you can watch the solution unfold stroke by stroke! Essentially, I steal the alphabet from a help file (:h<_↵↵↵YZZP), then record a macro (qq…q) that repeatedly chops a letter off the top line, makes two copies of it to grow the triangle vertically, then appends the chopped-off letter to all lines to grow it horizontally. I repeat this macro 24 more times to draw the full triangle. \$\endgroup\$
    – Lynn
    Aug 9, 2016 at 10:06
30
\$\begingroup\$

Logo, 232 207 196 190 bytes

Did somebody say triangles?

Get out your compass and protractor, and let's do this the graphical way. The geometry uses an equilateral triangle to align the results. I previously had an isosceles triangle, but it involved too many decimal places. This change also compacted the output, reducing the amount of screen prep and font changing I had to do.

I used the Calormen online interpreter to flesh this one out. If you don't have enough screen real estate, it's going to wrap, but you can also fiddle with some numbers to take care of that. I used the "F11" full-screen mode on my browser.

ht
pu
to r:n:b:l repeat:n[rt:b label char 90-:n lt:b fd:l] end
to t:s
fd 12 rt 120 bk 6
repeat 2[r:s 90 12]
repeat 2[rt 120 r:s 90-heading 24]
end
rt 90 label "Z lt 210
repeat 25[t repcount]

The r procedure draws a line of n characters. The character is determined automatically depending on how many segments it is told to use. The b parameter tells it how much to temporarily rotate so that the letters are pointing in the right direction. The l parameter determines the linear distance between letters.

The t procedure steps to the next position and calls the r function a four times to create a triangle, rotating when appropriate. I called it twice for the vertical side because that took fewer bytes than calling it once with special handling. The end of the procedure positions the turtle for start of the next triangle, one step above.

Z is a special case, so we just print it directly and rotate as if we had just finished a triangle. Finally, t is called 25 times.

In progress annotated pictureFinished result

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Out of the box. Nicely done. \$\endgroup\$ Aug 12, 2016 at 20:30
19
\$\begingroup\$

Haskell, 58 bytes

f x=init x++reverse x
t=unlines$f[f['A'..c]|c<-['A'..'Z']]

Defines a function t that returns the output as a string.

f x=               define a helper function
init x             take the argument minus its last element
++                 and concatenate it with
reverse x          the argument reversed, producing ex. [a,b,c,b,a] from [a,b,c]

t=                                    define the main function
           [         |c<-['A'..'Z']]  for every char c from 'A' to 'Z'...
             ['A'..c]                 generate the range from 'A' to c
            f                         call the helper function to "reflect" it
          f                           call the helper function on the entire list
  unlines$                            join on newlines
\$\endgroup\$
12
\$\begingroup\$

Jelly, 16 13 bytes

Ṗ;Ṛ
ØAḣJÇ€Çj⁷

Thanks to @LeakyNun for golfing off 3 bytes!

Try it online!

How it works

Ṗ;Ṛ        Helper link. Argument: A (array)

Ṗ          Pop; yield A without its last element.
  Ṛ        Reversed; yield A with inverted order.
 ;         Concatenate the results to both sides.


ØAḣJÇ€Çj⁷  Main link. No arguments.

ØA         Alphabet; set link argument and return value to "A...Z".
   J       Indices; yield [1, ..., 26].
  ḣ        Head; take the first, the first two, etc. elements of the alphabet.
           This yields ["A", AB", ..., "A...Z"].
    ǀ     Apply the helper link to each string.
      Ç    Apply the helper link to the array itself.
       j⁷  Join, separating by linefeeds.
\$\endgroup\$
9
  • 3
    \$\begingroup\$ 3 bytes off \$\endgroup\$
    – Leaky Nun
    Aug 3, 2016 at 5:12
  • 4
    \$\begingroup\$ I'd be curious to know how in the world this works... \$\endgroup\$ Aug 3, 2016 at 5:34
  • \$\begingroup\$ maybe if use the link duplicator u can save one byte \$\endgroup\$
    – Leaky Nun
    Aug 3, 2016 at 5:35
  • \$\begingroup\$ @SocraticPhoenix I've added an explanation. \$\endgroup\$
    – Dennis
    Aug 3, 2016 at 5:49
  • 3
    \$\begingroup\$ @MathieuRodic Jelly uses a custom code page that encodes all 256 characters it understands as a single byte each. The bytes link in the header points to it. \$\endgroup\$
    – Dennis
    Aug 4, 2016 at 15:41
11
\$\begingroup\$

Python, 74 bytes

def f(x=66,s='A'):
 t=s+s[-2::-1];print t
 if x<91:f(x+1,s+chr(x));print t

A Python 2 function that prints and takes no arguments. The key idea is to generate the triangular there-and-back pattern with recursion. First consider this simpler function that prints the letters 'A' up to 'Z' and down back to 'A':

def f(x=65):
 t=chr(x);print t
 if x<90:f(x+1);print t 

The function first prints "A" (char-code 65), then recurses to print "B" (66) and so on to "Z" (90). From there, it stops recursing. On the way popping back down the recursive stack, it prints whatever character t it printed at the same layer, from "Y" back to "A".

The main code does the same, except it accumulates into s the string of letters so far, and prints the up-and-down string s+s[-2::-1].

Thanks to xsot for 2 bytes.

In Python 3, the same thing is a byte shorter (73 bytes) by putting everything on one line.

def f(x=66,s='A'):t=s+s[-2::-1];print(t);x>90or[f(x+1,s+chr(x)),print(t)]
\$\endgroup\$
3
  • \$\begingroup\$ You can save 2 bytes if you offset the variables, i.e. f(x=66,s='A'). This allows you to update s in the function call instead of the function body. \$\endgroup\$
    – xsot
    Aug 3, 2016 at 12:09
  • \$\begingroup\$ I think your Python 3 version, like its Python 2 relative, needs a value of 90 instead of 89 in order to have the longest row that goes all the way to Z and back. \$\endgroup\$
    – Tebbe
    Aug 4, 2016 at 19:29
  • \$\begingroup\$ @Tebbe Thanks, fixed them. \$\endgroup\$
    – xnor
    Aug 4, 2016 at 20:21
8
\$\begingroup\$

brainfuck, 1733 121 119 bytes

----[---->+<]>++.<++++++++++.<+++++[<+++++>-]<+>>>.<[>>[>.]<[>+>+<<-]>+.>[<<+> >-]<[<.]<-]>>[>[>]<[-]<[<]>>[.>]<<[.<]>]

Slightly more readable version:

----[---->+<]>++.<
++++++++++.<
+++++[<+++++>-]<+
>>
>.<
[
  >>[>.]<
  [>+>+<<-]
  >+.>
  [<<+>>-]
  <[<.]<
  -
]
>>
[
  >[>]<
  [-]
  <[<]>
  >[.>]<<[.<]>
]

Explanation possibly to come.

\$\endgroup\$
13
  • \$\begingroup\$ Try using a loop instead of building each character manually. \$\endgroup\$
    – Leaky Nun
    Aug 4, 2016 at 8:56
  • \$\begingroup\$ @LeakyNun I have no idea how to go about that. Any suggestions? \$\endgroup\$
    – DanTheMan
    Aug 4, 2016 at 9:00
  • 4
    \$\begingroup\$ Nice, so you only slept for 4 hours. \$\endgroup\$
    – Leaky Nun
    Aug 4, 2016 at 14:04
  • 1
    \$\begingroup\$ Congratulations on getting the program smaller than the output! \$\endgroup\$ Aug 5, 2016 at 19:53
  • 1
    \$\begingroup\$ How does one golf off 1612 bytes? \$\endgroup\$
    – qqq
    Dec 22, 2017 at 16:11
8
\$\begingroup\$

05AB1E, 20 13 12 6 bytes

Saved 2 bytes thanks to Adnan.
Saved 6 bytes thanks to Magic Octopus Urn and some new language functionality.

Aη€ûû»

Try it online!

Explanation

Aη       # push prefixes of alphabet
  €û     # palendromize each prefix
    û    # palendromize the whole list
     »   # join on newlines
\$\endgroup\$
8
  • \$\begingroup\$ Very nice! You can change Œ26£ to .p, which is the prefix command. Also, you can change D, to =, which prints without popping. \$\endgroup\$
    – Adnan
    Aug 3, 2016 at 10:02
  • \$\begingroup\$ Wow, clever trick with the gF,! \$\endgroup\$
    – Adnan
    Aug 3, 2016 at 10:05
  • \$\begingroup\$ @Adnan: Thanks! I knew there was a prefix command in there somewhere :) I seldom check the extended ones though. \$\endgroup\$
    – Emigna
    Aug 3, 2016 at 10:05
  • 2
    \$\begingroup\$ That bifurcate command  is very nice and a really neat feature. \$\endgroup\$
    – miles
    Aug 3, 2016 at 16:48
  • 1
    \$\begingroup\$ @carusocomputing: unfortunately û is newer than the challenge and would make this answer non-competing. \$\endgroup\$
    – Emigna
    Oct 25, 2016 at 20:09
6
\$\begingroup\$

Python 3, 97 bytes

s="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
a=[s[:x]+s[x::-1]for x in range(26)]
print('\n'.join(a+a[24::-1]))

Ideone it!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can also do '\n'.join(a+a[-2::-1]) \$\endgroup\$
    – Miguel
    Aug 3, 2016 at 16:40
  • \$\begingroup\$ 96 bytes! \$\endgroup\$
    – Miriam
    Jun 14, 2019 at 19:37
6
\$\begingroup\$

J, 26 23 22 bytes

f(f=:,1}.|.)\u:65+i.26

Explanation

,1}.|.  Monad f: Input: A
    |.  Reverse the items in A
 1}.    Drop the first item in the reversed A
,       Join A and the previous

f(f=:,1}.|.)\u:65+i.26
                  i.26  Create the range [0, 1, ..., 25]
               65+      Add 65 to each
             u:         Convert to characters to get 'A..Z'
  f=:,1}.|.             Define a verb f
 (         )\           Call f monadically on each prefix of 'A..Z'
f                       Call f again on that result
\$\endgroup\$
2
  • \$\begingroup\$ f=:,1}.|. try this \$\endgroup\$
    – Leaky Nun
    Aug 3, 2016 at 5:34
  • \$\begingroup\$ @LeakyNun Thanks I don't know why I thought they were different. \$\endgroup\$
    – miles
    Aug 3, 2016 at 5:41
5
\$\begingroup\$

Ruby, 71 bytes

Try it on repl.it

s=*?A..?Y
s+=[?Z]+s.reverse
puts s.map{|e|k=[*?A...e]*'';k+e+k.reverse}
\$\endgroup\$
1
  • \$\begingroup\$ This solution builds on yours, using absolute value arithmetic to save 3 bytes. \$\endgroup\$
    – benj2240
    Mar 23, 2018 at 16:59
5
\$\begingroup\$

><>, 60 bytes

1"AA"1[v
?v:1-:}>:5d*=
o>l  ?!v
{$-}:1[\ao]{:}+::"@Z"@=?;=2*

Try it online!

\$\endgroup\$
5
\$\begingroup\$

C, 272 247 234 230 144 137 bytes:

(Saved many bytes (272 -> 230) in my previous method thanks to great golfing tips & tricks from sigalor!)

(Saved nearly 100 bytes (230 -> 144) by switching to a better method.)

main(q,i,e,x){for(q=0;q<51;q++){i=q>25 ? 25-(q-25):q;for(e=65;e<66+i;e++)printf("%c",e);for(x=64+i;x>64;x--)printf("%c",x);printf("\n");}}

My first answer ever in C. I just started self-learning it recently, so let's see how it goes.

C it in Action! (Ideone)

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Ahhh, I just wanted to add a C answer as well... Whatever, I'll just help you then ;) First, this is code golf, you do not need to write perfect code. Compiler warnings are completely fine. That's why you can remove main()'s return type and even the #include <stdio.h>. GCC (and also sites like Ideone) are OK with that. Next, you can 'outsource' variable definitions to the parameter list of a function. Let for(int i=65;... become for(i=65... and change main() to main(i). Do the same for every other int variable as well (GCC defaults missing types to int). \$\endgroup\$
    – sigalor
    Aug 3, 2016 at 9:48
  • \$\begingroup\$ @sigalor Thanks for the tips! :) Just one question: why do I need to change main() to main(i)? \$\endgroup\$
    – R. Kap
    Aug 3, 2016 at 9:51
  • \$\begingroup\$ @sigalor Actually, now I'm getting a bunch of compilation errors. \$\endgroup\$
    – R. Kap
    Aug 3, 2016 at 9:54
  • \$\begingroup\$ When you do not declare your i variable in the for loop's initialization, you need to declare it somewhere else. And because (at least in C) the parameters of a function can be used like normal variables, there should be no problem. Btw, which compiler are you using? \$\endgroup\$
    – sigalor
    Aug 3, 2016 at 9:55
  • \$\begingroup\$ @sigalor Currently C in Ideone. I'm getting several <variable> undeclared errors. \$\endgroup\$
    – R. Kap
    Aug 3, 2016 at 9:56
5
\$\begingroup\$

JavaScript (ES6), 81 bytes

[...'ZYXWVUTSRQPONMLKJIHGFEDCBA'].reduce((p,c)=>c+`
`+p.replace(/^|$/gm,c)+`
`+c)
\$\endgroup\$
5
\$\begingroup\$

Mathematica 59 bytes

Column@FromCharacterCode[#@#@26+64]&[#-Abs@Range[1-#,#-1]&]
\$\endgroup\$
3
  • \$\begingroup\$ I think that removing the //Column from the end and prefixing your code with Column@ works. \$\endgroup\$
    – Yytsi
    Aug 3, 2016 at 15:17
  • 2
    \$\begingroup\$ You seem to have counted and as single bytes. I doubt that there's a single-byte code page that has them and is also supported by Mathematica out of the box. They'd by three bytes in UTF-8, so they don't really save anything over plain [[...]]. I'm also not sure how legitimate Column is since it only displays like a list of lines in a Mathematica notebook. Running this code from a script file wouldn't display anything. However, Print/@ is the same number of bytes and works in either case. \$\endgroup\$ Aug 4, 2016 at 10:12
  • \$\begingroup\$ If you want to make a link to a page with a long address, you can do the following: [what you see](actual link). Ex. [Example Link](https://www.example.com), which shows as Example Link \$\endgroup\$
    – Stan Strum
    Sep 16, 2017 at 16:47
4
\$\begingroup\$

Dyalog APL, 18 bytes

↑(⊣,⌽)(⊣,1↓⌽)¨,\⎕a
\$\endgroup\$
1
4
\$\begingroup\$

R, 63 61 59 bytes

for(i in c(1:26,25:1))cat(LETTERS[c(1:i,i:1-1)],"
",sep="")

Helpfully LETTTERS[0] doesn't return any characters.

Edit: lost one thanks to @leakynun

Edit: two more thanks to @plannapus

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can use a literal newline instead of \n \$\endgroup\$
    – Leaky Nun
    Aug 5, 2016 at 16:57
4
\$\begingroup\$

(plain) TeX, 209 bytes

\newcount~~65\newcount\j\j64\tt\def\a#1{{\loop\advance\j1\char\j\ifnum\j<#1\repeat\loop\advance\j-1\char\j\ifnum\j>65\repeat}\par}\def\c#1#2#3.{\loop\advance~#11\a~\ifnum~#2#3\repeat}A\par\c{}<90.\c->66.A\bye

Output:

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf! Nice first answer. \$\endgroup\$ Mar 15, 2021 at 13:11
3
\$\begingroup\$

TSQL, 159 bytes

DECLARE @ varchar(52)='ABCDEFGHIJKLMNOPQRSTUVWXY',@o varchar(max)SELECT @+='Z'+REVERSE(@)+'
',@o=@
WHILE''<@
SELECT @=STUFF(@,LEN(@)/2,2,''),@o=@+@o+@
PRINT @o

Fiddle

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I tried to do it but end up with 250+ bytes so never posted that. You, indeed, have a better solution then mine. Once again :) \$\endgroup\$ Aug 10, 2016 at 16:47
3
\$\begingroup\$

Javascript(using external library-Enumerable), 135 bytes

_.Range(1,51).WriteLine(x=>(g=_.Range(65,x>25?52-x:x)).Write("",y=>(w=String.fromCharCode)(y))+(g.Reverse().Skip(1).Write("",y=>w(y))))

Link to the library: https://github.com/mvegh1/Enumerable

Code explanation: Create a range of ints starting at 1, for a count of 51. For each, write a line according to complex pred. Do some JS wizardry with global variables and caching...and voila. For each int in WriteLine, we are creating the left hand range of ints and storing into global "g", and String Joining (Write) with "" delimiter and mapping each int to the String mapping to the int char code. Then, we concat the right hand side by taking the reversal of that sequence (and skipping the first element because that will match the last element of the original order...), writing with the same logic. EDIT: Updated the internals of Write in the library. An empty sequence will write an empty string instead of null now. This also shaved 15 bytes off the answer

enter image description here

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Don't you need to include bytes that you need to import the library? \$\endgroup\$ Aug 3, 2016 at 12:06
  • 1
    \$\begingroup\$ Idk, Ive posted over 20 answers using a library and you would be the first to say that to me. I dont think anybody really cares because my answers never win anyway \$\endgroup\$ Aug 3, 2016 at 12:58
  • 1
    \$\begingroup\$ @applejacks01 Pretty sure if you don't import it, then you have to say something like "JS + Enumerable" at the top. Similar to "Bash + Coreutils" \$\endgroup\$
    – mbomb007
    Aug 3, 2016 at 14:03
  • 2
    \$\begingroup\$ It's commonplace to count the import. Python + SymPy answers still have import sympy or from sympy import* at the top. The Bash + x answers are different because you only have to install x, not enable it somehow. \$\endgroup\$
    – Dennis
    Aug 3, 2016 at 15:29
  • 1
    \$\begingroup\$ @PatrickRoberts As long as the library existed before the challenge was posted, yes. Python answers make use of sympy, numpy, scipy, etc. all the time. \$\endgroup\$
    – Dennis
    Aug 4, 2016 at 2:49
3
\$\begingroup\$

Powershell, 61 52 bytes

Thanks to TimmyD for saving 9 bytes!

65..90+89..65|%{-join[char[]]((65..$_-ne$_)+$_..65)}

Loops through ASCII values for capital letters forwards, then backwards. For each number, this creates an array of the first X numbers, removes the X-1st number, then adds the reverse of the first X numbers, which is all then cast to chars and joined into a string.

\$\endgroup\$
1
  • \$\begingroup\$ Hey, that's good, thanks! I had plugged in 65..90..65 on a whim earlier with no success. Guess I forgot I could just add the ranges together. \$\endgroup\$
    – Ben Owen
    Aug 3, 2016 at 13:51
3
\$\begingroup\$

Python 2, 117 111 105 100 bytes

s="ABCDEFGHIJKLMNOPQRSTUVWXYZ"*2
for i in range(51):print(s[:-i-1]+s[-i-3::-1],s[:i]+s[i::-1])[26>i]

Run it

Thanks to @LeakyNun and @manatwork for pointing out a few byte saves.

Non-Golfed:

import string

def print_alphatriangle(n):
    offset = 1
    tail_offset = 3
    alpha = string.ascii_uppercase * n

    for i in range(len(alpha) - offset):
        if len(alpha) / 2 > i:
            print alpha[:i] + alpha[i::-offset]
            continue
        print alpha[:-i-offset] + alpha[-i-tail_offset::-offset]

This method works simply by string splicing an alphabet string that is concatenated together. Depending on whether i has reached a mid-way point of the string, it then starts to print out decreasing strings.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ You can remove both instances of 0 \$\endgroup\$
    – Leaky Nun
    Aug 3, 2016 at 16:53
  • \$\begingroup\$ Good catch! Thanks, updated @LeakyNun \$\endgroup\$
    – ospahiu
    Aug 3, 2016 at 16:54
  • 1
    \$\begingroup\$ Huh? len(s)/2? Why not 26? \$\endgroup\$
    – manatwork
    Aug 3, 2016 at 17:00
  • \$\begingroup\$ Good catch! @manatwork \$\endgroup\$
    – ospahiu
    Aug 3, 2016 at 17:04
  • 1
    \$\begingroup\$ See and apply marcog's tip from Tips for golfing in Python: print[s[:-i-1]+s[-i-3::-1],s[:i]+s[i::-1]][26>i]. \$\endgroup\$
    – manatwork
    Aug 3, 2016 at 17:09
3
\$\begingroup\$

Cheddar, 102 96 79 69 67 bytes

17 bytes thanks to Downgoat, and inspiration for 10 more.

"A"+(2@"27+@"(25|>1)).bytes.map(i->65@"(64+i)+@"((64+i)|>65)).vfuse

The fact that strings can concatenate but not arrays means that I would have to convert the two ranges to strings, concatenate, and then convert back to arrays.

Also, the fact that vfuse produces a leading newliens means that I would need to generate the first line manually and then concat to the rest.

@" as a dyad (two-argument function) can convert to string directly, but does not work for reversed range (if first argument is bigger than the second).

Range was half-inclusive. After the bug-fix it became inclusive.

Usage

cheddar> "A"+(2@"27+@"(25|>1)).bytes.map(i->(65@"(64+i)+@"((64+i)|>65))).vfuse
"A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
ABCDEFGFEDCBA
ABCDEFGHGFEDCBA
ABCDEFGHIHGFEDCBA
ABCDEFGHIJIHGFEDCBA
ABCDEFGHIJKJIHGFEDCBA
ABCDEFGHIJKLKJIHGFEDCBA
ABCDEFGHIJKLMLKJIHGFEDCBA
ABCDEFGHIJKLMNMLKJIHGFEDCBA
ABCDEFGHIJKLMNONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNONMLKJIHGFEDCBA
ABCDEFGHIJKLMNMLKJIHGFEDCBA
ABCDEFGHIJKLMLKJIHGFEDCBA
ABCDEFGHIJKLKJIHGFEDCBA
ABCDEFGHIJKJIHGFEDCBA
ABCDEFGHIJIHGFEDCBA
ABCDEFGHIHGFEDCBA
ABCDEFGHGFEDCBA
ABCDEFGFEDCBA
ABCDEFEDCBA
ABCDEDCBA
ABCDCBA
ABCBA
ABA
A"

Cheddar, 55 bytes (non-competing)

In the latest version with all the fixes, the answer is:

(|>25+24|>0).map(i->65@"(65+i)+(i?(64+i)@"65:"")).vfuse

but it was made after the challenge.

\$\endgroup\$
4
  • \$\begingroup\$ @"(1|>26) can be 1@"26 \$\endgroup\$
    – Downgoat
    Aug 3, 2016 at 18:17
  • \$\begingroup\$ String.letters can be (65@"91) \$\endgroup\$
    – Downgoat
    Aug 3, 2016 at 18:18
  • \$\begingroup\$ String.letters.slice(0,i) could maybe be 65@"(66+i) \$\endgroup\$
    – Downgoat
    Aug 3, 2016 at 18:19
  • \$\begingroup\$ Aha, I see you've been grating your bytecount. \$\endgroup\$
    – steenbergh
    Oct 27, 2016 at 7:52
3
\$\begingroup\$

C, 93 bytes

Call f() without arguments.

g(l,n){putchar(l);n?g(l+1,--n),putchar(l):0;}f(n){for(n=-26;++n<26;puts(""))g(65,25-abs(n));}

Try it on ideone.

\$\endgroup\$
3
\$\begingroup\$

Mathematica 98 96 92 bytes

There has to be a shorter way, even in Mathematica.

6 bytes saved thanks to Martin Ender.

r=Reverse@*Most; Print/@FromCharacterCode@Join[t=Join[s=Range[65,64+k],r@s]~Table~{k,26},r@t]
\$\endgroup\$
8
  • \$\begingroup\$ Can't Range[65,64+k] just be 65~Range~64+k? \$\endgroup\$
    – Yytsi
    Aug 3, 2016 at 10:31
  • \$\begingroup\$ That doesn't work. I think the +k somehow is left out. \$\endgroup\$
    – DavidC
    Aug 3, 2016 at 10:55
  • \$\begingroup\$ ~Table~ and Column@ should work though. And since you seem to use r only in conjunction with Most you might as well define it as Reverse@*Most. \$\endgroup\$ Aug 3, 2016 at 14:36
  • \$\begingroup\$ Table and Column now have infix notation. r=Reverse@Most appears not to work. \$\endgroup\$
    – DavidC
    Aug 3, 2016 at 15:00
  • \$\begingroup\$ It should be Reverse@*Most (the asterisk wasn't a typo ;)). I'm also not sure how legitimate Column actually is since it only displays like a list of lines in a Mathematica notebook. Running this code from a script file wouldn't display anything. However, Print/@ is the same number of bytes and works in either case. \$\endgroup\$ Aug 4, 2016 at 10:14
3
\$\begingroup\$

VBA, 94 bytes

Function T:For j=-25To 25:k=25-Abs(j):For i=-k To k:T=T &Chr(65+k-Abs(i)):Next:T=T &vbLf:Next

Call in Immediate window with ?T

Just to explain what's going on: I use Abs function twice, to reflect both the alphabet traverse and the line length. It's well suited to the task because of the single extreme value in both cases, which corresponds to the zero crossing of the pre-Abs variable.

As a simple set of commands in VBA Immediate window, rather than a program or function, the following would need 72 bytes:

For j=-25To 25:k=25-Abs(j):For i=-k To k:?Chr(65+k-Abs(i));:Next:?:Next

(with thanks to @GuitarPicker)

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I used some similar logic in one of my Iceland flag submissions. Couldn't you golf this further by running it entirely in the immediate window and skipping the function declaration, or does that break some rule I'm not familiar with? \$\endgroup\$ Aug 4, 2016 at 12:52
  • \$\begingroup\$ @GuitarPicker ; not sure whether running in immediate window counts as a complete program, but if so then 8 bytes less, effectively; instead of starting with Function T: , end with :?T (although it would only work once, because after that you'd need to reset T to "" - but who needs more than one of these triangles?) \$\endgroup\$
    – Joffan
    Aug 4, 2016 at 16:04
  • 2
    \$\begingroup\$ You don't even need T if you ? as you go with ;. \$\endgroup\$ Aug 4, 2016 at 16:10
  • \$\begingroup\$ I was able to shave it down to 71 using that method. Hint: you won't need vbCrLf either. \$\endgroup\$ Aug 4, 2016 at 16:18
  • 1
    \$\begingroup\$ yeah, I got the same; note that return is required. \$\endgroup\$
    – Joffan
    Aug 4, 2016 at 16:22
3
\$\begingroup\$

Python, 73 71 bytes

Thanks to @xnor for the recursion

f=lambda x=66,s='A',t='':x/92*t or t+f(x+1,s+chr(x),s+s[-2::-1]+"\n")+t

Explanation

  • Parameters:
    • x is the ascii value of the next letter in the alphabet
    • s is an accumulator for the alphabet
    • t is a line in the triangle (ie s + s backwards)
  • Return: t if the alphabet is done (ie we're at the center)
  • Else: t+f(...)+t with:
    • x incremented
    • s appended with the next letter
    • t reset to s + s backwards + \n

Update

  • -2 [16-08-05] Remove leading \n (+1) and shortened conditional (-3) all thanks to @xnor
\$\endgroup\$
1
  • 1
    \$\begingroup\$ What a clever method, pushing t through to the next loop. There's an extra leading newline though; x=66,s='A'' gets rid of it. The base case can be shortened to x/92*t or . \$\endgroup\$
    – xnor
    Aug 5, 2016 at 9:45
3
\$\begingroup\$

HTML + CSS, 884 characters

(763 characters HTML + 121 characters CSS)

Just expanding Leaky Nun's comment on MonkeyZeus's answer. (Though I might misread the comment…)

p{margin:0}p:before{content:"ABCDEFGH"}p:after{content:"HGFEDCBA"}a:before{content:"IJKLMNOP"}a:after{content:"PONMLKJI"}
<pre>A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
ABCDEFGFEDCBA
ABCDEFGHGFEDCBA
<p>I</p><p>IJI</p><p>IJKJI</p><p>IJKLKJI</p><p>IJKLMLKJI</p><p>IJKLMNMLKJI</p><p>IJKLMNONMLKJI</p><p>IJKLMNOPONMLKJI</p><p><a>Q</p><p><a>QRQ</p><p><a>QRSRQ</p><p><a>QRSTSRQ</p><p><a>QRSTUTSRQ</p><p><a>QRSTUVUTSRQ</p><p><a>QRSTUVWVUTSRQ</p><p><a>QRSTUVWXWVUTSRQ</p><p><a>QRSTUVWXYXWVUTSRQ</p><p><a>QRSTUVWXYZYXWVUTSRQ</p><p><a>QRSTUVWXYXWVUTSRQ</p><p><a>QRSTUVWXWVUTSRQ</p><p><a>QRSTUVWVUTSRQ</p><p><a>QRSTUVUTSRQ</p><p><a>QRSTUTSRQ</p><p><a>QRSTSRQ</p><p><a>QRSRQ</p><p><a>QRQ</p><p><a>Q</a></p><p>IJKLMNOPONMLKJI</p><p>IJKLMNONMLKJI</p><p>IJKLMNMLKJI</p><p>IJKLMLKJI</p><p>IJKLKJI</p><p>IJKJI</p><p>IJI</p><p>I</p>ABCDEFGHGFEDCBA
ABCDEFGFEDCBA
ABCDEFEDCBA
ABCDEDCBA
ABCDCBA
ABCBA
ABA
A

\$\endgroup\$
3
\$\begingroup\$

Brachylog, 37 29 bytes

Credits to Fatalize for his assistance throughout.

4 bytes thanks to Fatalize, and inspiration for another 4 bytes.

@A:1&e:"a"yr:1&cw@Nw\
:Lc.r.!

Try it online!

Predicate 0 (Main predicate)

@A:1&e:"a"yr:1&cw@Nw\
@A:1&                  Apply predicate 1 to @A, which is
                       basically "abcdefghijklmnopqrstuvwxyz"
     e                 Choose one element from the result (choice point)
      :"a"yr               generate substring from element to "a"
            :1&            apply predicate 1
               c           concatenate
                w          write to STDOUT
                 @Nw       write "\n" to STDOUT
                    \  Backtrack to last choice point to choose
                       another element until there is no more
                       choice left, then halt.

Predicate 1 (Auxiliary predicate)

This basically builds a palindrome from the given string.

:Lc.r.!
:Lc.     output is [input:L]
   .r.   output reversed is still output
      !  stop searching after the first output
\$\endgroup\$
3
3
\$\begingroup\$

R, 127 125 bytes

k=cat;L=LETTERS;for(i in 1:26)k(c(L[1:i],L[(i-1):0],"\n"));for(i in 1:26)k(c(L[0:(26-i)],L[ifelse((25-i)>=0,25-i,0):0],"\n"))

Not completely satisfied with this solution, especially the two for loops, but couldn't come with something better !
LETTERS contains the uppercase letters.

Ungolfed :

for(i in 1:26){
  cat(c(LETTERS[1:i],LETTERS[(i-1):0],"\n"))
               }

for(i in 1:26){
  cat(c(LETTERS[0:(26-i)],LETTERS[ifelse((25-i)>=0,25-i,0):0],"\n"))
               }

ifelse is a shorter way for unsing if... else... and works this way : ifelse(condition,action if TRUE, action if FALSE)

An other 125 bytes' solution :

for(i in 1:26)(k=cat)(c((L=LETTERS)[1:i],L[(i-1):0],"\n"));for(i in 1:26)k(c(L[0:(26-i)],L[ifelse((25-i)>=0,25-i,0):0],"\n"))
\$\endgroup\$
1
3
\$\begingroup\$

Java 131 bytes

Without using String (131 bytes)

public static void main(String[] args) {
    for(int i = 0 ,k=1; i>-1; i+=k){
        for(int c= 65, d = 1; c>64;){
            d = d>-1 & c < 65+i?1:-1;
            System.out.print((char)c+((c+=d)<65?"\n":""));
        }
        k = k>-1 & i < 25?1:-1;
    }
}

Codegolfed

for(int i=0,k=1;i>-1;k=k>-1&i<25?1:-1,i+=k)for(int c=65,d=1;c>64;d=d>-1&c<65+i?1:-1,System.out.print((char)c+((c+=d)<65?"\n":"")));

With String(173 bytes)

String a="abcdefghijklmnopqrstuvwxyz";
for(int i = 1 ,k=1; i>0; i+=k==1?1:-1){
    System.out.println(a.substring(0,i)+new StringBuilder(a).reverse().substring(27-i));
    k = k>-1 & i < 26?1:-1;
}

Codegolfed

String a="abcdefghijklmnopqrstuvwxyz";for(int i=1,k=1;i>0;k=k>-1&i<26?1:-1,System.out.println(a.substring(0,i)+new StringBuilder(a).reverse().substring(27-i)),i+=k==1?1:-1);

Thanks to manatwork and Kevin Cruijssen

\$\endgroup\$
8
  • 2
    \$\begingroup\$ Welcome to PPCG. Please read the “How should I answer a code golf? Any hints?” section in the code-golf tag's info page. Answers to this kind of challenges are expected to present efforts to reduce the code size. In this you may find help in Tips for golfing in Java and Tips for golfing in <all languages>. \$\endgroup\$
    – manatwork
    Aug 4, 2016 at 8:59
  • 1
    \$\begingroup\$ There you use 4 ternary operators and all conditions are enclosed in parenthesis. You can remove those to save 8 characters. \$\endgroup\$
    – manatwork
    Aug 4, 2016 at 9:13
  • 1
    \$\begingroup\$ d and k can not go below -1, right? Then you can replace d!=-1 with d>-1, same for k. (BTW, you forgot to fix the golfed version.) \$\endgroup\$
    – manatwork
    Aug 4, 2016 at 10:12
  • \$\begingroup\$ Moved statements from loop body to increment statement section to save 3 bytes.. \$\endgroup\$
    – Syamesh K
    Aug 4, 2016 at 11:39
  • 1
    \$\begingroup\$ Hi, I know it's been quite a while, but you can golf two things: i+=k==1?1:-1 can be i+=k and System.out.print((char)c+(c+d<65?"\n":"")),c+=d==1?1:-1); can be System.out.print((char)c+((c+=d)<65?"\n":"")));. So in total it becomes (131 bytes): for(int i=0,k=1;i>-1;k=k>-1&i<25?1:-1,i+=k)for(int c=65,d=1;c>64;d=d>-1&c<65+i?1:-1,System.out.print((char)c+((c+=d)<65?"\n":""))); \$\endgroup\$ May 1, 2017 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.