14
\$\begingroup\$

Challenge

Given an input n, print an ASCII art cake n layers tall, viewed from the side, with two candles on top. Refer to the examples below for details.

Output

>> cake(1)

 _|_|_
|     |
+-----+

>> cake(3)

     _|_|_
    |     |
  +---------+
  |         |
+-------------+
|             |
+-------------+

...and so on.

Rules

  • Standard loopholes prohibited
  • Please make an attempt at a clever solution
  • This is , so shortest answer in bytes wins. However, the answer will not be selected.

Have fun!

\$\endgroup\$

17 Answers 17

6
\$\begingroup\$

Python 2, 238 chars

i=input()
m=["+"+"-"*(i*4+1)+"+","|"+" "*(i*4+1)+"|"]
for v in range(i,1,-1):
 m+=[" "*(i-v)*2+"+"+"-"*(v*4+1)+"+"," "*(i-v+1)*2+"|"+" "*((v-1)*4+1)+"|"]
m.pop()
m+=[" "*(i-1)*2+"|"+" "*5+"|"," "*(i-1)*2+" _|_|_"]
print'\n'.join(m[::-1])

The missing example of Cake 2:

   _|_|_
  |     |
+---------+
|         |
+---------+
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hello, and welcome to the site! You could take input from STDIN and take off 24 chars. For example, i=int(input()) \$\endgroup\$ – James Sep 17 '16 at 5:59
  • \$\begingroup\$ If you want, you should be able to change to Python 2 and change int(input()) to input() and the print statement, plus you can change the four spaces to one (if it's a tab, change it to a space to make it more obvious that it's one character). Plus your bytecount is 4 too high for some reason. \$\endgroup\$ – ASCII-only Sep 17 '16 at 6:29
  • \$\begingroup\$ @Mars Ultor oops, yes, I'm not sure why I chose python 3 to begin with. Thanks. \$\endgroup\$ – edelbitter Sep 17 '16 at 6:45
  • \$\begingroup\$ You may also be able to save a few bytes using percent formatting \$\endgroup\$ – ASCII-only Sep 17 '16 at 6:54
4
\$\begingroup\$

Ruby, 109 107 bytes

->n{p=->t{puts t.center 3+4*n}
p['_|_|_']
(1..n).map{|i|p[?|+' '*(1+4*i)+?|]
p[?++?-*((i<n ?5:1)+4*i)+?+]}}
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Batch, 233 bytes

@echo off
set i=
for /l %%j in (2,1,%1)do call set i=  %%i%%
echo %i% _^|_^|_
set s=-----
for /l %%j in (2,1,%1)do call:l
echo ^|%s:-= %^|
echo +%s%+
exit/b
:l
echo %i%^|%s:-= %^|
set i=%i:~2%
set s=----%s%
echo %i%+%s%+

Shorter than Python? Something must be wrong...

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 134 bytes

A recursive cake.

f=(n,i=--n,r=(n,c)=>'- '[+!c].repeat(n),p=r((i-n)*2),j=n*4+5,x=p+`+${r(j,1)}+
`)=>(n?f(n-1,i)+x:p+` _|_|_
`)+p+`|${r(j)}|
`+(n-i?'':x)

Demo

let f=(n,i=--n,r=(n,c)=>'- '[+!c].repeat(n),p=r((i-n)*2),j=n*4+5,x=p+`+${r(j,1)}+
`)=>(n?f(n-1,i)+x:p+` _|_|_
`)+p+`|${r(j)}|
`+(n-i?'':x)

console.log(f(4))

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Haskell, 103 bytes

f(a:b)n=a:([0..4*n]>>b)++[a]
x!n=x:[f"| "n,f"+-"n]
g 1=" _|_|_"!1
g n=map("  "++)(init.g$n-1)++f"+-"n!n

Defines a function g which returns a list of strings containing the lines of the output

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 115, 101 chars

>UXð×?" _|_|_",Xð×?"|     |",X<U0<VXGNVXY-ð×?'+?8Y·+G'-?}'+,XY-ð×?'|?7Y·+ð×?'|,}XY-ð×?'+?8Y·+G'-?}'+,

Saved 14 chars thanks to Adnan!
Definitely some room for golfing here.

Try it online!

Note that this does print everything offset by one space.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Welcome to Programming Puzzles and Code Golf! Very nice first answer :) \$\endgroup\$ – Adnan Sep 17 '16 at 23:12
  • 1
    \$\begingroup\$ Maybe string multiplication helps, which is the × command. This is an example on how it's used. \$\endgroup\$ – Adnan Sep 17 '16 at 23:13
  • \$\begingroup\$ @Adnan That does help! Thanks! \$\endgroup\$ – Luke Sep 17 '16 at 23:39
2
\$\begingroup\$

Python 2, 122 bytes

a='  '*input()
b='+-+'
c=d=' '
while a:b='+----'+b[1:];c=d*4+c;a=a[2:];print a+[' _|_|_',b][c>d*5]+'\n%s|%%s|'%a%c
print b
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Python 3, 162 characters

p=print
t=int(input())
d=4*'-'
s='  '
a='+\n'
r=(t-1)*s
p(r+' _|_|_\n'+r+'|     |')
for i in range(2,t+1):b=(t-i)*s;p(b+'+-'+i*d+a+b+'| '+i*2*s+'|')
p('+-'+t*d+a)

It's not very clever, but I've never done one of these before. (Edit: removed unnecessary parentheses; reduced by one more character)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Welcome to the site, and nice first answer! \$\endgroup\$ – James Sep 18 '16 at 2:53
2
\$\begingroup\$

Pyth, 73 bytes

