# 91 Bottles of ASCII-beer on the Wall

Given a single integer x where 0 <= x <= 91 output a stack of bottles of beer with that many bottles (and shelves) missing. For simplicity sake I'll only show the first 6 bottles and what it would be for each of the first inputs.

Here's the stack of bottles, each number is the bottle you should remove for that input (1-indexed):

https://pastebin.com/wSpZRMV6

Note, we're using 91 instead of 99 because 99 would result in an unstable stack of bottles.

# Example

With 0 bottles missing (x=0):

             |=|
| |
| |
/   \
.     .
|-----|
|     |
|-----|
|_____|
=============
|=|     |=|
| |     | |
| |     | |
/   \   /   \
.     . .     .
|-----| |-----|
|     | |     |
|-----| |-----|
|_____| |_____|
=====================
|=|     |=|     |=|
| |     | |     | |
| |     | |     | |
/   \   /   \   /   \
.     . .     . .     .
|-----| |-----| |-----|
|     | |     | |     |
|-----| |-----| |-----|
|_____| |_____| |_____|
=============================
[THERE ARE MORE UNDER THIS]


For the full output of 0, see here: https://pastebin.com/ZuXkuH6s

With 1 bottle missing (x=1):

         |=|     |=|
| |     | |
| |     | |
/   \   /   \
.     . .     .
|-----| |-----|
|     | |     |
|-----| |-----|
|_____| |_____|
=====================
|=|     |=|     |=|
| |     | |     | |
| |     | |     | |
/   \   /   \   /   \
.     . .     . .     .
|-----| |-----| |-----|
|     | |     | |     |
|-----| |-----| |-----|
|_____| |_____| |_____|
=============================
[THERE ARE MORE UNDER THIS]


Once again, this is the first two rows from here: https://pastebin.com/ZuXkuH6s (with 1 removed)...

With 2 bottles missing:

                 |=|
| |
| |
/   \
.     .
|-----|
|     |
|-----|
|_____|
=====================
|=|     |=|     |=|
| |     | |     | |
| |     | |     | |
/   \   /   \   /   \
.     . .     . .     .
|-----| |-----| |-----|
|     | |     | |     |
|-----| |-----| |-----|
|_____| |_____| |_____|
=============================
[THERE ARE MORE UNDER THIS]


With 91 bottles missing (n = 91):

