g | x | w | all
Bytes Lang Time Link
032Uiua241122T230047Znoodle p
090JavaScript Node.js241125T030230Ztsh
059J241125T223318ZJonah
021Jelly241123T182425ZJonathan
029Japt R241125T154839ZShaggy
029Japt R241125T133742Znoodle p
02205AB1E241125T103434ZKevin Cr
080Retina241122T235803ZNeil
097APL+WIN241123T154037ZGraham
131JavaScript Node.js241122T192810Zl4m2
024Charcoal241122T150322ZNeil

Uiua, 41 35 33 32 bytes

⍉⊂⇌⊸↘1⍉⬚@ ⧅⇌+@1⊚⇌⧈-[⍥(⊃-√⊸⍜√⌊)∞]

Try it: Uiua pad.

-2 thanks to ovs.

Explanation: Consider the input 119.

The greedy square-finding algorithm is implemented by repeatedly subtracting the greatest square less than N until a fixed point is reached, collecting intermediate square roots in an array. The greatest square less than N is retrieved by ⍜√⌊ - "under square root floor", meaning take the square root, floor it (round it down to an integer), and square it again.

      [⍥(⊃-√⊸⍜√⌊)∞] 119
[0 0 1 1 1 4 10]

We take the consecutive differences:

      ⧈-
[0 1 0 0 3 6]

Reversing this and passing it to ⊚ where, which keeps A[i] copies of each index i of A, gives the left-half of the bottom row:

      ⇌
[6 3 0 0 1 0 0]
      ⊚
[0 0 0 0 0 0 1 1 1 4]
      +@1
"1111112225"

Reversing each prefix of this string, padding with spaces, gives the right-half of the triangle:

      ⬚@ ⧅⇌
╭─              
╷ "1         "  
  "11        "  
  "111       "  
  "1111      "  
  "11111     "  
  "111111    "  
  "2111111   "  
  "22111111  "  
  "222111111 "  
  "5222111111"  
               ╯

The last thing to do is reflect the array horizontally, and the task is complete:

      ⍉⊂⇌⊸↘1⍉
╭─                       
╷ "         1         "  
  "        111        "  
  "       11111       "  
  "      1111111      "  
  "     111111111     "  
  "    11111111111    "  
  "   1111112111111   "  
  "  111111222111111  "  
  " 11111122222111111 "  
  "1111112225222111111"  
                        ╯

JavaScript (Node.js), 90 bytes

f=(m,i=n=r=m,t=(g=v=>i*i>m?--i?v+g(v)+v:v+'':g(-~v,m-=i*i,r-=i+i-1))` `)=>r?f(r,n)+`
`+t:t

Try it online!

f=(
  m,   // number for render
  i=   // loop from width (`n`) to 1
  n=   // width of output
  r=m, // remaining number for next (upper) line
  t=(  // current line
    g= // loop for `i`
    v=> // value for current (most left / right side) character
      i*i>m?
        // do not need another triangle
        // render a single character if it is center
        // or pair of characters with recursive for their center
        --i?v+g(v)+v:v+'':
        // do need another triangle
        // value for render increased
        // update `m` and `r` accordingly
        g(-~v,m-=i*i,r-=i+i-1)
    )` ` // initially, the character for render is a space
  )=>
    r? // if there are number remaining for next (upper) line
      f(r,n)+`\n`+t: // render next (upper) line then current one
      t // that is last line now

J, 59 bytes

[:|.' 123456789'{~[:+/@(i.@->/0{|@i:)1+2%:2-/\(-<.&.%:)^:a:

Try it online!

Jelly,  24  21 bytes

ƽ²ạƊƬIN½r1RṠSz⁶UŒBṚY

A full program that accepts a positive integer and prints the triangle.

Try it online!

How?

Calculate the squares, then for each create half the triangle back-to-front and upside-down using ones, then add these up and rotate and reflect to produce the full, superimposed triangle:

e.g. \$22 = 4^2 + 2^2 + 1^2 + 1^2\$:

       squares: [4,                            2,          1,    1]
half-triangles: [[[1,1,1,1],[1,1,1],[1,1],[1]],[[1,1],[1]],[[1]],[[1]]]
        summed:  [[4,2,1,1],[2,1,1],[1,1],[1]]
 fill & rotate:  [[1,0,0,0],[1,1,0,0],[2,1,1,0],[4,2,1,1]]
       reflect:  [0,0,0,1,0,0,0],[0,0,1,1,1,0,0],[0,1,1,2,1,1,0],[1,1,2,4,2,1,1]]
   print lines:     1   
                   111  
                  11211 
                 1124211
ƽ²ạƊƬIN½r1RṠSz⁶UŒBṚY - Link: positive integer, N
     Ƭ                - collect until a fixed point under:
    Ɗ                 -   last three links as a monad - f(Current):
ƽ                    -     integer square root {Current}
  ²                   -     squared
   ạ                  -     absolute difference {Current}
      I               - forward differences
       N              - negated
        ½             - square rooted
         r1           - range to 1 (vectorises)
           R          - range
            Ṡ         - signs
             S        - sum (vectorises)
              z⁶      - transpose filling with space characters
                U     - reverse each
                 ŒB   - bounce each
                   Ṛ  - reverse
                    Y - join with newline characters

Japt -R, 29 bytes

Was tapping away at this over the weekend and then got beaten to the punch by a very similar solution.

9ƵNpU¬f)̲ÃNäa ËçEÃŬå+ ù Ëê

Try it

9ƵNpU¬f)̲ÃNäa ËçEÃŬå+ ù Ëê     :Implicit input of integer U
9Æ                                :Map the range [0,9)
 µ                                :  Decrement U by
  N                               :    Array of all inputs (i.e., [U] initially)
   p                              :    Push
    U¬                            :      Square root of U
      f                           :      Floor
       )                          :    End push
        Ì                         :    Last element
         ²                        :    Squared
          Ã                       :End map
           Nä                     :Consecutive pairs of array reduced by
             a                    :  Absolute difference
               Ë                  :Map each D at 0-based index E
                çE                :  E repeated D times
                  Ã               :End map
                   Å              :Slice off first element
                    ¬             :Join
                     å+           :Cumulatively reduce by concatenating
                        ù         :Left pad each with spaces to the length of the longest
                          Ë       :Map
                           ê      :  Palindromise
                                  :Implicit output joined with newlines