+K*dtyQ"_|_|_"+tK"|     |"jP.iJms[*\ yt-Qd\+*+5*4d\-\+)+StQtQmXd"+-""| "J

A program that takes input of an integer on STDIN and prints the result.

There is probably still some golfing to be done here.

Try it online

Explanation coming later

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 171 bytes

n=>[(s="  "[R='repeat'](n-1))+" _|_|_",s+"|     |",...Array(n-1),`+${"-"[R](n*4+1)}+`].map((_,i)=>_||(s="  "[R](n-i))+`+${"-"[R](i=i*4+1)}+`+`
${s}|${" "[R](i)}|`).join`
`

First pass, probably not optimal...

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PHP, 150 147 138 136 130 140 bytes

new approach:

echo$p=str_pad("",-2+2*$n=$argv[1])," _|_|_";for($x="    ",$b=$y="----";$n--;){$a.=$x;if($n)$b.=$y;echo"
$p| $a|
",$p=substr($p,2),"+-$b+";}

old version for reference:

$p=str_pad;for($o=["_|_|_"];$i++<$n=$argv[1];$o[]="+".$p("",($i<$n)*4+$e,"-")."+")$o[]="|".$p("",$e=$i*4+1)."|";foreach($o as$s)echo$p($s,$n*4+3," ",2),"
";
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I’m curious; how does this read input? \$\endgroup\$ – Lynn Sep 18 '16 at 1:04
  • \$\begingroup\$ @Lynn: damn I forgot that this time.10 bytes overhead for $argv. :-/ \$\endgroup\$ – Titus Sep 18 '16 at 1:54
1
\$\begingroup\$

Vimscript, 116 115 bytes

Pretty messy but it works!

fu A(n)
let @z="Vkyjply4lpjy4hp"
exe "norm 2i+\e5i-\eo||\e5i \e".a:n."@zddl4xggd$i_|_|_"
exe "%ce ".(a:n*4+3)
endfu

To call it: call A(3) in an empty buffer. To load the function, source cake.vim

Explanation

  • 2i+<Esc>5i-<Esc> writes the first line +-----+
  • o||<Esc>5i<Space><Esc> adds | | on the second line
  • Vkyjply4lpjy4hp is saved in the macro @z - it visually selects both lines, yanks them, pastes them under and adds 4 dashes and spaces to them.
  • #@z repeats this # times
  • ddl4x deletes the last lines and remove for dashes to the bottom of the cake to make it equal with the top of the bottom layer
  • ggd$i_|_|_ replaces the first line by the top of the cake
  • %ce then centers the whole cake to the width of the bottom layer! !
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

SOGL V0.12, 27 26 bytes

∫4*I:┌*╗1Ο;@*┐1Ο}⁴¹k┐╔2ΟΚ╚

Try it Here!

Explanation:

∫               }           for each in 1..input inclusive, pushing counter
 4*                           multiply by 4
   I                          increase by 1
    :                         duplicate; this will be used later
     ┌*                       repeat a dash pop times
       ╗1Ο                    encase them in plusses
          ;                   get the duplicate on the stacks top
           @*                 repeat a space pop times
             ┐1Ο              encase in vertical bars
                 ⁴          duplicate the item below ToS - the last line
                  ¹         wrap the stack in an array
                   k        remove the arrays first item
                    ┐       push "_"
                     ╔      push "|"
                      2Ο    encase 2 copies of the vertical bar in underscores
                        Κ   and prepend that to the array
                         ╚  center the array horizontally
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Excel VBA, 139 130 127 Bytes

Anonymous VBE immediate window that takes input from cell A1 and outputs a cake to the VBE immediate window

For i=1To[A1]:s=Space(2*([A1]-i)):x=String(1+4*i,45):?s &IIf(i=1," _|_|_","+" &x &"+"):?s"|"Replace(x,"-"," ")"|":Next:?s"+"x"+
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

CJam, 79 bytes

l~4*):Z5:X{D'+'-C}:A{D'|SC}:B{X*1$N}:C];{SZX-Y/*}:D~" _|_|_"NB{XZ<}{X4+:X;AB}wA

Try it online

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

QBasic, 115 bytes

INPUT n
?SPC(n*2-1)"_|_|_
FOR i=1TO n
s=n*2-i*2
?SPC(s)"|"SPC(i*4+1)"|
?SPC(s-2)"+"STRING$(i*4+(i=n)*4+5,45)"+
NEXT

Ungolfed

Print the top line with the candles; then print the rest of the cake two lines at a time.

INPUT n
PRINT SPC(n * 2 - 1); "_|_|_"
FOR i = 1 TO n
  indent = n * 2 - i * 2
  PRINT SPC(indent); "|"; SPC(i * 4 + 1); "|"
  PRINT SPC(indent - 2); "+"; STRING$(i * 4 + (i = n) * 4 + 5, 45); "+"
NEXT

SPC, when used in a PRINT statement, emits the given number of spaces. Conveniently, when given a negative argument, it treats it as 0, so the fact that indent - 2 is -2 in the last iteration isn't a problem. STRING$ takes a count and a character code (here, 45 for -) and repeats the character that number of times. Here, we have to special-case the last line (when i=n) to be 4 hyphens shorter than it would otherwise be.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

C (gcc), 158 153 bytes

-5 bytes thanks to ceilingcat.

i,l,s;p(c,s){printf("%*c%*.*s%c\n",i-~i,c,l,l,s,c);}f(n){s=memset(malloc(5*n),45,5*n);l=1;for(i=n;i--;p('|',""))l+=4,n+~i?p(43,s):p(32,"_|_|_");p(43,s);}

Try it online!

| improve this answer | |
\$\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.