12
\$\begingroup\$

It's my friend's birthday soon and since he is a programmer and ASCII art lover, I thought I'd make him some ASCII cake!

Sadly, I keep forgetting his current age, so I would like to have a program for my ASCII oven, that bakes a cake with a specified number of candles, so I don't have to do it myself again if I am wrong with his age.

ASCII ovens only have limited memory and storage capacity, so it should use the fewest bytes possible.


Your Task:

Write a program that outputs a birthday cake to the console, with as many candles as the input specifies.

Cake requirements are:

  • It has to have a border, built up of horizontal - and vertical | lines, and vertices +.
  • Atleast 5 characters wide (including cake border |)
  • Atleast 5 characters high (including cake border -)
  • There has to be a whitespace character between the cake border and the first candle-base (not the flame), on each side, except if there is a flame in that space. A flame or candle-base should not be able to overlap the cake borders.
  • The maximum width of the cake is 9 characters, so there is a maximum of 5 candles per row.
  • Since we don't want our cake to be 2-dimensional, it has to be an extra 2 rows high, to give it some volume. Add another border at the bottom and connect the vertices with the ones above them, again using the ASCII characters from above (-, | and +).

Candle requirements are:

  • Consists of the base | and the flame *, with the flame stacked on top of the base.
  • Candles may not be directly adjacent to eachother, except diagonally.
  • Candles are placed left-to-right, then top-to-bottom, with 5 in one line at maximum.
    (Note: If there were 5 candles in the previous row, the next row can't possibly have 5 aswell, since then they would be adjacent.)

Additional notes:

  • The cake width depends on the number of candles in the first row, but it has to be a minimum of 5 characters and a maximum of 9 characters wide.
  • The candles are filled starting in the top-most row, going left to right. Once one row if full the next one should start in the row below the first one.

Input:

You may accept a number in (reasonable) format you like.

For this challenge you may assume that the number is between 0 and 231 (not including 0), even though I don't acknowledge someone who is this old.

Output:

You can either return a string or directly write the resulting cake into the output console.

Rules:

  • Standard loopholes are forbidden.
  • This is , so shortest code in bytes, in any language, wins.

Examples:

Input: 8

+-----------+
| * * * * * |
| |*|*|*| | |
|  | | |    |
|           |
+-----------+
|           |
+-----------+

Input: 2

+-----+
| * * |
| | | |
|     |
+-----+
|     |
+-----+

Input: 12

+-----------+
| * * * * * |
| |*|*|*|*| |
| *|*|*| |  |
| | | |     |
|           |
+-----------+
|           |
+-----------+

Good luck!

\$\endgroup\$
  • \$\begingroup\$ Can there be multiple valid solutions for an input? \$\endgroup\$ – officialaimm Aug 1 '17 at 8:39
  • 1
    \$\begingroup\$ @officialaimm Since there are specifications for candle-ordering and cake-sizing it should not be possible. \$\endgroup\$ – Ian H. Aug 1 '17 at 8:44
  • 2
    \$\begingroup\$ Useless fact: If you celebrate your birthday every second instead of every year, then 2^31 ~= 68 year-old. But that makes a lot of cakes every day and might become tedious after some time. \$\endgroup\$ – Arnauld Aug 1 '17 at 9:13
  • 1
    \$\begingroup\$ @Arnauld But then 99% of the time it's not your birthday :( ... except if you are celebrating the general fact that you were born. \$\endgroup\$ – Ian H. Aug 1 '17 at 9:16
  • 3
    \$\begingroup\$ @IanH. Let's say that you're celebrating your inception timestamp, then. :-) \$\endgroup\$ – Arnauld Aug 1 '17 at 9:19
10
\$\begingroup\$

Charcoal, 76 71 70 66 46 bytes

NθF=+B⁺³⌊⟦χ⁺θθ⟧÷⁺℅ι⁺θθ⁹↘↘Fθ«↑|*¶¶¿‹⁶﹪⁺ιι⁹«M⁹←↓

Try it online! Link is to verbose version of code. Edit: Saved 1 byte thanks to @ASCII_Only. Saved a massive 20 bytes by discovering a neat way of drawing the candles. Explanation:

NθF=+B⁺³⌊⟦χ⁺θθ⟧÷⁺℅ι⁺θθ⁹

Calculate the size both of the whole cake including extra volume and just the top of the cake so that they can be drawn. ((= = ASCII 61) = (+ = ASCII 43) + 9 * 2 for the extra volume.)

↘↘Fθ«

Move the cursor to the first row of 5 candles. Loop through each candle.

↑|*¶¶

Print a candle and move right two characters for the next candle.

¿‹⁶﹪⁺ιι⁹«

However after the (zero-indexed) 4th, 8th, 13th, 17th, 22nd etc. candles (that are at the end of a row),

M⁹←↓