Japt -R, 33 29 bytes

AƵV=U¬f ²V¬Ãä- ËçEÄìå+ mê û

Try it

Thanks to Shaggy for -4 with some nice Japt knowledge.

I haven't used Japt in quite a while and I remembered that it had functions to palindromize a string and center-pad an array, so this seemed like a good opportunity to pick it back up.

05AB1E, 22 bytes

ΔDtïDˆn-}¯üαÅ1ƶ˜η€ûJ.c

Try it online or verify all test cases.

Explanation:

Step 1: Get the greedy list of squares:

Δ        # Loop until the result no longer changes (using the implicit input)
 D       #  Duplicate the current integer
  t      #  Take the square-root of the copy
   ï     #  Floor it to an integer
    Dˆ   #  Add a copy of that to the global array
      n  #  Take the square of that floored square root
       - #  Subtract it from the current integer for the next iteration
}¯       # After the changes-loop: push the global array
         #  e.g. input=119 → [10,4,1,1,1,0]

Try just step 1 online.

Step 2: Create the first halve of the bottom row of the output:

üα       # For each overlapping pair: get its absolute difference
         #  → [6,3,0,0,1]
  Å1     # Convert each value to a list of that many 1s
         #  → [[1,1,1,1,1,1],[1,1,1],[],[],[1]]
    ƶ    # Multiply each inner value with its 1-based index
         #  → [[1,1,1,1,1,1],[2,2,2],[],[],[5]]
     ˜   # Flatten this list of lists
         #  → [1,1,1,1,1,1,2,2,2,5]

Try just the first two steps online.

Step 3: Use it to create the entire triangle and format it to the correct output:

η        # Get the prefixes of this list
         #  → [[1],[1,1],...,[1,1,1,1,1,1,2,2,2,5]]
 €û      # Palindromize each inner list
         #  → [[1],[1,1,1],...,[1,1,1,1,1,1,2,2,2,5,2,2,2,1,1,1,1,1,1]]
   J     # Join each inner list together to a string
         #  → ["1","111",...,"1111112225222111111"]
    .c   # Centralize; join this list by newlines,
         # and add leading spaces to center all lines
         #  → "         1
         #             111
         #             ...
         #     1111112225222111111"
         # (after which it is output implicitly as result)

Retina, 81 80 bytes

.+
*
L$`(\G_|\1__)+
$#1*
\G_(?<=(_+))(?=(_*¶\1)*)
$.(_$#2*
L^$`\d
$.`* $^$%'$<%'

Try it online! Link includes test cases. Explanation:

.+
*

Convert n to unary.

L$`(\G_|\1__)+
$#1*

Greedily decompose n into positive squares, still in unary.

\G_(?<=(_+))(?=(_*¶\1)*)
$.(_$#2*

Count the number of squares that overlap each position, starting from the centre working out, in decimal.

L^$`\d
$.`* $^$%'$<%'

Turn the string of counts into the final triangle; this is the main reason I've used Retina 1 since mirroring is tricky at best in Retina 0.8.2.

APL+WIN, 97 bytes

Prompts for integer

r←0⍴0
n←⎕
:while n≠0
r←r,i←⌊n*.5
n←n-i*2
:end
(' ',(⍕⍳⌈/,n)~' ')[1+(0 ¯1↓⌽n),n←⊖+⌿⊃m∘.≤¨⌽¨m←⍳¨,r]

Try it online! Thanks to Dyalog Classic

JavaScript (Node.js), 131 bytes

f=(n,i=m=n,A=(e=[...Array(2*m)]).fill(e))=>n?i*i>n?f(n,i-1,A):f(n-i*i,i,A.map((r,y)=>r.map((c,x)=>-~c-(x+y<3*m-i|y-x<m-i)||' '))):A

Try it online!

Charcoal, 24 bytes

NθW⌊₂θ«≧⁻×ιιθG←↗↘←ιI⊕ΣKK

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

Nθ

Input n.

W⌊₂θ«

Repeat until n's square root is zero. (Floating-point inaccuracy would apply after 2¹⁰⁶.)

≧⁻×ιιθ

Subtract the square of that from n.

G←↗↘←ιI⊕ΣKK

Draw a centred triangle of that size using the next digit.