Casciitum Scribe

23

3

Introduction

Cacti come in various different sizes, shapes and colors. However, the most iconic cactus and must-have in every Western has to be the saguaro. Important features are its size and arms, which have defined the stereotypical cactus appearance.

Your task is to bring the saguaro in the ASCII world. However, -- as in the real world -- no saguaro is like another, so your program has to be able to generate saguaros with varying arm configurations.

An example saguaro

  • Input: [0b10, 0b11] ([2, 3] in decimal, input length of 2)
     _     
    / \    
 _  | |    
/ \ | |    
| | | |    
\ \_| |    
 \__  |    
    \ |    
 _  | |  _ 
/ \ | | / \
| | | | | |
\ \_| |_/ /
 \__   __/ 
    \ /    
    | |    
    | |    

Specifications

A saguaro always has a base and a top, with variable amounts of stem in between. The stem parts can have no arms, an arm on the right, one on the left or two arms.

Saguaro growth patterns are given as an input list containing two-bit values. 00 means no arms, 01 an arm on the right, 10 an arm on the left and 11 two arms (all in binary). The input list's length determines the saguaro's height.

Saguaro sections look like the following. Cactus parts are surrounded by octothorps, #, for clarity which shall not be printed.
A saguaro's height is always equal to 4+6*k characters for nonnegative integers k.

#############
#     _     # Saguaro top
#    / \    #
#############
# _  | |  _ # Stem, both arms
#/ \ | | / \# Stem id: 11
#| | | | | |#
#\ \_| |_/ /#
# \__   __/ #
#    \ /    #
#############
# _  | |    # Stem, left arm
#/ \ | |    # Stem id: 10
#| | | |    #
#\ \_| |    #
# \__  |    #
#    \ |    #
#############
#    | |  _ # Stem, right arm
#    | | / \# Stem id: 01
#    | | | |#
#    | |_/ /#
#    |  __/ #
#    | /    #
#############
#    | |    # Stem, no arms
#    | |    # Stem id: 00
#    | |    #
#    | |    #
#    | |    #
#    | |    #
#############
#    | |    # Saguaro base
#    | |    #
#############

Input

As previously said, the input consists of a list of two-bit values (0, 1, 2, 3 in decimal). It can be given in any reasonable format. The list's first element corresponds to the saguaro's highest stem part, the second element to its second highest stem part, etc.
If you want, you can require the input list's length as an additional input. Please specify it in your answer if you do so.

Output

Your output ASCII saguaro should be built using the exact stem parts as described above. Trailing spaces on a line and trailing new lines are ignored; you may print more, fewer or as many as specified above.

Rules

Test cases

  • An outlier. Input: [0b01, 0b00, 0b01, 0b11]
     _     
    / \    
    | |  _ 
    | | / \
    | | | |
    | |_/ /
    |  __/ 
    | /    
    | |    
    | |    
    | |    
    | |    
    | |    
    | |    
    | |  _ 
    | | / \
    | | | |
    | |_/ /
    |  __/ 
    | /    
 _  | |  _ 
/ \ | | / \
| | | | | |
\ \_| |_/ /
 \__   __/ 
    \ /    
    | |    
    | |    

  • Alternating arms. Input: [0b10, 0b01, 0b10]
     _     
    / \    
 _  | |    
/ \ | |    
| | | |    
\ \_| |    
 \__  |    
    \ |    
    | |  _ 
    | | / \
    | | | |
    | |_/ /
    |  __/ 
    | /    
 _  | |    
/ \ | |    
| | | |    
\ \_| |    
 \__  |    
    \ |    
    | |    
    | |    

  • An abundance of arms. Input: [0b11, 0b11]
     _     
    / \    
 _  | |  _ 
/ \ | | / \
| | | | | |
\ \_| |_/ /
 \__   __/ 
    \ /    
 _  | |  _ 
/ \ | | / \
| | | | | |
\ \_| |_/ /
 \__   __/ 
    \ /    
    | |    
    | |    

  • No arms, also known as a spear. Input: [0b00]
     _     
    / \    
    | |    
    | |    
    | |    
    | |    
    | |    
    | |    
    | |    
    | |    

  • No body, some call it a young cactus. Input: []
     _     
    / \    
    | |    
    | |    

Jonathan Frech

Posted 2017-09-26T05:13:38.557

Reputation: 6 681