move the cursor to the first candle on the next row. This works on both odd and even rows!

\$\endgroup\$
  • 1
    \$\begingroup\$ Your solution puts an (unwanted) extra row for input number smaller than 6. :) \$\endgroup\$ – Ian H. Aug 1 '17 at 9:10
  • \$\begingroup\$ @IanH. Sorry, I thought that was the minimum height for some reason. Fixing that actually saved me 4 bytes! \$\endgroup\$ – Neil Aug 1 '17 at 9:18
  • \$\begingroup\$ Still displays wrong on TIO :/ \$\endgroup\$ – Ian H. Aug 1 '17 at 9:19
  • 1
    \$\begingroup\$ @IanH. Try it online! gives me identical output to your example... \$\endgroup\$ – Neil Aug 1 '17 at 9:22
  • 1
    \$\begingroup\$ @Neil remember you don't need the at the start :P (btw thanks for finding another golfer (not-so-)edge case) \$\endgroup\$ – ASCII-only Aug 1 '17 at 11:47
3
\$\begingroup\$

Jelly, 67 bytes

s9s€5Ẏa;⁶;⁶z⁶Z
ç”|ṙ-ż"ç”*$U⁸RḤ’¤¦Ẏ€j@€“| “|”Zj@€⁾--Z”+®¦€0,1©¦;ṫ¥-Y

A monadic link taking a number and returning a list of characters or a full program printing the output.

Try it online!

How?

s9s€5Ẏa;⁶;⁶z⁶Z - Link 1, make some candle parts & topping: number, age; character, part
s9             - split (implicit range(age)) into chunks of 9 (or remainder)
  s€5          - split each chunk of 9 into chunks of 5 (a 5 and a 4 or remainder)
     Ẏ         - tighten (to a list of lists of length 5, 4, 5, 4, ..., remainder)
      a        - logical and with the part character (either | or * here)
       ;⁶      - concatenate a space (we all still want topping when no candles)
         ;⁶    - ...and another (we also want some extra topping below the last row)
           z⁶  - transpose with filler space (fill the top with topping!)
             Z - transpose (put it back around the right way again chef)

ç”|ṙ-ż"ç”*$U⁸RḤ’¤¦Ẏ€j@€“| “|”Zj@€⁾--Z”+®¦€0,1©¦;ṫ¥-Y - Main link: number, age
ç”|                                                  - call last link (1) as a dyad with '|'
   ṙ-                                                - rotate left by -1
          $                                          - last two links as a monad:
       ç”*                                           -   call (1) as a dyad with '*'
      "                                              - zip with the dyadic operation:
     ż                                               -   zip (interleave each)
                 ¦                                   - sparse application:
           U                                         - ...of: upend (reverse each)
                ¤                                    - ...to indexes: nilad+links as a nilad:
            ⁸                                        -   chain's left argument, age
             R                                       -   range
              Ḥ                                      -   double (vectorises)
               ’                                     -   increment
                  Ẏ€                                 - tighten €ach (from '|*' or '*|' pairs)
                       “| “|”                        - literal ["| ", "|"]
                    j@€                              - join (swap arguments) for €ach (add a little extra topping to the left, and add piping to the sides)
                             Z                       - transpose
                                 ⁾--                 - literal "--"
                              j@€                    - join (swap arguments) for €ach (add piping to the top and bottom edges)
                                    Z                - transpose (time to invest in a potters wheel!)
                                              ¦      - sparse application:
                                          0,1        - ...to indexes: [0,1] (both ends)
                                             ©       -   (copy that to the register)
                                         €           - ...of: for each:
                                        ¦            -   sparse application:
                                     ”+              -   ...of: '+' character
                                       ®             -   ...to indexes: recall from register (both ends)
                                                  -  - literal -1
                                                 ¥   - last two links as a dyad
                                                ṫ    -   tail from index (gets last two rows)
                                               ;     -   concatenate (repeats them underneath)
                                                   Y - join with newlines
                                                     - as a full program: implicit print
\$\endgroup\$
  • 1
    \$\begingroup\$ Holy what +1 for beating Charcoal \$\endgroup\$ – ASCII-only Aug 2 '17 at 12:56
  • \$\begingroup\$ @ASCII-only Sorry, I found a 4-byte saving... \$\endgroup\$ – Neil Aug 5 '17 at 16:10
  • \$\begingroup\$ @Neil well that's good too, Charcoal is supposed to be good at ASCII art (better than jelly) after all :P \$\endgroup\$ – ASCII-only Aug 5 '17 at 18:45
1
\$\begingroup\$

Japt, 94 bytes

/4½ c ÆYu ç +Um5-Yu)ÇV°<U?Q:Sø+(1+Yu)ç
"| {Ug ç}|"
Vd"|+ -"
[W¡"| {X}|"ÃVVWVW]c ·y rQ+S"*|" y

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.