:(


You must output an unhappy face, because you're out of beer.

# Rules

• Bottles are to be removed left to right.
• Shelves are removed when no beer remains on the top of the shelves.
• For an input of 0, you are outputting 91 bottles stacked in a triangle.
• The bottom row has 13 bottles, the top has 1.
• 1 space between each bottle on each shelf.
• Shelves must be input between each row of bottles.
• Shelves may use =, - or # as the character.
• Shelves must be 3 wider (on each side) than the bottles they hold.
• This is , lowest byte-count wins.
• Could you provide, say, a pastebin of at least one of the entire test cases? Aug 11, 2017 at 20:44
• Are trailing spaces after a shelf's last bottle required? Aug 11, 2017 at 20:56
• Preceding spaces are required, as you are removing them left to right, the spaces to the right of the ASCII-art are up to you. Aug 11, 2017 at 21:00
• @ConorO'Brien seeing as you didn't specify which test case, I wish I had put an unhappy face in a pastebin ;P. Aug 11, 2017 at 21:10
• Oh, I thought you had chosen 91 to prevent any kind of built-ins. o0 Aug 11, 2017 at 21:12

# Charcoal, 99 91 bytes

Ａ⁻⁹¹ＮθＡ¹³η:(Ｗθ«Ａ⌊⟦θη⟧ζＡ⁻θζθＡ⁻η¹ηＦζ«↑⁴↖.\↑²←|=↓³←↙¹↓.Ｐ⁶↓²Ｐ⁶↓¹Ｐ______←| »¿θ«Ｍ⁹↑Ｍ³→×=⁻×⁸ζ³↑Ｍ⁴←


Try it online! Link is to verbose version of code. Actually the real version is only 83 70 bytes:

Ｆ¹⁵Ｆι⊞υκ:(Ｆ⁻⁹¹Ｎ«Ｆ¬⊟υ«Ｍ³±⁹×=⁺⁵×⁸⊟υ↑Ｍ⁴←»↑⁴↖.\↑²←|=↓³←↙¹↓.Ｐ⁶↓²Ｐ⁶↓¹Ｐ×_⁶←|←


Explanation:

Ｆ¹⁵Ｆι⊞υκ


Populate an array providing information as to where the shelves go and how long they are.

:(


Print an unhappy face, although this will be immediately overwritten by the first bottle of beer (if any).

Ｆ⁻⁹¹Ｎ«


Loop through the remaining bottles of beer.

   Ｆ¬⊟υ«


Check to see whether a shelf needs to be drawn.

        Ｍ³±⁹×=⁺⁵×⁸⊟υ↑Ｍ⁴←»


Print the shelf and position ready to draw the next bottle above it.

   ↑⁴↖.\↑²←|=↓³←↙¹↓.Ｐ⁶↓²Ｐ⁶↓¹Ｐ×_⁶←|←


Draw a bottle and position ready to draw another bottle.

• Huh. Too bad this challenge isn't about 99 bottles of beer. Gotta get 8 bytes down :) :P Aug 12, 2017 at 1:32
• @EriktheOutgolfer That's why I suggested golfing 8 bytes :P And yay he actually did golf 8 bytes :D Aug 12, 2017 at 14:24
• @HyperNeutrino Not exactly; I golfed 11, then ungolfed 3...
– Neil
Aug 12, 2017 at 14:39
• @KevinCruijssen Normally you'd increment using a for loop. This is a while loop, so I have to do some thing more manually.
– Neil
Aug 14, 2017 at 14:28
• @KevinCruijssen Although, thinking about it, a for loop was the way to go all along... 13 bytes saved! (Well, I got a bit lucky with the ease of populating my array.)
– Neil
Aug 15, 2017 at 8:52

# Python 3, 306299265253255252247 244 bytes

Quick attempt, could be optimised

Edit: -2 bytes thanks to @MrXcoder

Edit: -32 bytes as trailing spaces is not needed

Edit: -12 bytes by combining the two functions

Edit: -5 bytes thanks to @musicman523

Edit: +7 bytes to remove the shelf after the last row

Edit: -3 bytes

Edit: -5 bytes due to a lambda function only being used once in a map

Edit: -3 bytes by using the string function center

def l(y,x=13,z=" "):b=min(x,91-y);A,D="  |%s|  ","|-----|";print(y<91and(l(y+x,x-1)or"".join(map(lambda t:((t+z)*b)[:-1].center(103)+"\n",(A%"=",A%z,A%z," /   \ ",".     .",D,"|     |",D,"|_____|")))+z*(49-4*x)+"="*(x*8+5)*(x<13))or(x>12)*":(")


Try it online!

## JavaScript (ES6), 251 256 bytes

Edit: Saved 2 bytes thanks to @dzaima.
Edit: Added 7 bytes to fix issue with parameter. :(

c=>(f=(c,w=13)=>c>0&&f(c-w,w-1)+(c=c<w?c:w,r=(n,s=' ')=>s.repeat(n),a='\n'+r(52-w*4),'  |=|  0  | |  0  | |  0 /   \\ 0.     .0|-----|0|     |0|-----|0|_____|'.split(0).map(x=>a+r((w-c)*8+2)+r(c,' '+x)).join('')+a+r(w*8+5,'#')),(c=91-c)?f(c).slice(6):':(')


Here's the (mostly) ungolfed version:

function (consumed) {
let remaining = 91 - consumed;

function inner (count, width = 13) {
if (count <= 0) return false;

function repeat (count, string = ' ') {
return string.repeat(count);
}

const pattern = [
'  |=|  ',
'  | |  ',
'  | |  ',
' /   \\ ',
'.     .',
'|-----|',
'|     |',
'|-----|',
'|_____|' ];

let clamped = Math.min(count, width);
let alignment = '\n' + repeat((13 - width) * 4);
let empty = alignment + repeat((width - clamped) * 8 + 2);
let shelf = alignment + repeat((width * 8) + 5, '#');
let bottles = pattern.map(row => empty + repeat(clamped, ' ' + row));

return inner(count - width, width - 1) + bottles.join('') + shelf;
}

return (remaining) ? inner(remaining).slice(6) : ':(';
}


### Test code

const golfed =

c=>(f=(c,w=13)=>c>0&&f(c-w,w-1)+(c=c<w?c:w,r=(n,s=' ')=>s.repeat(n),a='\n'+r(52-w*4),'  |=|  0  | |  0  | |  0 /   \\ 0.     .0|-----|0|     |0|-----|0|_____|'.split(0).map(x=>a+r((w-c)*8+2)+r(c,' '+x)).join('')+a+r(w*8+5,'#')),(c=91-c)?f(c).slice(6):':(')

console.log(golfed(91)); // :(
console.log(golfed(72));
//                                                          |=|     |=|     |=|     |=|     |=|     |=|
//                                                          | |     | |     | |     | |     | |     | |
//                                                          | |     | |     | |     | |     | |     | |
//                                                         /   \   /   \   /   \   /   \   /   \   /   \
//                                                        .     . .     . .     . .     . .     . .     .
//                                                        |-----| |-----| |-----| |-----| |-----| |-----|
//                                                        |     | |     | |     | |     | |     | |     |
//                                                        |-----| |-----| |-----| |-----| |-----| |-----|
//                                                        |_____| |_____| |_____| |_____| |_____| |_____|
//     #####################################################################################################
//      |=|     |=|     |=|     |=|     |=|     |=|     |=|     |=|     |=|     |=|     |=|     |=|     |=|
//      | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |
//      | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |
//     /   \   /   \   /   \   /   \   /   \   /   \   /   \   /   \   /   \   /   \   /   \   /   \   /   \
//    .     . .     . .     . .     . .     . .     . .     . .     . .     . .     . .     . .     . .     .
//    |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----|
//    |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     | |     |
//    |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----| |-----|
//    |_____| |_____| |_____| |_____| |_____| |_____| |_____| |_____| |_____| |_____| |_____| |_____| |_____|
// #############################################################################################################

• Very impressive, great answer. I like your r "macro"; I felt like there could be a shorter method but nothing I tried brought it down any. Aug 12, 2017 at 12:26

# C (gcc), 360 358 bytes

#define P printf(
r,i,j;char*b[]={"  |=|  ","  | |  ","  | |  "," /   \\ ",".     .","|-----|","|     |","|-----|","|_____|"};w(n){P"%*c",n,' ');}main(n,a)char**a;{(n=-atoi(a[1]))<-90?P":(\n"):({while(++r<14)if((n+=r)>0){for(j=0;j<9;++j){w(4*(13-r)+1);for(i=r;i>0;)--i<n?P b[j]),w(1):w(8);P"\n");}if(r<13){w(4*(13-r)-2);for(i=0;++i<8*r+6;)P"=");P"\n");}}});}