can I take the input as the amount of parts and then each parts number separately? (e.g. 1st test-case would be 4 1 0 1 3) – dzaima – 2017-09-26T13:37:04.880

can we ignore the trailing spaces? – Brian H. – 2017-09-26T13:41:32.000

@dzaima You may. – Jonathan Frech – 2017-09-26T13:58:16.657

@BrianH. Yes; trailing spaces are ignored on every line. – Jonathan Frech – 2017-09-26T13:59:30.107

Answers

10

Charcoal, 50 49 bytes

↘_\¶/F²«J¹¦²Fθ¿﹪÷Iκ⁺¹ι²”{➙∧⊟≕δaL7YF¬⊕ρ↥↖_K”↓⁶↓²‖T

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

↘_\¶/

Draw the top.

F²«

Loop over each side.

J¹¦²

Jump to just under the right side of the top.

Fθ

Loop over each stem part.

¿﹪÷Iκ⁺¹ι²

Test whether there is an arm.

”{➙∧⊟≕δaL7YF¬⊕ρ↥↖_K”

If so print an arm.

↓⁶

Otherwise just print a vertical line.

↓²

After printing the stem, print the base.

‖T

Reflect ready to draw the other side. Once both sides are drawn, the sides are then reflected back into their final position.

Neil

Posted 2017-09-26T05:13:38.557

Reputation: 95 035

7

JavaScript (ES6), 210 bytes

I spent far too long on another solution before realising there was a better way, which didn't leave me as much time as I would've liked to work on this.

a=>`     _
    / \\`+a.map(([x,y])=>`
 1  | |  2
3 5 | | 4 6
7 7 | | 8 8
5 51| |24 4
 511${`| `[x]} ${`| `[y]}224
    ${`|\\`[x]} `.replace(/\d/g,m=>` _/\\|`[m%2?x*-~m/2:y*m/2])+`|/`[y],s=`
    | |`).join``+s+s

Try it

o.innerText=(f=
a=>`     _
    / \\`+a.map(([x,y])=>`
 1  | |  2
3 5 | | 4 6
7 7 | | 8 8
5 51| |24 4
 511${"| "[x]} ${"| "[y]}224
    ${"|\\"[x]} `.replace(/\d/g,m=>` _/\\|`[m%2?x*-~m/2:y*m/2])+"|/"[y],s=`
    | |`).join``+s+s
)(i.value=["11","10","01","00"]);oninput=_=>o.innerText=f(i.value.split`,`)
<input id=i><pre id=o>

Shaggy

Posted 2017-09-26T05:13:38.557

Reputation: 24 623

this in taking literal 00,01,10,11 as input, instead of binary input or 0,1,2,3. using OP test cases this fails. – Brian H. – 2017-09-26T14:14:01.800

@BrianH.: Quoting the challenge spec on input: "It can be given in any reasonable format" – Shaggy – 2017-09-26T14:15:03.460

1but it states "the input consists of a list of two-bit values (0, 1, 2, 3 in decimal)." right before that... (btw im not downvoting or anythin, this is insanely clever, it's just that per my interpretation of the rules the input doesn't match) – Brian H. – 2017-09-26T14:36:43.310

5

Python 2, 189 bytes

lambda l:'     _\n    / \\\n'+'\n'.join(('    |',' /|\  _   \  \|\_    __ |||| \\'[j::6])[i/2]+' '+('|','|||| /   __  /|/_ _   /  \|/'[j::6])[i%2]for i in l for j in range(6))+'\n    | |'*2

Try it online!

Erik the Outgolfer

Posted 2017-09-26T05:13:38.557

Reputation: 38 134

3

Python 2, 256 253...205 203 199 bytes

r=[('     _',''),('/','\ ')]
for a in input()+[0]:r+=zip(*[['|'*6,'_|    |_,,/|  \/  |\,,||  ||  ||,,\| _\/_ |/,,\ ____ /,,\/'[i::2].split(',')][2-i&a>0]for i in 0,1])
for l in r[:-4]:print'%5s %s'%l

Try it online!

TFeld

Posted 2017-09-26T05:13:38.557

Reputation: 19 246

As you do in other string literals, in the first line you can omit the escaping backslash. – Jonathan Frech – 2017-09-26T07:13:11.030

It looks like you could save 18 bytes by removing all the trailing spaces. – Shaggy – 2017-09-26T08:17:38.480

for ...:\n r...\n r... -> for ...:r...;r... saves three bytes. – Jonathan Frech – 2017-09-26T08:30:04.810

1

Java (OpenJDK 8), 626 566 499 466 398 312 310 308 bytes

Can be golfed a tonne

a->{String r=" |,",g="    |",n="     _,    / \\,";boolean j,k;for(int e:a)n+=((k=e>1)?" _  |":g)+((j=e%2>0)?" |  _,":r)+(k?"/ \\ |":g)+(j?" | / \\,":r)+(k?"| | |":g)+(j?" | | |,":r)+(k?"\\ \\_|":g)+(j?" |_/ /,":r)+(k?" \\__ ":g)+(j?"  __/,":r)+(k?"    \\":g)+(j?" /,":r);return(n+g+r+g+r).replace(",","\n");}

Try it online!

Roberto Graham

Posted 2017-09-26T05:13:38.557

Reputation: 1 305

1You can save 2 bytes by changing {j=e>1;k=e%2>0;n+=(k?" _ |":g)+(j?" | _,":r)+ to n+=((k=e%2>0)?" _ |":g)+((j=e>1)?" | _,":r)+ and removing the closing } of the for-loop as well. – Kevin Cruijssen – 2017-09-26T15:22:02.490

You have the "arms" the wrong way 'round for 1 and 2. – Shaggy – 2017-09-26T22:28:46.643

1

PowerShell, 235 bytes

param($a)'     _
    / \'
($a|%{((,'1|'*6),('1|  _
1| / \
1|2
1|_/ /
1 __/ 
1/'),(' _ 2
/ \2
| |2
\ \_| |
 \__  |
    \ |'),(' _ 2  _
/ \2 / \
| |22
\ \_| |_/ /
 \__   __/
    \ /'))[$_]})-replace1,'    | '-replace2,' | |'
,'    | |'*2

Try it online!

PowerShell doesn't have a map or zip or a real easy way to reverse strings, so we're left with something else -- simple replacements of repeated sections.

The first two lines take input as an array of integers and output the top of the cactus. Then we loop through $a and select into an array of four strings based on the current value. Those strings are left on the pipeline and then we use our -replace to fill in the appropriate spots. We then put the bottom of the cactus onto the pipeline as well.

Everything is gathered from the pipeline and an implicit Write-Output happens at program completion, inserting a newline between every element.

AdmBorkBork

Posted 2017-09-26T05:13:38.557

Reputation: 41 581

1

05AB1E, 76 75 bytes

„ _…/ \‚4ú»,v6F'|4ú"_ |/\"•Aö¡Èèj{^ë•5вèJ5ôNè©‚y1›èð'|®∞2äθ‚yÉèJ,}}„| 4úû=,

Try it online!

Emigna

Posted 2017-09-26T05:13:38.557

Reputation: 50 798

1Meh, I'ma try to beat ya, doubt it though. – Magic Octopus Urn – 2017-09-27T19:29:41.687

@MagicOctopusUrn: Good luck! Hope you manage it (and maybe turn it into a skirmish :P) – Emigna – 2017-09-27T20:34:05.367

My one good idea to beat this was squashed by like 30 bytes b/c of the command I posted in the "oasis/05AB1E" chat. Nice golf, if I tried now it'd just be too close. – Magic Octopus Urn – 2017-09-27T20:43:45.690

0

SOGL V0.12, 56 54 53 bytes

5⁷yΙ‚‘∑≡`a#¾‘O.{@.2%i»¹{"⁸G‘6∙;?X"j1>ζ╔²i[n¹‘5n}┼±↔}O

Try it Here!

Explanation:

..‘                   push the ending part - "    | |\n    | |"
   ..‘O               output the starting part - "     _ \n    / \"
       .{             input times do
         @              push a space
          .2%           push input%2
             i»         push floor(prevInput/2)
               ¹        wrap the two in an array

{                   }   for each of the two numbers
 "..‘                     push "|    " - base stem
     6∙                   multiply vertically 6 times
       ;?       }         if the current item iterating over is truthy (i.e. != 0)
         X                  remove ToS - the regular stem - from the stack 
          "..‘              push "|  _ | / \| | ||_/ / __/ /    " - stem with an arm
              5n            split it into line lengths of 5
                 ┼        add that horizontally to the space pushed earlier (or whatever it's become)
                  ±↔      reverse ToS - the stem currently - horizontally
                     O  output the array of the current part

dzaima

Posted 2017-09-26T05:13:38.557

Reputation: 19 048