22
\$\begingroup\$

You can depict a triangular number, T(N), by writing one 1 on a line, then two 2's on the line below, then three 3's on the line below that, and so on until N N's. You end up with a triangle of T(N) numbers, hence the name.

For example, T(1) through T(5):

1

1
22

1
22
333

1
22
333
4444

1
22
333
4444
55555

To keep things nicely formatted we'll use the last digit of the number for N > 9, so T(11) would be:

1
22
333
4444
55555
666666
7777777
88888888
999999999
0000000000
11111111111

Now pretend like each row of digits in one of these triangles is a 1-by-something polyomino tile that can be moved and rotated. Call that a row-tile.

For all triangles beyond T(2) it is possible to rearrange its row-tiles into a W×H rectangle where W > 1 and H > 1. This is because there are no prime Triangular numbers above N > 2. So, for N > 2, we can make a rectangle from a triangle!

(We're ignoring rectangles with a dimension of 1 on one side since those would be trivial by putting every row on one line.)

Here is a possible rectangle arrangement for each of T(3) through T(11). Notice how the pattern could be continued indefinitely since every odd N (except 3) reuses the layout of N - 1.

N = 3
333
221

N = 4
44441
33322

N = 5
55555
44441
33322

N = 6
6666661
5555522
4444333

N = 7
7777777
6666661
5555522
4444333

N = 8
888888881
777777722
666666333
555554444

N = 9
999999999
888888881
777777722
666666333
555554444

N = 10
00000000001
99999999922
88888888333
77777774444
66666655555

N = 11
11111111111
00000000001
99999999922
88888888333
77777774444
66666655555

However, there are plenty of other ways one could arrange the row-tiles into a rectangle, perhaps with different dimensions or by rotating some row-tiles vertically. For example, these are also perfectly valid:

N = 3
13
23
23

N = 4
33312
44442

N = 5
543
543
543
541
522

N = 7
77777776666661
55555444433322

N = 8
888888881223
666666555553
444477777773

N = 11
50000000000
52266666634
57777777134
58888888834
59999999994
11111111111

Challenge

Your task in this challenge is to take in a positive integer N > 2 and output a rectangle made from the row-tiles of the triangles of T(N), as demonstrated above.

As shown above, remember that:

  • The area of the rectangle will be T(N).

  • The width and height of the rectangle must both be greater than 1.

  • Row-tiles can be rotated horizontally or vertically.

  • Every row-tile must be depicted using the last digit of the number it represents.

  • Every row-tile must be fully intact and within the bounds of the rectangle.

The output can be a string, 2D array, or matrix, but the numbers must be just digits from 0 through 9.

The output does not need to be deterministic. It's ok if multiple runs produce multiple, valid rectangles.

The shortest code in bytes wins!

\$\endgroup\$
2
  • \$\begingroup\$ inspired by Gauss? \$\endgroup\$ – ZaMoC Apr 6 '20 at 9:16
  • \$\begingroup\$ @J42161217 Nah, was just playing with Triangular numbers. \$\endgroup\$ – Calvin's Hobbies Apr 6 '20 at 9:30

17 Answers 17

18
\$\begingroup\$

Python 2, 59 bytes

n=input()
c=~n%2
while c<n:print`n%10`*n+`c%10`*c;n-=1;c+=1

Try it online!

Prints like:

55555
44441
33322

It looks kind-of redundant to update n-=1;c+=1 where sum n+c remains unchanged. I feel like there's a better way, but I haven't seen it so far. Bounty is up for grabs!


60 bytes

n=input()
b=a=n/2
while n-b:b+=1;print`a%10`*a+`b%10`*b;a-=1

Try it online!

Prints like:

22333
14444
55555

Based on ideas by @newbie.

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

APL (Dyalog), 49 47 34 38 35 bytes

3 bytes saved thanks to @Bubbler!

{10|(⌈⍵÷2)↑↑,/⍴⍨¨⍉↑((⍳⍵)-2|⍵)(⌽⍳⍵)}

Try it online!

                  ⍉↑                    ⍝ concat each pair in 
                     ((⍳⍵)     )(⌽⍳⍵)   ⍝ 1..n and n..1 (into 2×n matrix)
                          -2|⍵           ⍝ concats n-1..0 if n is odd
               ⍴⍨¨                       ⍝ repeat each item *itself* times 
            ↑,/                          ⍝ flatten
     (⌈⍵÷2)↑                             ⍝ take first n/2 rows
10|                                      ⍝ for each item, take the last digit

0 7      7 7 7 7 7 7 7      7 7 7 7 7 7 7
1 6  =>  1 6 6 6 6 6 6  =>  1 6 6 6 6 6 6
2 5      2 2 5 5 5 5 5      2 2 5 5 5 5 5
3 4      3 3 3 4 4 4 4      3 3 3 4 4 4 4
4 3      4 4 4 4 3 3 3
5 2      5 5 5 5 5 2 2
6 1      6 6 6 6 6 6 1
\$\endgroup\$
2
  • \$\begingroup\$ Why not simply 10|? \$\endgroup\$ – Bubbler Apr 7 '20 at 0:34
  • \$\begingroup\$ @Bubbler thanks! \$\endgroup\$ – Uriel Apr 7 '20 at 9:23
2
\$\begingroup\$

05AB1E, 16 15 14 bytes

Ýεθy×}2äí`RøJ»

Try it online!

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

JavaScript (ES8),  72 71  68 bytes

Returns a string.

n=>(g=k=>k<n?(h=k=>''.padEnd(k,k%10))(k)+h(n--)+`
`+g(k+1):'')(~n&1)

Try it online!

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

Charcoal, 24 bytes

NθE…÷θ²θ⭆⟦⊕ι⁻|θ¹⊕ι⟧⭆λ﹪λχ

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

Nθ

Input N.

E…÷θ²θ

Loop rows from N/2 to N. (Due to the increments in the code below, N/2 is excluded and N is included. I could have put the increments here for the same byte count.)

⭆⟦⊕ι⁻|θ¹⊕ι⟧

Each row contains two row-tiles, one for the row and one for N|1 minus the row. (If N is odd then this last row-tile is empty.)

⭆λ﹪λχ

Each row-tile consists of copies of its last digit.

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

Erlang (escript), 109 bytes

Seems huge in comparison with other answers.

t(A,B)when A<B->"";t(A,B)->[string:copies([X rem 10+48],X)||X<-[A,B]]++"
"++t(A-1,B+1).
t(N)->t(N,1-N rem 2).

Try it online!

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

Perl 5 -n, 43 bytes

@a=map$_%10x$_,$_&1^1..$_;say$_,pop@a for@a

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ this solution breaks large polyominos across multiple rows - (I found out when inputing '32' on the online version) \$\endgroup\$ – jsbueno Apr 9 '20 at 13:33
  • 1
    \$\begingroup\$ That's not possible because the entire polyomino is stored as a single unit. I suspect that the fact that the polyomino is being represented only by its last digit may be causing confusion. For example, you may be seeing the entries for 12 and 22 near each other, but they are distinct polyominos. \$\endgroup\$ – Xcali Apr 9 '20 at 14:38
  • \$\begingroup\$ yes - that is the case. Sorry for the noise. \$\endgroup\$ – jsbueno Apr 9 '20 at 14:42
2
\$\begingroup\$

Java 11, 89 bytes

n->{for(int c=~n&1;c<n;)System.out.println((n%10+"").repeat(n--)+(c%10+"").repeat(c++));}

Port of @xnor's Python answer, so make sure to upvote him!!

Try it online.

Explanation:

n->{                            // Method with integer parameter and no return-type
  for(int c=~n&1;               //  Temp-integer `c`, starting at 0 if the input is odd;
                                //  or 1 if even
      c<n;)                     //  Loop as long as this `c` is smaller than the input `n`:
    System.out.println(         //   Print with trailing newline:
      (n%10                     //     The last digit of `n`
           +"")                 //     converted to String
               .repeat(n        //     repeated `n` amount of times
                        --)     //     After which `n` is decreased by 1 with `n--`
      +                         //    Appended with:
       (c%10                    //     The last digit of `c`
            +"")                //     converted to String
                .repeat(c       //     repeated `c` amount of times
                         ++));} //     After which `c` is increased by 1 with `c++`
\$\endgroup\$
0
2
\$\begingroup\$

J, 41 33 bytes

-8 bytes thanks to Bubbler!

10(|-:@##"1~@{.],.|.)2&|@>:}.i.,]

Try it online!

K (oK), 41 38 32 bytes

-6 bytes thanks to ngn!

{(x%2)#10!{x}#'(a-2!x),'|a:1+!x}

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ J, 33 bytes. \$\endgroup\$ – Bubbler Apr 7 '20 at 2:12
  • \$\begingroup\$ @Bubbler Thank you for your nice code. I was going to propose you to post it for yourself, but I saw you have posted an even better solution. \$\endgroup\$ – Galen Ivanov Apr 7 '20 at 6:15
  • 1
    \$\begingroup\$ {(x-2!#x),'|x}1+!x -> (a-2!x),'|a:1+!x \$\endgroup\$ – ngn Apr 8 '20 at 23:24
  • 1
    \$\begingroup\$ {,/x#'10!x} -> 10!{x}# \$\endgroup\$ – ngn Apr 8 '20 at 23:29
  • \$\begingroup\$ @ngn Thank you! {x} is so obvious, when you showed it (as using a tenp variable). K is a really nice language, I love it! \$\endgroup\$ – Galen Ivanov Apr 9 '20 at 6:20
1
\$\begingroup\$

C (gcc), 85 82 bytes

Saved 3 bytes thanks to newbie!!!

i;c;f(n){for(c=-n%2;++c<n;--n,puts(""))for(i=0;i<n+c;)putchar((i++<n?n:c)%10+48);}

Try it online!

Port of xnor's Python answer so make sure to upvote him!!!

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

Ruby, 64 62 bytes

->n{c=1&~n;n,c=n-1,-~c,puts("#{n%10}"*n+"#{c%10}"*c)while c<n}

Try it online!

Based on @xnor's Python answer, thanks!

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

APL (Dyalog Unicode), 42 bytes

10|{⍵=1:1 1⍴1⋄2|⍵:⍵⍪∇⍵-1⋄(⍳∘≢,1+⊢,⊢/)∇⍵-1}

Try it online!

A fresh approach using recursion, though not very short.

How it works

10|{⍵=1:1 1⍴1⋄2|⍵:⍵⍪∇⍵-1⋄(⍳∘≢,1+⊢,⊢/)∇⍵-1}

           ⍝ Input: n
⍵=1:1 1⍴1  ⍝ Base case: If n=1, give a 1x1 matrix of 1

2|⍵:⍵⍪∇⍵-1  ⍝ For odd n, prepend n copies of n on the top

(⍳∘≢,1+⊢,⊢/)∇⍵-1  ⍝ For even n...
       ⊢,⊢/       ⍝ append its own last column to its right
     1+           ⍝ add 1 to all elements
 ⍳∘≢,             ⍝ prepend a column of 1..(number of rows) to its left

10|{...}  ⍝ Apply modulo 10 to all elements
\$\endgroup\$
1
\$\begingroup\$

Jelly, 13 bytes

_Ḷ€ZŒHṚ;"¥/%⁵

A monadic Link accepting an integer which yields a list of lists of integers in \$[0,9]\$.

Try it online! (footer just reformats the output list of lists)

I feel there may be shorter.

How?

_Ḷ€ZŒHṚ;"¥/%⁵ - Link: integer, n
  €           - for each (i) in (implicit range [1..n])
 Ḷ            -   lowered range (i) -> [0..i-1]
_             - (n) subtract (vectorised across that) -> [[n],[n,n-1],...,[n,n-1,...,1]]
   Z          - transpose -> [[n]*n,[n-1]*(n-1),...,[1]]
    ŒH        - split into half (first half longer if n is odd)
          /   - reduce (this list of two lists) by:
         ¥    -   last two links as a dyad:
      Ṛ       -     reverse (the first half)
        "     -     zip together applying:
       ;      -       concatenation
            ⁵ - literal ten
           %  - modulo

An alternative first three bytes is rRṚ

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

J, 30 29 bytes

10(|-:@#$]#~@,"0|.)2&|0&,1+i.

Try it online!

J's reshape $ is so weird that it works in place of take {. when the left is positive singleton (regardless of what comes on the right).


J, 30 bytes

10(|-:@#{.]#~@,"0|.)2&|0&,1+i.

Try it online!

Yet another case of repeat-bind (dyadic &) winning over other approaches.

How it works

10(|-:@#{.]#~@,"0|.)2&|0&,1+i.   NB. input=n
                          1+i.   NB. 1..n
                    2&|0&,   NB. prepend 0, but only if n is odd
  (       ]    "0|.)   NB. for each pair (x,y) of the above and above reversed,
           #~@,        NB. concatenate x copies of x and y copies of y
    -:@#{.   NB. take half the rows
10 |         NB. modulo 10 to all elements of the array
\$\endgroup\$
1
  • \$\begingroup\$ Great solution and explanation! \$\endgroup\$ – Galen Ivanov Apr 7 '20 at 6:08
1
\$\begingroup\$

Husk, 16 bytes

←½Ṡz+↔↓¬%2¹m´Rŀ→

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Icon, 76 bytes

procedure f(n)
c:=seq(1-n%2)&write(repl(n%10,n)||repl(c%10,c))&(n-:=1)=c
end

Try it online!

Inspired by xnor's Python solution - don't forget to upvote it!

\$\endgroup\$
0
\$\begingroup\$

Wolfram Language (Mathematica), 106 bytes

(r=#+(y=Mod[#+1,2]);""<>{z@#,z[r-#]}&/@Range@r)[[-⌈r/2⌉;;-y-1]]&
z@x_:=""<>ToString/@Table[x~Mod~10,x]

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.