Try it online!

Explanation:

#define P printf(
r,i,j;
char*b[]={
"  |=|  ",
"  | |  ",
"  | |  ",
" /   \\ ",
".     .",
"|-----|",
"|     |",
"|-----|",
"|_____|"};

// function to print n spaces:
w(n){P"%*c",n,' ');}

main(n,a)char**a;
{
// no beer left?
(n=-atoi(a[1]))<-90

?P":(\n")

// else create stack
// using GCC extension "expression statement" ({ <statement> }) here,
// shorter than if-else or a function call
:({
// loop over 13 rows
while(++r<14)

// found non-empty row?
if((n+=r)>0)
{
// loop over text lines of beer bottles
for(j=0;j<9;++j)
{
w(4*(13-r)+1);

// for each bottle
for(i=r;i>0;)

// print either 8 spaces or line of the bottle
--i<n?P b[j]),w(1):w(8);P"\n");
}

// except for last row, ...
if(r<13)
{
// ... print shelf
w(4*(13-r)-2);
for(i=0;++i<8*r+6;)
P"=");
P"\n");
}
}
});
}


# Python 2, 436 bytes

Yikes!!

My method is too verbose, but anyway: it essentially 'draws' each row of bottles, adds in the spaces, and then 'erases' whatever necessary, printing whatever is left.

B=['  |=|   ','  | |   ','  | |   ',' /   \\  ','.     . ','|-----| ','|     | ','|-----| ','|_____| ']
N=lambda r:sum(n for n in range(1,r+1))
n=input()
R=0
while N(R)<n:R+=1
L=R-n+N(R-1)
e=range(1,R)+([R],[])[L!=0]
for r in range(1,14):
if r in e:continue
if(r-1 in e)<1:print('',' '*(1+(13-r)*4)+'='*(r*8-3))[r!=1]
i=(0,R-L)[r==R];w=(8*i+(13-r)*4,0)[i==0];print'\n'.join([' '*w+((13-r)*4*' '+l*r)[w:]for l in B])
if n=91:print':('


Halvard Hummel's is much better.