16
\$\begingroup\$

Draw an "apartment" building according to the specifications below.

Basic Rules

Take, as input, the number of floors of the building. Return a building with that many floors meeting the following specifications:

The building will be eight characters wide, with eight underscore characters (_) on top and eight dashes (-) on the bottom.

The first floor of the building will always look like this: | || |.

As long as the building has more than one floor, the top floor will always look like this: | ---- |

All floors in between must be randomly selected between the following:

| - - |

| [] |

|__ __|

Example Outputs:

5 floors:

________
| ---- |
|  []  |
| -  - |
|__  __|
|  ||  |
--------

2 floors:

________
| ---- |
|  ||  |
--------

1 floor:

________
|  ||  |
--------

Specific rules

Your inputted number of floors will, at minimum, be 1.

You may output as a string, a list of strings, a nested list of characters, or any other output format in which the position of each element is clear.

All floor types must have a nonzero chance of appearing at any given level (other than the bottom and the top), but they do not have to be uniformly randomly chosen.

Code-golf, so shortest code wins.

\$\endgroup\$
6
  • \$\begingroup\$ Is it allowed to use different characters to represent _, -, |, [ and ]? \$\endgroup\$
    – Yousername
    May 18 at 0:27
  • 6
    \$\begingroup\$ I don't think that should be allowed, since it's ascii-art. \$\endgroup\$
    – Romanp
    May 18 at 0:33
  • \$\begingroup\$ Is there a minimum maximum number of floors? That is, is it okay if my program doesn't accept floor numbers past a certain amount (say 127)? Also, do imports need to be included? \$\endgroup\$ May 18 at 20:03
  • \$\begingroup\$ Imports should be included, I believe (check the standard rules, though). As long as you can accept a reasonable number, it's fine. Only accepting 3-floor buildings would not, 127 or less is fine. You have to handle the 1 and 2 floor case though. \$\endgroup\$
    – Romanp
    May 18 at 22:23
  • \$\begingroup\$ For languages without a PRNG built into it, can we accept a list of pregenerated random numbers instead? \$\endgroup\$
    – TehPers
    May 26 at 13:29

21 Answers 21

6
\$\begingroup\$

x86-64 machine code, 68 bytes

B8 5F 5F 5F 5F BA 7C 20 2D 2D AB 0F C8 3C 5B 75 02 B0 5D AB B0 0A AA 0F C7 F0 9E B8 7C 20 20 5B 72 0C B8 7C 20 2D 20 74 05 B8 7C 5F 5F 20 92 FF CE 7F D7 B8 7C 20 20 7C 74 D0 6A 08 59 B0 2D F3 AA 88 0F C3

Try it online!

Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes in RDI an address at which to place the result, as a null-terminated byte string, and takes the input number in ESI.

In assembly:

.global f
f:  mov eax, ('_'*0x01010101)  # For the first line.
    mov edx, ('|' | ' '<<8 | '-'<<16 | '-'<<24) # For the next line.
o:  stosd       # Add EAX to the output string, advancing the pointer.
    bswap eax   # Reverse the order of the bytes of EAX.
    cmp al, '[' # Check if the low byte is '[' ...
    jne sf      # ... and if it is ...
    mov al, ']' # ... change it to ']'.
sf: stosd       # Add EAX to the output string, advancing the pointer.
    mov al, '\n'# Set AL to a line feed.
    stosb       # Add that to the output string, advancing the pointer.
    rdrand eax  # Put a random number in EAX.
    sahf        # Set flags from AH (its second byte).
    mov eax, ('|' | ' '<<8 | ' '<<16 | '['<<24) # One of the possibilities.
    jc d        # Jump if CF=1.
    mov eax, ('|' | ' '<<8 | '-'<<16 | ' '<<24) # Another possibility.
    jz d        # Jump if ZF=1.
    mov eax, ('|' | '_'<<8 | '_'<<16 | ' '<<24) # The third possibility.
d:  xchg eax, edx   # Exchange registers.
    dec esi     # Subtract 1 from ESI, counting down from the input number.
    jg o        # Jump back if the number was >1 before the subtraction.
    mov eax, ('|' | ' '<<8 | ' '<<16 | '|'<<24) # For the lowest floor.
    jz o        # Jump back if the number is 0.
    push 8; pop rcx  # Set RCX to 8.
    mov al, '-' # Set AL to '-'.
    rep stosb   # Add AL to the output string RCX times, advancing the pointer.
    mov [rdi], cl   # Add the low byte of RCX, which is now counted down to 0.
    ret         # Return.
