6
\$\begingroup\$

Your task is, given a array of numbers, that is strictly increasing, output the crate stack. The input is an array of positive integers which represents which layer has how many crates there are. So the first number is the top layer and so on. The sum of the array is the size of the crate.

Since the array order follows this rule layer 1>layer 2>layer 3..., we have to make sure every layer above the bottom one is centered with respect to the whole width of the layer below it. If it can't be centered, place it so that it's as close as possible to the center (you can choose it to be shifted left or right).

Testcases

[1]
->
*

[1,2]
->
 ***
 * *
 ***
******
* ** *
******

[2,3]
->
  **********
  *   **   *
  *   **   *
  *   **   *
  **********
***************
*   **   **   *
*   **   **   *
*   **   **   *
***************

[2,3,4]
->
        ******************
        *       **       *
        *       **       *
        *       **       *
        *       **       *
        *       **       *
        *       **       *
        *       **       *
        ******************
    ***************************
    *       **       **       *
    *       **       **       *
    *       **       **       *
    *       **       **       *
    *       **       **       *
    *       **       **       *
    *       **       **       *
    ***************************
************************************
*       **       **       **       *
*       **       **       **       *
*       **       **       **       *
*       **       **       **       *
*       **       **       **       *
*       **       **       **       *
*       **       **       **       *
************************************

Leading spaces and trailing spaces are allowed

This is , so shortest code wins!

\$\endgroup\$
3
  • 6
    \$\begingroup\$ Is * as character mandatory, or could we use any single non-whitespace character? \$\endgroup\$ Mar 4, 2022 at 8:27
  • 1
    \$\begingroup\$ I think you should add at least one test case with increasing steps other than 1, such as [1,3]. \$\endgroup\$
    – Arnauld
    Mar 4, 2022 at 21:00
  • \$\begingroup\$ I assumed that you meant inputs incrementing by one based on your test cases. Is this true? \$\endgroup\$
    – code
    Mar 4, 2022 at 21:22

6 Answers 6

3
\$\begingroup\$

JavaScript, 225 219 bytes

-7 thanks to Arnauld's suggestion

s=d=>{j=console.log;o=(p,g)=>p.repeat(g);a="*";[t]=d.slice(-1);if(t==1)return j(a);b=t*-~t/2-2;b=b<1?1:b;d.map(i=>{h=o(" ",(t*b-i*b)/2);c=`${h+o(o(a,b+2),i)}${o(`
${h+o(`*${o(" ",b)}*`,i)}`,b)}
${h+o(o(a,b+2),i)}`;j(c)})}

Try it online!

Unminified for your enjoyment:

function stack(arr) {
    String.prototype.o = function(p) {
        return this.repeat(p);
    }
    const a = "*";
    const [t] = arr.slice(-1);
    if(t == 1) return console.log(a);
    let sum = ((t * t + t) / 2) - 2;
    if(sum < 1) sum = 1;
    arr.forEach(i => {
        const spaces = " ".o((t * sum - i * sum) / 2);
        const crate = `${spaces + a.o(sum + 2).o(i)}${`\n${spaces + `*${" ".o(sum)}*`.o(i)}`.o(sum)}\n${spaces + a.o(sum + 2).o(i)}`;
        console.log(crate);
    });
}
\$\endgroup\$
6
  • 3
    \$\begingroup\$ It seems like your code doesn't center the crates properly (try with [1, 3] for instance). \$\endgroup\$
    – ophact
    Mar 4, 2022 at 8:32
  • 1
    \$\begingroup\$ Some tips. 1) Because your function is not recursive, you don't have to put s= in your main code (you can put it the header section of TIO). 2) You should also put s([2, 3, 4]); in the footer section of TIO so that the correct size is reported. 3) ((t*t+t)/2)-2 can be simplified to t*-~t/2-2 and (t*b-i*b)/2 to (t-i)*b/2. 4) You can use literal linefeeds instead of \n's. \$\endgroup\$
    – Arnauld
    Mar 4, 2022 at 17:42
  • \$\begingroup\$ @ophact the question states the input must be "strictly increasing" (based on the examples, by 1), so that input is invalid. \$\endgroup\$
    – code
    Mar 4, 2022 at 20:42
  • \$\begingroup\$ @Arnauld Thanks for your feedback. Does \n count as one or two bytes? \$\endgroup\$
    – code
    Mar 4, 2022 at 20:49
  • \$\begingroup\$ What should be counted is the actual number of bytes in the source code. So \n is two bytes. \$\endgroup\$
    – Arnauld
    Mar 4, 2022 at 20:57
