16
\$\begingroup\$

Simpler version of this

Task

You must create a program that outputs a triangle of a given size N.

  • A triangle is made of 3 identical triangles
  • A triangle of size N should be made of N lines
  • A triangle's line starts from 1 star, and increases by 2 stars each line

Test Cases:

1 ->

 *
* *

3 ->

     *
    ***
   *****
  *     *
 ***   ***
***** *****

5 ->

         *
        ***
       *****
      *******
     *********
    *         *
   ***       ***
  *****     *****
 *******   *******
********* *********

10 ->


                   *
                  ***
                 *****
                *******
               *********
              ***********
             *************
            ***************
           *****************
          *******************
         *                   *
        ***                 ***
       *****               *****
      *******             *******
     *********           *********
    ***********         ***********
   *************       *************
  ***************     ***************
 *****************   *****************
******************* *******************

Scoring:

This is code-golf so shortest code size wins!

Trailing whitespace is allowed

Credits to Ninsuo for the puzzle

\$\endgroup\$
5
  • \$\begingroup\$ im assuming its alright still? (i added the puzzle to the top) \$\endgroup\$
    – DialFrost
    Feb 11 at 13:45
  • 1
    \$\begingroup\$ Yes, it's not as nearly duplicate as I initially thought. Anyway, we usually link related challenges for the benefit of readers \$\endgroup\$
    – Luis Mendo
    Feb 11 at 13:46
  • \$\begingroup\$ i've added the link js now thx for the comment anyways! \$\endgroup\$
    – DialFrost
    Feb 11 at 13:47
  • 6
    \$\begingroup\$ Can we use a different character than * to create the triangles? And any reason why the input is always a triangular number (which 5 isn't as mentioned by @Giuseppe), since any positive integer works for the intended output? \$\endgroup\$ Feb 11 at 14:13
  • 4
    \$\begingroup\$ rules on leading/trailing whitespace? \$\endgroup\$
    – Jonah
    Feb 11 at 17:17

18 Answers 18

9
\$\begingroup\$

Python 3, 74 bytes

lambda n:[print(i//n*f"{i%n*'**'+'*':^{8*n>>i//n}}")for i in range(n,3*n)]

Try it online!

Deera Wijesundara saved 2 bytes by suggesting print-based I/O instead of "\n".join.

Explanation

For each i in range(n,3*n), we center i%n*2+1 asterisks in 8*n>>i//n spaces and repeat this string i//n times.

i i%n i%n*'**'+'*' 8*n>>i//n i//n
n 0 * 4n 1
n+1 1 *** 4n 1
n+2 2 ***** 4n 1
2n 0 * 2n 2
2n+1 1 *** 2n 2
2n+2 2 ***** 2n 2
  • i%n*'**'+'*' is a byte shorter than (i%n*2+1)*'*'.
  • f"{s:^{n}}" is an icky but short way to write (s).center(n).
\$\endgroup\$
2
  • \$\begingroup\$ You can add print and make it 2 bytes shorter lambda n:[print(i//n*f"{i%n*'**'+'*':^{8*n>>i//n}}")for i in range(n,3*n)] \$\endgroup\$ Feb 12 at 6:00
  • \$\begingroup\$ you can add both io but it'll add 6 more bytes n=int(input());[print(i//n*f"{i%n*'**'+'*':^{8*n>>i//n}}")for i in range(n,3*n)] \$\endgroup\$ Feb 12 at 6:04
5
\$\begingroup\$

Canvas, 11 bytes

*×[]:{│]∔/│

Try it here!

Explanation:
*x[]:{|]+/| | Full code (replaced with ASCII)
------------+-----------------------------------------
*           | Push '*'
 x          | Repeat <input> times horizontally
  []        | List of prefixes
    :       | Duplicate
     { ]    | Map over each element
      |     | Palindromize horizontally with 1 overlap
        +   | Add the two lists together
         /  | Anti-diagonalize
          | | Palindromize horizontally with 1 overlap
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Anti-diagonalize and palindromize are quite nice primitives. \$\endgroup\$
    – Jonah
    Feb 12 at 14:51
  • \$\begingroup\$ @Jonah Canvas is literally designed for ASCII art, so taking advantage of common ASCII art features like diagonals and symmetry is something of a must... really comes in handy for these types of challenges! \$\endgroup\$
    – hakr14
    Feb 12 at 18:05
5
\$\begingroup\$

Charcoal, 12 bytes

NθF²«G⌊θ*↖‖O

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

Nθ

Input the size.

F²«

Repeat twice.

G⌊θ*

Draw half of a triangle. The first time, this draws the left half of the bottom left triangle; the second time, the left half of the top triangle.

Move to the next triangle. (See below as to why this moves left instead of right. This command has no effect on the second iteration.)

‖O

Reflect to complete the triangle. On the first iteration, this also reflects the current position to where it needs to be. On the second iteration, this also reflects the bottom left triangle to create the bottom right triangle.

\$\endgroup\$
4
  • \$\begingroup\$ how do code in charcoal so well? like how do know what to use in the verbose lang of charcoal \$\endgroup\$
    – DialFrost
    Feb 12 at 0:25
  • \$\begingroup\$ @DialFrost Practice, mostly (after all I've written over 1,000 programs in Charcoal) but obviously the Wiki was very helpful for getting started. \$\endgroup\$
    – Neil
    Feb 12 at 0:52
  • \$\begingroup\$ what wiki? the github page? (i wanna learn a golf lang soon lol) \$\endgroup\$
    – DialFrost
    Feb 12 at 0:53
  • \$\begingroup\$ @DialFrost Yeah, the wiki on the github. \$\endgroup\$
    – Neil
    Feb 12 at 0:54
4
\$\begingroup\$

05AB1E, 20 16 bytes

·ÅÉ'*×DāRúí.º«.c

Try it online or verify the test cases in the range \$[1,10]\$.

Explanation:

           #  e.g. input=3
·          # Double the (implicit) input-integer
           #  STACK: 6
 ÅÉ        # Pop and push a list of all odd numbers below this
           #  STACK: [1,3,5]
   '*×    '# Map each to that many "*" as strings
           #  STACK: ["*","***","*****"]
D          # Duplicate this list
           #  STACK: ["*","***","*****"],["*","***","*****"]
 ā         # Push a list in the range [1,length] (without popping)
           # (which is basically a list in the range [1,input])
           #  STACK: ["*","***","*****"],["*","***","*****"],[1,2,3]
  R        # Reverse it to range [input,1]
           #  STACK: ["*","***","*****"],["*","***","*****"],[3,2,1]
   ú       # Pad the strings of the top copy with that many leading spaces
           #  STACK: ["*","***","*****"],["   *","  ***"," *****"]
    í      # Reverse each string in the list so the spaces are trailing
           #  STACK: ["*","***","*****"],["*   ","***  ","***** "]
     .º    # Overlapping mirror each string
           #  STACK: ["*","***","*****"],["*     *","***   ***","***** *****"]
       «   # Merge the two lists of lines together
           #  STACK: ["*","***","*****","*     *","***   ***","***** *****"]
        .c # Join each line by newlines, and centralize it
           #  STACK: "     *\n    ***\n   *****\n  *     *\n ***   ***\n***** *****"
           # (after which the result is output implicitly)
\$\endgroup\$
4
\$\begingroup\$

Excel, 94 bytes

=LET(x,SEQUENCE(A1*2),a,REPT(" ",A1*2-x),b,REPT("*",MOD(x-1,A1)*2+1),a&b&REPT(a&" "&a&b,x>A1))

Link to Spreasheet

\$\endgroup\$
4
\$\begingroup\$

J, 39 37 bytes

'* '{~](](=|.)/@,:{.)(>i.@-+/|@i:)@+:

Try it online!

-2 thanks to Lynn!

Includes leading whitespace that can be removed with a few bytes.

Not super golfy but the concept is fun:

how

Let's take n=3 as our example:

  • (>i.@-+/|@i:)@+: Create a single triangle double the requested input size:

    0 0 0 0 0 0 1 0 0 0 0 0 0
    0 0 0 0 0 1 1 1 0 0 0 0 0
    0 0 0 0 1 1 1 1 1 0 0 0 0
    0 0 0 1 1 1 1 1 1 1 0 0 0
    0 0 1 1 1 1 1 1 1 1 1 0 0
    0 1 1 1 1 1 1 1 1 1 1 1 0
    
  • ](..........{.) Take the first n lines of that:

    0 0 0 0 0 0 1 0 0 0 0 0 0
    0 0 0 0 0 1 1 1 0 0 0 0 0
    0 0 0 0 1 1 1 1 1 0 0 0 0
    
  • ].......,: And append it to the big triangle, auto-filling the extra rows with zeros:

    0 0 0 0 0 0 1 0 0 0 0 0 0
    0 0 0 0 0 1 1 1 0 0 0 0 0
    0 0 0 0 1 1 1 1 1 0 0 0 0
    0 0 0 1 1 1 1 1 1 1 0 0 0
    0 0 1 1 1 1 1 1 1 1 1 0 0
    0 1 1 1 1 1 1 1 1 1 1 1 0
    
    0 0 0 0 0 0 1 0 0 0 0 0 0
    0 0 0 0 0 1 1 1 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 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0
    
  • (=|.)/@ Reverse rows of the little triangle and check where the planes are still equal:

    0 0 0 0 0 0 1 0 0 0 0 0 0
    0 0 0 0 0 1 1 1 0 0 0 0 0
    0 0 0 0 1 1 1 1 1 0 0 0 0
    0 0 0 1 1 1 1 1 1 1 0 0 0
    0 0 1 1 1 1 1 1 1 1 1 0 0
    0 1 1 1 1 1 1 1 1 1 1 1 0
    
         = elementwise?
    
    0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 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 1 1 1 0 0 0 0 0
    0 0 0 0 0 0 1 0 0 0 0 0 0
    
               v
    
    1 1 1 1 1 1 0 1 1 1 1 1 1
    1 1 1 1 1 0 0 0 1 1 1 1 1
    1 1 1 1 0 0 0 0 0 1 1 1 1
    1 1 1 0 1 1 1 1 1 0 1 1 1
    1 1 0 0 0 1 1 1 0 0 0 1 1
    1 0 0 0 0 0 1 0 0 0 0 0 1
    
  • '* '{~ Convert to asterisks and spaces:

          *      
         ***     
        *****    
       *     *   
      ***   ***  
     ***** *****
    
\$\endgroup\$
2
  • 2
    \$\begingroup\$ You can replace +|. by =|., then get rid of 2| and invert ' *' to '* '. \$\endgroup\$
    – Lynn
    Feb 12 at 14:14
  • \$\begingroup\$ Very nice, thanks Lynn! \$\endgroup\$
    – Jonah
    Feb 12 at 14:39
3
\$\begingroup\$

Python 3.8 (pre-release), 114 bytes

def f(n,x=1):[print([n*(p:=" "),(t:=(s:=p*(~-n-i))+"*"+"**"*i+s)+p][x]+t)for i in range(0if x and f(n,0)else 0+n)]

Try it online!

Less-golfed version

def f(n, drawingTopPart=True):
    for i in range(n):
        space = " "
        spacing = space*(n-i-1)
        stars = spacing + '*' + '**' * i + spacing
        print(n*space + stars) if drawingTopPart else print(stars + space + stars)
    if drawingTopPart:
        f(n, False)
\$\endgroup\$
3
  • \$\begingroup\$ Is “0+n” necessary? \$\endgroup\$
    – ophact
    Feb 11 at 15:11
  • \$\begingroup\$ @ophact I couldn't think of any other way to do a singular conditional recursive call \$\endgroup\$
    – rebane2001
    Feb 11 at 17:19
  • \$\begingroup\$ You can do 0if x and f(n,0)else 0+n=>x and f(n,0)or n, since the function never returns anything, it's value is None which is falsy, which means that n is always the value of the expression \$\endgroup\$
    – AnttiP
    Feb 11 at 20:19
3
\$\begingroup\$

Ruby, 70 bytes

->n{a=[]
n.times{|i|puts" "*n+b=(?**i-=~i).center(n*2)
a<<b*2}
puts a}

Try it online!

Prints the single triangle as it iterates while building up an array of double triangles.

Then dumps a printout of the array at the end.

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

JavaScript (ES6), 80 bytes

f=(n,x=y=h=n*2)=>y?` *
`[--x+h?x>=y-h&x<=h-y^y<=n&x*x<y*y:(x=h,y--,2)]+f(n,x):''

Try it online!

Patterns

Coordinates:

  • \$y\$ goes from \$2n\$ at the top to \$1\$ at the bottom
  • \$x\$ goes from \$2n-1\$ on the left to \$-2n+1\$ on the right

The examples below are given with \$n=3\$.

x >= y - h        x <= h - y
               
XXXXXX-----       -----XXXXXX       -----X-----
XXXXXXX----       ----XXXXXXX       ----XXX----
XXXXXXXX---  AND  ---XXXXXXXX  -->  ---XXXXX---
XXXXXXXXX--       --XXXXXXXXX       --XXXXXXX--
XXXXXXXXXX-       -XXXXXXXXXX       -XXXXXXXXX-
XXXXXXXXXXX       XXXXXXXXXXX       XXXXXXXXXXX

y <= n            x² < y²
               
-----------       XXXXXXXXXXX       -----------
-----------       -XXXXXXXXX-       -----------
-----------  AND  --XXXXXXX--  -->  -----------
XXXXXXXXXXX       ---XXXXX---       ---XXXXX---
XXXXXXXXXXX       ----XXX----       ----XXX----
XXXXXXXXXXX       -----X-----       -----X-----


-----X-----       -----------       -----X-----
----XXX----       -----------       ----XXX----
---XXXXX---  XOR  -----------  -->  ---XXXXX---
--XXXXXXX--       ---XXXXX---       --X-----X--
-XXXXXXXXX-       ----XXX----       -XXX---XXX-
XXXXXXXXXXX       -----X-----       XXXXX-XXXXX
\$\endgroup\$
2
\$\begingroup\$

Python NumPy, 95 bytes

lambda n:where((t:=tril(1>tri(4*n)[::-1])[2*n:])^(t[::-1]&t[:,n:n+1]),*'* ')
from numpy import*

Attempt This Online!

Old Python NumPy, 99 bytes

lambda n:[r:=tri(n),z:=0*r,l:=1-r[::-1]]and where(bmat("z l r z;l r l r"),*'* ')
from numpy import*

Attempt This Online!

Returns a numpy array of "*"s and " "s.

\$\endgroup\$
2
\$\begingroup\$

Julia 1.0, 86 bytes

n/k=1:n.|>j->((s=" "^(k-j))*" "*"*"^(2j-1)*s)^(1+(n==k))
~n=n./[2n,n].|>l->println.(l)

Try it online!

Golfing David Scholz's answer (cannot comment under other people solutions yet!)

Basically got rid of join by nesting the println call. println also gives you trailing \n for free. Finally I removed i iteration index as it can be expressed in terms of j

\$\endgroup\$
4
  • 1
    \$\begingroup\$ This is really clever! (I'll upvote in 11 hours, I've used mine all :p) \$\endgroup\$ Feb 17 at 12:42
  • \$\begingroup\$ aha thanks! :D also, the other thing to point out is that counts for 3 bytes, simply replacing it saved 6 bytes \$\endgroup\$
    – amelies
    Feb 17 at 13:00
  • \$\begingroup\$ Yes indeed. I didn't know that one could remove the brackets for two arguments as well! \$\endgroup\$ Feb 17 at 16:35
  • 1
    \$\begingroup\$ you can even do it for three arguments tio \$\endgroup\$
    – amelies
    Feb 17 at 18:47
1
\$\begingroup\$

Python 3.8 (pre-release), 96 bytes

lambda n:'\n'.join(' '*(d:=2*n-1-i)+(c:='*'*(1+i%n*2))+('  '*d+' '+c)*(i>=n)for i in range(n+n))

Try it online!

\$\endgroup\$
1
1
\$\begingroup\$

Retina 0.8.2, 54 bytes

.+
$**
.
$._$*_$.'$* $`*$`$.'$* ¶
_+
$&$%'¶$%' 
_
 
O`

Try it online! Link includes test cases. Explanation:

.+
$**

Convert the input to a string of asterisks.

.
$._$*_$.'$* $`*$`$.'$* ¶

Create a triangle of asterisks indented by underscores. $._$*_ is the string of asterisks replaced by underscores. $.'$* is the space padding on either side of the triangle. $`*$` is the triangle.

_+
$&$%'¶$%' 

Duplicate each line. $&$%' ends up keeping the first line the same, while the $%' causes the second copies of the lines to have an extra copy of the triangle, but without the indent.

_
 

Convert the underscores back to spaces.

O`

Sort the lines into order. This puts the lines with the most spaces first, thus grouping the top triangle's lines back together (and also the remaining lines of the bottom double triangle of course).

\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 41 bytes

Prompts for n

(⌽0 1↓m),m←⊃(-⍳2×n)↑¨(m,¯1+2×m←⍳n←⎕)⍴¨'*'

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
1
\$\begingroup\$

Vyxal C, 35 bytes

λhd›×*;→ẋė:£ƛ←†;¥ƛ←†:?d‹nhd-ð*JȮJ;J

Try it Online!

Explanation

λhd›×*;→  Simple Lambda
λ         Start lambda
 h        Get head
  d›      Double and add 1
    ×*    Repeat it "*" time
      ;→  Close lambda and set it to var.

ẋė:£ƛ←†;  Top triangle
ẋė        Make an empty list with length n and generate tuple (index, item)
  :£      Duplicate tuple and set it to the register
    ƛ     Map through tuple of (index, item)
     ←†;  Get var, call it and close lambda

¥ƛ←†:?d‹nhd-ð*JȮJ;J  Bottom left ans right triangle
¥ƛ                   Get register (index, item) and start a mapping lambda
  ←†:                Get var, call it and duplicate
     ?d‹             Double n and increment by one
        hd-          Get head, double and decrement by one
           ð*        Repeat space that many times
             J       Join the left triangle row with spaces
              ȮJ     Get second to last item (left triangle row) and join
                ;J   Join the top triangle with the bottom triangles

C flag centers everything with spaces.
\$\endgroup\$
1
\$\begingroup\$

Julia, 129 bytes

l="\n"
△(n,k)=((i,j)->(" "^(k-j+1)*"*"^i*" "^(k-j))^(n==k ? 2 : 1)).(1:2:2n,1:n)
~n=print(join(△(n,2n),l),l,join(△(n,n),l))

Try it online!

I had a hard time with this one, any optimizations are highly appreciated!

The function takes two arguments n,k whereby n is the size of the triangle. The parameter k determines the number of whitespaces for each row of the triangle.

I have not found a way to get rid of the join operator, which joins the array of strings with \n as a separator. This costs me 8 bytes already.

\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 58 bytes

!n=1:2n.|>i->((s=' '^(2n-i))*'*'^2(~-i%n)*"* $s")^-~+(i>n)

Try it online!

output is a list of strings

\$\endgroup\$
1
\$\begingroup\$

Pari/GP, 79 bytes

n->for(i=1,m=2*n,print(Strchr([32+10*(i<=n||i+abs(j)>m&&i>-j)|j<-[1-m..i-1]])))

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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