\$\endgroup\$
5
\$\begingroup\$

Vyxal, 41 bytes

‹¨2[`  [ - __ `²℅|ð2-]\|p;‛| m4-½J\_4*pøm

Try it Online!

ܬ2                      ;                 # Dyadic map (val, index) to...
   [                 ]                     # If the index is truthy (i.e. not first)
    `  [ - __ `²                           # String literal "  [ - __ ", made into a square (chunks of 3)
                ℅                          # Choose one of these
                 |   ]                     # Else... (first)
                  ð2-                      # " --" - Take a space and append two -s
                       \|p                 # Prepend a |
                           ‛| m            # Take "| " and mirror it
                               4-          # Append four -s
                                 ½J        # Split that in half and append
                                   \_4*p   # Prepend "____"
                                        øm # Vertically mirror (flipping []) and join by newlines
\$\endgroup\$
0
5
\$\begingroup\$

05AB1E, 47 46 44 bytes

-2 thanks to Kevin Cruijssen.

'_4×I≠i"| --"¹ÍF"| - |  [|__ "3äΩ]„| º'-4×»º

Try it online!

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

Python, 102 139 136 ,134 117 bytes

lambda n:[8*"_","| ---- |",*choices(['| -  - |','|__  __|','|  []  |'],k=n)][:n]+[2*"|  |",8*'-']
from random import*

Attempt This Online!

Thanks to @Steffan for pointing out I can't read. Now outputs the correct apartment

-3 bytes thanks to @Steffan
-2 bytes from me
-17 bytes thanks to @loopy walt

\$\endgroup\$
5
  • 1
    \$\begingroup\$ > As long as the building has more than one floor, the top floor will always look like this: | ---- | \$\endgroup\$
    – Steffan
    May 18 at 1:04
  • 1
    \$\begingroup\$ Also: > The first floor of the building will always look like this: | || |. \$\endgroup\$
    – Steffan
    May 18 at 1:05
  • 1
    \$\begingroup\$ @Steffan Wow ok my reading comprehension is not doing great today. Will fix my answer \$\endgroup\$
    – jezza_99
    May 18 at 1:07
  • \$\begingroup\$ (1,2)[n>1] can be (n>1)+1 \$\endgroup\$
    – Steffan
    May 18 at 1:57
  • 2
    \$\begingroup\$ You can save a loop by using random.choices: ato.pxeger.com/… \$\endgroup\$
    – loopy walt
    May 18 at 6:16
4
\$\begingroup\$

C++, 281 bytes

#include<random>
#include<string>
using t=std::string;t a[3]={"| -  - |\n","|  []  |\n","|__  __|\n"};t f(int n){std::random_device g;std::uniform_int_distribution<int>d(0,2);t s("________\n");if(n>1)s+="| ---- |\n";for(int i=2;i<n;++i)s+=a[d(g)];s+="|  ||  |\n--------";return s;}

I didn't want to use the standard C rand and srand functions, so here I go with the standard library of C++.

\$\endgroup\$
3
  • \$\begingroup\$ Here's a port to TIO (using rand because it's code golf): 212 bytes \$\endgroup\$
    – Noodle9
    May 18 at 12:23
  • \$\begingroup\$ And here's a port to TIO (not using rand): 270 \$\endgroup\$
    – Noodle9
    May 18 at 12:29
  • \$\begingroup\$ Building on @Noodle9 266 bytes \$\endgroup\$
    – ceilingcat
    May 22 at 6:54
4
\$\begingroup\$

Perl 5 -n, 110 bytes

@a=map{('| -  - |','|  []  |','|__  __|')[rand 3]}1..$_;@a[0,-1]=("| ---- |","|  ||  |");say for'_'x8,@a,'-'x8

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ I'm never sure if you appreciate the extra golfing or not, but I've played with this and managed to get it down to 94 bytes: Try it online!. I'm going to play with another idea I have but I don't think I can beat this approach... \$\endgroup\$ May 19 at 18:41
4
\$\begingroup\$