2
\$\begingroup\$

Python 3.8 (pre-release), 128 bytes

lambda n:(s:=sum(n))and'\n'.join('\n'.join((n[-1]-N)*s//2*' '+N*('*'+'* '[0<m<s-1]*(s-2)+'*'*(s>1))for m in range(s))for N in n)

Try it online!

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

05AB1E, 21 bytes

O'*Ž9¦.Λ¶¡¸Iи€øJ€»».c

Try it online or verify all test cases or try it online with step-by-step debug lines.

Explanation:

O              # Sum the (implicit) input-list
 '*           '# Push "*"
   Ž9¦         # Push compressed 2460
      .Λ       # Use the (modifiable) Canvas builtin with these three options
¶¡             # Split this box by newlines
  ¸            # Wrap it in a list
   Iи          # Repeat it each of the inputs amount of times
     €         # Map over each list of boxes:
      ø        #  Zip/transpose; swapping rows/columns
       J       # Join each inner row together to a single string
        €»     # Join all inner lines by newlines
          »    # Join each vertical line of boxes by newlines
           .c  # Centralize all lines
               # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ž9¦ is 2460.

As for some additional information about the modifiable Canvas builtin :
It takes 3 arguments to draw an ASCII shape:

  1. Length of the lines we want to draw
  2. Character/string to draw
  3. The direction to draw in, where each digit represents a certain direction:
7   0   1
  ↖ ↑ ↗
6 ← X → 2
  ↙ ↓ ↘
5   4   3

O'*Ž9¦ creates the following Canvas arguments:

  1. Length: the sum of the input (e.g. for [2,3,4] this would be 9)
  2. Character: "*"
  3. Directions: [2,4,6,0], which translates to \$[→,↓,←,↑]\$

Try just the Canvas portion online.

Step 1: Draw 9 characters ("*********") in direction 2/:

*********

Step 2: Draw 9-1 characters ("********") in direction 4/:

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

Step 3: Draw 9-1 characters ("********") in direction 6/:

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

Step 4: Draw 9-1 characters ("********") in direction 0/:

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

After which we can use this string since we're using the modifiable Canvas builtin , instead of the Canvas builtin Λ that would output directly.

See this 05AB1E tip of mine for an in-depth explanation of the Canvas builtin.

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

Charcoal, 29 bytes

FLθ«J⊘קθιΣθ×ιΣθF§θι«BΣθ*MΣθ←

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

FLθ«

Loop over each layer.

J⊘קθιΣθ×ιΣθ

Jump to the top left corner of the last box in that layer.

F§θι«

Loop over each box in the layer.

BΣθ*

Draw the box of the appropriate size.

MΣθ←

Move to the previous box.

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

JavaScript (ES6),  132 128 120  119 bytes

Non-centered crates are shifted to the right.

f=(a,x=W=a.every(n=>w+=N=n,w=y=0)+w*N)=>(q=W-a[y/w|0]*w)?` *
`[--x?(X=x+q/2)%w<2|-~y%w<2&&X>=q&X<W:++y&&2]+f(a,x||W):''

Try it online!

Commented

f = (                  // f is a recursive function taking:
  a,                   //   a[] = input array
                       // and also using:
  x =                  //   (x, y) = current position
  W =                  //   W = total row width, w = crate width
    a.every(n =>       //   for each value n in a[]:
      w += N = n,      //     add n to w and save n in the global scope
      w = y = 0        //     start with w = 0 and y = 0
    )                  //   end of every(), which returns 1
    + w * N            //   add the last value multiplied by w
) =>                   //
( q = W -              // define q as the total row width less the
      a[y / w | 0] * w // total width of the crates on this row
) ?                    // if q is not NaN:
  ` *\n`[              //   character lookup:
    --x ?              //     decrement x; if it's not 0:
      (X = x + q / 2)  //       define X as x + q / 2
      % w < 2 |        //       if we're over a vertical crate edge
      -~y % w < 2      //       or over a horizontal crate edge
      &&               //       and
      X >= q & X < W   //       we're over the crates in this row,
                       //       then put a '*', else put a space
    :                  //     else:
      ++y && 2         //       increment y and put a linefeed
  ] +                  //   end of character lookup
  f(a,                 //   append the result of a recursive call
       x || W)         //   make sure to restart with x = W if x = 0
:                      // else:
  ''                   //   stop the recursion
\$\endgroup\$
0
\$\begingroup\$

Vyxal, 19 bytes

∑×2460ø^↵vẋƛ∩Ṡ;føĊ⁋

Try it Online!

\$\endgroup\$

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.