Charcoal, 36 bytes

×_⁴⸿E⊖N⎇ι‽⪪| - |  [|__⁴| --⟦|  |⁴⟧‖M

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

×_⁴⸿

Output four _s and then move to the start of the next line.

E⊖N⎇ι‽⪪| - |  [|__⁴| --

Output | -- for the top floor, but randomly choose between | - , | [ and |__ for intermediate floors.

⟦|  |⁴⟧

Output the left half of the ground floor and the ground.

‖M

Reflect to complete the building.

\$\endgroup\$
4
\$\begingroup\$

Excel, 143 142 bytes

Anonymous worksheet function that takes input from cell A1 and output to the calling cell.

="________
"&If(A1>1,"| ---- |
","")&Concat(IfError(Choose(RandArray(A1-2,,1,3,1),"| -  - ","|  []  ","|__  __")&"|
",""))&"|  ||  |
--------"

Example Output

enter image description here

\$\endgroup\$
3
\$\begingroup\$

JavaScript, 168 153 151 149 147 146 140 136 bytes

-13 thanks to Steffan, -2 by emaneresu A, -2 by myself, -2 by myself, -1 by myself, -6 by tsh, and -4 by me

n=>`________${[...Array(n-1)].map((_,i)=>`
|${[` -  - `,`  []  `,`__  __`,` ---- `][Math.random()*3|!i*3]}|`).join``}
|  ||  |
--------`

Try it online!

\$\endgroup\$
7
  • \$\begingroup\$ Try it online! for 155 bytes \$\endgroup\$
    – Steffan
    May 18 at 1:10
  • \$\begingroup\$ Actually, 153 bytes because the a= does not have to be included in the byte count. Relevant meta post. \$\endgroup\$
    – Steffan
    May 18 at 1:12
  • \$\begingroup\$ 151 \$\endgroup\$
    – emanresu A
    May 18 at 1:26
  • \$\begingroup\$ 140 bytes \$\endgroup\$
    – tsh
    May 18 at 2:53
  • \$\begingroup\$ @tsh brilliant, but why !i * 3? I replaced it with 0 and saw no difference. (Edit: When given input 2, your version remains constant, which I suppose is the reason behind it?) \$\endgroup\$
    – code
    May 18 at 3:00
2
\$\begingroup\$

Java (JDK), 160 bytes

f->{var b="________\n|"+(f>1?" ---- |\n|":"");for(var r=3;f-->2;r=3)b+=" -  - ,  []  ,__  __".split(",")[r*=Math.random()]+"|\n|";return b+"  ||  |\n--------";}

Try it online!

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

Google Sheets, 162 159 bytes

="________
"&IF(A1>1,"| ---- |
","")&JOIN("",ARRAYFORMULA(IFERROR(CHOOSE(INT(RANDARRAY(A1-2)*3)+1,"| -  - ","|  []  ","|__  __")&"|
","")))&"|  ||  |
--------"

enter image description here

-2 bytes thanks to Taylor Alex Raine

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Your answer almost looks like an apartment building... \$\endgroup\$
    – Romanp
    May 18 at 23:32
  • \$\begingroup\$ You can use Int in place of Floor to drop two bytes \$\endgroup\$ May 18 at 23:50
2
\$\begingroup\$

C (GCC), 213 bytes

s[]={365256,317512,594576};p(x,i){for(i=0;i++<8;x/=8)putchar("| _-[]"[x&7]);puts("");}c,r;main(n){srand(time(0));scanf("%d",&n);for(p(4793490);--n;p(c++?s[r]:374472))for(r=3;r==3;)r=rand()&3;p(294984);p(7190235);}

Attempt This Online!

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

C++ 20 (GCC), 182 177 170 bytes

#import<regex>
auto f(int i){std::string s(8,95),t[]{" -  - |","  []  |","__  __|"};if(--i)for(s+="\n| ---- |";--i;)s+="\n|"+t[rand()%3];return s+"\n|  ||  |\n--------";}

This requires gcc's #import directive. 95 == '_', so std::string(8, 95) constructs a string of 8 '_'.

Attempt This Online!

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

Perl 5 + -n -M5.10.0, 93 bytes

This is based on golfing @Xcali's answer.

say for"_"x8,(map{(<"|{ ---- , -  - ,  []  ,__  __}|">)[$_-2&&1+rand 3]}2..$_),"|  |"x2,"-"x8

Try it online!


Perl 5 + -n -M5.10.0, 97 bytes

say$_.reverse=~y/[/]/r for'_'x4,(map{(<'|{ --, - ,  [,__ }'>)[$_&&1+rand 3]}0..$_-2),'|  |','-'x4

Try it online!

Not smaller, but a reasonably different approach that might have potential for more golfing...

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

JavaScript (Node.js), 136 bytes

Tied with @code's solution. Used the !i*3 trick to shorten my own solution. Go vote up their answer because mine would be worse without theirs.

n=>['________',...[...Array(n-1)].map((_,i)=>['| -  - |','|  []  |','|__  __|','| ---- |'][Math.random()*3|!i*3]),'|  ||  |','--------']

Try it online!

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

Factor, 139 138 bytes

[ dup [ "________", 1 > [ "| ---- |", ] when 2 [-] [ { "|__  __|""| -  - |""|  []  |"} random , ] times "|  ||  |", "--------", ] f make ]

Try it online!

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

Pip, 63 bytes

P'_X8Fi,DaPi?RC" -  -   []  __  __"<>6'-X4WRsWR:'|P"|  |"X2'-X8

Attempt This Online!

Explanation

Roof:

P'_X8
P      Print
 '_     Underscore
   X8   Repeated 8 times

All floors except ground floor:

Fi,DaPi?RC" -  -   []  __  __"<>6'-X4WRsWR:'|
Fi                                             For i in
  ,Da                                          Range(argument decremented):

      i?                                        If i is nonzero (not top floor):
        RC                                       Random choice from
          " -  -   []  __  __"                   This string
                              <>6                Split into sections of size 6
                                                Else (top floor):
                                 '-X4            Four hyphens
                                     WRs         Wrapped in spaces
                                        WR:'|   Wrap the whole string in pipes
     P                                          Print it

Ground floor and ground:

P"|  |"X2'-X8
P              Print
 "|  |"         That string
       X2       Repeated 2 times
         '-X8  Hyphen repeated 8 times
               Last expression is autoprinted
\$\endgroup\$
1
\$\begingroup\$

Python 3, 164 161 bytes

from random import*
def b(n):
	yield"_"*8
	if n>1:yield"| ---- |"
	for _ in range(n-2):yield choice(["| -  - |","|  []  |","|__  __|"])
	yield"|  |"*2+'\n'+"-"*8

Try it online!

Python generator for the win.

Improvement 1 : Removed unnecessary white-spaces. Thank you @jezza_99 for the suggestion.

\$\endgroup\$
1
  • \$\begingroup\$ -3 bytes by removing unnecessary whitespace \$\endgroup\$
    – jezza_99
    May 18 at 22:10
1
\$\begingroup\$

SWI-Prolog, 177 bytes

N+[A|T]:-length([_|X],N),A='________',-X,append(X,['|  ||  |','--------'],T).
-X:-X=['| ---- |'|T],+T;+X.
+X:-X=[A|T],random_member(A,['| -  - |','|  []  |','|__  __|']),+T;1=1.

Recursion, recursion, recursion.

Try it online!

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

PowerShell, 111 109 102 96 93 bytes

'_'*8
for($x=' ---- ';--$args[0];$x=' -  - ','  []  ','__  __'|random){"|$x|"}
'|  |'*2
'-'*8

Try it online!

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

C (gcc -w), 162 bytes

*a[]={"| -  - |","|  []  |","|__  __|"};f(n,r){r=rand(srand(&n))%3;puts("________");for(n>1&&puts("| ---- |");n-->2;)puts(a[r++%3]);puts("|  ||  |\n--------");}

Test main:

int main(void) {
  int i;

  for(i=0; i<100; i++) {
    f(i);
    puts("");
  }
}

Technically, it's not genuinely random, but every level type has a chance of appearing at every level. Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ As per Code Golf SE tradition, please add your language and byte count to a header at the top of your answer. \$\endgroup\$ May 18 at 19:43
  • \$\begingroup\$ Oops, forgot. Sorry! \$\endgroup\$ May 20 at 23:06

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.