24
\$\begingroup\$

Draw an ASCII-art rainbow!

Input

An integer between 0 and 1000, inclusive.

Examples

Input 0:


/\
||

Input 1:

 _
/ \
| |

Input 2:

 __
/  \
|  |

Input 3:

 ___
/   \
|   |

The first row is a space followed by n underscores.

The second row is a slash followed by n spaces, and a backslash.

The third row is a pipe followed by n spaces, and a pipe.

Trailing spaces are allowed.

This is . Shortest code wins.

\$\endgroup\$
5
  • \$\begingroup\$ May we take input as 0009 or 0561 instead of 9 and 561 if it is less than 1000? \$\endgroup\$
    – Dion
    Aug 3, 2020 at 16:10
  • \$\begingroup\$ @Dion Yes, that is acceptable. \$\endgroup\$
    – nph
    Aug 3, 2020 at 16:11
  • 15
    \$\begingroup\$ I'd call this an arch, not a rainbow \$\endgroup\$ Aug 4, 2020 at 13:05
  • 3
    \$\begingroup\$ @NooneAtAll A rainbow is an arch, isn't it? \$\endgroup\$
    – user96495
    Aug 6, 2020 at 2:24
  • 3
    \$\begingroup\$ it's Π house shaped \$\endgroup\$ Aug 6, 2020 at 16:00

60 Answers 60

1
2
2
\$\begingroup\$

Cinnamon Gum, 15 bytes

00000000: 70 05 1f 78 e5 2d 36 4e 0b 94 1d 5b d2 c7 fd

Try it online!

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

Whispers v2, 92 bytes

> 1
> Input
> " _\n/ \\\n| |"
>> Then 1 2 1 1 2 1 1 1 2 1
>> L⋅R
>> Each 5 4 3
>> Output 6

Try it online!

Sort of a run-length encoding.

Line 3 encodes the input without sequences of repeated characters. Line 4 builds the list of counts (1 is 1, 2 is the input). Line 6 combines them together repeating each character as many times as needed.

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

Whispers v2, 148 135 111 bytes

> Input
> "_"
> " "
> "/"
> "|"
> "\\"
>> 1⋅2
>> 3+7
>> 3⋅1
>> 4+9
>> 10+6
>> 5+9
>> 12+5
>> Output 8 11 13

Try it online!

This took much longer than expected to make.

-13 bytes from Michael Chatiskatzi.

-24 bytes from Leo.

\$\endgroup\$
2
  • \$\begingroup\$ You could use Then to concat your lines. That would be 135 bytes. \$\endgroup\$ Feb 7, 2021 at 19:07
  • 1
    \$\begingroup\$ Or you could use Output directly with multiple arguments. That would be 111 bytes. \$\endgroup\$
    – Leo
    Feb 9, 2021 at 3:09
2
\$\begingroup\$

Vyxal j, 18 bytes

\_2꘍f*` /|`vøṀ$¨vj

Try it online or verify all test cases.

How?

\_2꘍f*` /|`vøṀ$¨vj
\_                 # Push "_"
  2꘍               # Append two spaces, making this "_  "
    f              # Convert to list of characters
     *             # Repeat each the input amount of times
      ` /|`        # Push string " /|"
          vøṀ      # For each (implicitly converting to a list), mirror it, flipping "/" to "\"
             $     # Swap
              ¨vj  # Join each in the other list by the corresponding value in the top list
                   # j flag joins on newlines
\$\endgroup\$
1
\$\begingroup\$

Ruby, 57 bytes

n=gets.to_i
$><<' '+?_*n+" \n/"+' '*n+"\\\n|"+' '*n+'|'

Try It Online!

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

Python 3, 57 bytes

lambda x:[print(z+y*x+a)for y,z,a in["_  "," /\\"," ||"]]

Try it online!

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

C (gcc), 75 bytes

i;f(n){for(i=-1;n-i++;)putchar(i?95:32);printf("\n/%*c\n|%*c",i,92,i,124);}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ TiO throws some errors. Seems there is a closing parenthesis missing after the putchar() call. \$\endgroup\$
    – gastropner
    Aug 3, 2020 at 23:06
  • \$\begingroup\$ @gastropner whoops, thanks for the catch! \$\endgroup\$
    – att
    Aug 4, 2020 at 1:26
1
\$\begingroup\$

Perl 6, 49 bytes

Edit: -4 bytes

->$n {my$s=" "x$n;my$u="_"x$n;" $u\n/$s\\\n|$s|"}

Try it online!

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

Io, 127 bytes

method(x,list(" _ ","/ \\","| |")map(i,list(i at(0)asCharacter,i at(1)asCharacter repeated(x),i at(2)asCharacter)join println))

Try it online!

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

PHP, 63 61 60 bytes

$a=++$argn;printf("%-'_{$a}s
/%{$a}s
|%{$a}s",' ','\\','|');

Try it online!

printf seemed the optimal way, but I may be wrong..

EDIT: saved 2 bytes with a multiline string

EDIT 2: saved another one by init $a before

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

Retina, 22 bytes

.+
 $0*_¶/$0* \¶|$0* |

Try it online or verify a few more test cases.

Pretty straight-forward: convert the input to unary, using that amount of '_' ($0*_) and two times that amount of spaces ($0* ) respectively, surrounded with the rest of the output (leading space on the first line; surrounded with /\ on the second line; and surrounded with || on the third line).

\$\endgroup\$
2
  • \$\begingroup\$ Huh, why didn't I think to post a Retina answer... \$\endgroup\$
    – Neil
    Aug 5, 2020 at 8:58
  • \$\begingroup\$ @Neil I was wondering the same thing when I saw your Charcoal answer but no Retina answer yet. ;) \$\endgroup\$ Aug 5, 2020 at 9:08
1
\$\begingroup\$

Whitespace, 243 bytes

[S S S T    S T T   T   S S N
_Push_92_|][S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input][N
S S N
_Create_Label_LOOP1][S N
S _Duplicate][N
T   S S N
_If_0_Jump_to_Label_DONE_WITH_LOOP1][S S S T    N
_Push_1][T  S S T   _Subtract][S S S N
_Push_0_space][S N
T   _Swap_top_two][N
S N
N
_Jump_to_Label_LOOP1][N
S S S N
_Create_Label_DONE_WITH_LOOP1][S N
N
_Discard_top][S S S T   S T T   T   S S N
_Push_92_|][S S T   T   S T T   S N
_Push_-22_newline][S S S T  T   T   T   S S N
_Push_60_\][S S S N
_Push_0][T  T   T   _Retrieve_input][N
S S T   N
_Create_Label_LOOP2][S N
S _Duplicate][N
T   S S S N
_If_0_Jump_to_Label_DONE_WITH_LOOP2][S S S T    N
_Push_1][T  S S T   _Subtract][S S S N
_Push_0_space][S N
T   _Swap_top_two][N
S N
T   N
_Jump_to_Label_LOOP2][N
S S S S N
_Create_Label_DONE_WITH_LOOP2][S N
N
_Discard_top][S S S T   T   T   T   N
_Push_15_/][S S T   T   S T T   S N
_Push_-22_newline][S S S N
_Push_0][T  T   T   _Retrieve_input][N
S S S T N
_Create_Label_LOOP3][S N
S _Duplicate][N
T   S T S N
_If_0_Jump_to_Label_PRINT_LOOP][S S S T N
_Push_1][T  S S T   _Subtract][S S S T  T   T   T   T   T   N
_Push_63__][S N
T   _Swap_top_two][N
S N
S T N
_Jump_to_Label_LOOP3][N
S S T   S N
_Create_Label_DONE_WITH_LOOP3][S S S T  S S S S S N
_Push_32][T S S S _Add][T   N
S S _Print_as_character][N
S N
T   S N
_Jump_to_Label_PRINT_LOOP]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

Push the codepoint of "|", minus the constant 32
Integer n = STDIN as integer
Integer t = n
LOOP1:
  If(t == 0):
    Jump to DONE_WITH_LOOP1
  t = t - 1
  Push codepoint of " ", minus the constant 32
DONE_WITH_LOOP1:
  Discard t
  Push "|\n\", minus the constant 32
  Integer t = n
LOOP2:
  If(t == 0):
    Jump to DONE_WITH_LOOP2
  t = t - 1
  Push codepoint of " ", minus the constant 32
DONE_WITH_LOOP2:
  Discard t
  Push "/\n"
  Integer t = n
LOOP3:
  If(t == 0):
    Jump to PRINT_LOOP
  t = t - 1
  Push codepoint of "_", minus the constant 32
PRINT_LOOP:
  (note, we don't discard t this time, since we need the codepoint of " " minus 32
   for the trailing character, which is just like t also 0)
  Print the top value + constant 32 as character to STDOUT
  Go to the next iteration of PRINT_LOOP

Uses this Whitespace tip of mine to print the output after pushing the characters in reversed order minus a certain constant, which will exit the program with an error as soon as we're done with printing and the stack is empty. The optimal constant 32 is generated by this Java program (based on \$n=1\$).

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

brainfuck, 174 bytes

only works with input from 0 to 9, didn't think about this problem while writing the program

++++[>++++<-]>[->++++++++>+++>++>>>++++++>++++++>+>+++<<<<<<<<<]>---->->>>,>->---->------>[-<<<<->>>>]<<<<<<.>>[->.<<+>]>>>.<<<<<<.>>[-<.>>+<]>>>.>.<<<<<<<.>>>>[-<+<.>>]<<<<.

Try it online!

comments

++++[>++++<-]>  store 16 in cell 0
[               while cell 0 != 0
    -           cell 0 remove 1   total 0
    >++++++++   cell 1 add    8   total 128
    >+++        cell 2 add    3   total 48
    >++         cell 3 add    2   total 32
    >>          leave 2 empty cells
    >++++++     cell 6 add    6   total 96
    >++++++     cell 7 add    6   total 96
    >+          cell 8 add    1   total 16
    >+++        cell 9 add    3   total 48
    <<<<<<<<<   return to cell 0
]
>---->->>>,>->---->------ ajust cells to 0 124 47 32 0 0 92 95 10 48
                                            |   / space   \  _ \n  0
                          and take input into cell 5
>[-<<<<->>>>]             remove 48 from cell 5 
                          transforming the digit character into the numeric value
<<<<<<.                   print a space
>>[->.<<+>]               print n times _
>>>.                      print a new line
<<<<<<.                   print /
>>[-<.>>+<]               print n spaces
>>>.                      print \
>.                        print a new line
<<<<<<<.                  print |
>>>>[-<+<.>>]             print n spaces
<<<<.                     print |

brainfuck, 359 bytes, with input up to 255

input must take 3 characters, e.g. 42 must be inputted as 042

++++[>++++<-]>[->++++++++>+++>++>>>++++++>++++++>+<<<<<<<<]>---->->>>>->---->------>++++++++[->++++++<]>>-[>++<-----]>--<,>>,>++++++++++>,<<<<<[->->>->>-<<<<<]>[->[-<<+<+>>>]<<<[->>>+<<<]>>]>[-]>[-<<+>>]>[-<<+>>]>[-<<+>>]<<<<<>[->[-<<+<+>>>]<<<[->>>+<<<]>>]>>[-<<<+>>>]<<<[-<<<<<+>>>>>]<<<<<<<.>>[->.<<+>]>>>.<<<<<<.>>[-<.>>+<]>>>.>.<<<<<<<.>>>>[-<+<.>>]<<<<.

Try it online!

Create characters

++++[>++++<-]>  store 16 in cell 0
[               while cell 0 != 0
    -           cell 0 remove 1   total 0
    >++++++++   cell 1 add    8   total 128
    >+++        cell 2 add    3   total 48
    >++         cell 3 add    2   total 32
    >>          leave 2 empty cells
    >++++++     cell 6 add    6   total 96
    >++++++     cell 7 add    6   total 96
    >+          cell 8 add    1   total 16
    <<<<<<<<   return to cell 0
]
>---->->>>>->---->------  ajust cells to 0 124 47 32 0 0 92 95 10
                                            |   / space   \  _ \n

Input

>++++++++[->++++++<]>>-[>++<-----]>--<,>>,>++++++++++>,
    set cells :
        10 to 48
        11 to input 1
        12 to 100
        13 to input 2
        14 to 10
        15 to input 3
<<<<<                                move to cell 10
[->->>->>-<<<<<]                     remove 48 to cells 10 11 13 and 15
                                     getting digits from the characters
>[->[-<<+<+>>>]<<<[->>>+<<<]>>]      set cell 10 to cell 11 times cell 12
>[-]>[-<<+>>]>[-<<+>>]>[-<<+>>]<<<<< move cells 13 14 and 15 to cells 11 12 and 13 
>[->[-<<+<+>>>]<<<[->>>+<<<]>>]      add cell 11 times cell 12 to cell 10
>>[-<<<+>>>]<<<                      add cell 13 to cell 10
[-<<<<<+>>>>>]                       move cell 10 to cell 5
              

Actual drawings

<<<<<<<.                  print a space
>>[->.<<+>]               print n times _
>>>.                      print a new line
<<<<<<.                   print /
>>[-<.>>+<]               print n spaces
>>>.                      print \
>.                        print a new line
<<<<<<<.                  print |
>>>>[-<+<.>>]             print n spaces
<<<<.                     print |

brainfuck, 155 bytes, With input as brainfuck byte

++++[>++++<-]>[->++++++++>+++>++>>>++++++>++++++>+<<<<<<<<]>---->->>>,>->---->------<<<<<.>>[->.<<+>]>>>.<<<<<<.>>[-<.>>+<]>>>.>.<<<<<<<.>>>>[-<+<.>>]<<<<.

Try it online!

++++[>++++<-]>  store 16 in cell 0
[               while cell 0 != 0
    -           cell 0 remove 1   total 0
    >++++++++   cell 1 add    8   total 128
    >+++        cell 2 add    3   total 48
    >++         cell 3 add    2   total 32
    >>          leave 2 empty cells
    >++++++     cell 6 add    6   total 96
    >++++++     cell 7 add    6   total 96
    >+          cell 8 add    1   total 16
    <<<<<<<<    return to cell 0
]
>---->->>>,>->---->------ ajust cells to 0 124 47 32 0 0 92 95 10
                                            |   / space   \  _ \n
                          and take input into cell 5

<<<<<.                    print a space
>>[->.<<+>]               print n times _
>>>.                      print a new line
<<<<<<.                   print /
>>[-<.>>+<]               print n spaces
>>>.                      print \
>.                        print a new line
<<<<<<<.                  print |
>>>>[-<+<.>>]             print n spaces
<<<<.                     print |
```
\$\endgroup\$
3
  • \$\begingroup\$ You may be able to require the input given not as an ASCII character but as a brainfuck byte value; being hindered by a language's integer entropy cap is an accepted rule whilst only allowing input characters [0-9] feels a bit arbitrary. \$\endgroup\$ Aug 5, 2020 at 17:30
  • \$\begingroup\$ @JonathanFrech what's the best : do I modify my whole answer or do I add this as a third solution ? \$\endgroup\$
    – jonatjano
    Aug 5, 2020 at 19:50
  • \$\begingroup\$ I would add it as a third solution, as it changes I/O. \$\endgroup\$ Aug 5, 2020 at 21:30
1
\$\begingroup\$

Python 3, 50 bytes

lambda x:print(f" {'_'*x}\n/{' '*x}\\\n|{' '*x}|")

if returning the string is acceptable instead of printing it it'd be 43 bytes

lambda x:f" {'_'*x}\n/{' '*x}\\\n|{' '*x}|"
\$\endgroup\$
1
\$\begingroup\$

C#, 97 bytes

string X(int n)=>$@" {R(n,'_')}
/{R(n)}\
|{R(n)}|";string R(int n,char c=' ')=>new string(c,n);

Try it online!

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

R, 74 bytes

cat(" ",rep("_",n<-scan()),"\n","/",s<-rep(" ",n),"\\\n","|",s,"|",sep="")

Try it online!

I hit a dead end trying to golf this at 77 bytes (or even this).

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

Perl 5 -p, 32 bytes

$#_=$_;$_=$"._ x$_."
/@_\\
|@_|"

Try it online!

Explanation

Pretty straightforward, but the first part of this sets the last index of the undefined list @_ to the (implicit from -p) input ($_). $_ is then set to $" (space) followed by $_ _s, a literal newline, then /, and the interpolated empty list @_ that has a length of $_+1 which, when interpolated in a double quoted string places $" between each (empty) entry, resulting in $_ spaces, then \, a literal newline, then the same mechanism for the final line but using |.

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

MAWP 2.0, 43 41 bytes

32;@!"_"*:10;47;!" "*:92;10;"|":" "*:"|":

Try it!

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

CJam, 25 bytes

S'_qi:A*N'/' A*:Z'\N'|Z'|

Try it online!

Explanation:

S                           Push a space
 '_                         Push an underscore
   qi:A                     Push input and assign it to the variable A
       *                    Repeat underscores A times
        N                   Push a newline
         '/                 Push a slash
           ' A*:Z           Push a space repeated A times ad assign that to variable Z
                 '\N'|      Push a backslash, newline and |
                      Z     Push variable Z
                       '|   Push a |
\$\endgroup\$
1
\$\begingroup\$

Excel, 58 bytes

=" "&REPT("_",A1)&"
/"&REPT(" ",A1)&"\
|"&REPT(" ",A1)&"|"

Straightforward implementation. The line breaks are inside strings to they'll print.

Once the input is large enough, it is difficult to display the entire thing.

Screenshot1

Screenshot1000

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

><>, 97 bytes

<vo" "::+1
o>"_"$1-:@?!v
/\  v~ooa"/"<
!^o:>~" "$1-:@?
" "$1-:@?!vo:>~
\"|"a"\"oo o~^
     ;o"|"/

Takes input on the stack.

Could probably be golfed further.

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

Canvas, 12 bytes

½U_× ¶\¶|+↔│

Try it here!

\$\endgroup\$
1
+50
\$\begingroup\$

Forth (gforth), 97 89 bytes

: e emit ; : b space dup 0 ?do 95 e loop cr 47 e dup spaces 92 e cr 124 e spaces 124 e ; 

Try it online!

-8 bytes from Bubbler.

Forth goes into infinite loops when given 0 for a do loop, since every loop must run atleast once. So a for loop with an if statement is used. Otherwise, this function is pretty straightforward.

\$\endgroup\$
1
  • \$\begingroup\$ ?do..loop runs 0 times when the start and end are the same. \$\endgroup\$
    – Bubbler
    Nov 9, 2020 at 1:55
1
\$\begingroup\$

Batch 154 151 143 133 123 bytes

Notes:

  • start from cmd.exe's command line with arg %1 as integer
  • Output will be line wrapped unless console is resized to a number of columns that supports %1
  • line 1 has a trailing Space
  • Requires windows 10 / virtual terminal support
  • ESC is a stand in for the ansii escape character 0x027
  • Raw code including the character can be found here
    • Or the character can be generated by opening the command prompt and typing:
      • >"%TEMP%\escape.chr" Echo(ALT+027 then pressing ENTER
    • Or output using a for loop with Echo off:
      • (For /F "skip=4 DELIMS=" %a in ('Echo(prompt $E^|cmd')Do Echo(%a) >"%TEMP%\escape.chr"
@Set o=@^<nul set/P 
@Set "f=&@(for /l %%p in (1 1 %1)do %o%"
%o%=ESCB %f%=_)&%o%=ESC[1E/%f%=ESC[s )&%o%=\ESC[1E^|%f%=ESC7 )&%o%=^|

How:

  • virtual teminal positioning codes to position cursor for wall pieces and to effect new lines (ESC[1E) where needed.
  • a for loop macro outputs the crest and whitespace between wall sides -'ESC7Space' is used to allow leading whitespace to be output using <nul set /p =string
  • Cursor positioning is enacted relative to the initial cursor position
\$\endgroup\$
1
\$\begingroup\$

Pyth, 28 bytes

%" %s\n/%s\\\n|%s|"m*dQ(\_dd

Port of @xnor's Python 2 solution.

Try it online!

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

JavaScript, 59 bytes

f=n=>n?f(n-1).replace(/.\n/g,c=>' _'[c<1|0]+c):`  
/\\
||
`

Try it online!

A recursive function. Uses how JS coerces whitespace to 0, and punctuation to NaN.

Not as competitive as Arnauld's JS answers, but I think it's still interesting.

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

Python 3, 58 55 bytes

lambda n:f" {'_'*n if n else''}\n/{' '*n}\\\n|{' '*n}|"

Try it online!

Simple f-string

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

Ly, 42 31 bytes

"| |\ / - "nsp[ol[f:of,]ppo9`o]

Try it online!

This version is shorter using a completely different algorithm. It pushes 3 characters that define what each output line should look like. The leading char, the repeated char, and the closing char. After pushing those triplets to the stack, the code loops until the stack is empty. Each time through the loop prints one line, with an inner loop to generate the repeating characters.

"| |\ \ - "                     - Push 3-char loop instructions
           nsp                  - Read the number, store and delete
              [               ] - Loop once per output line
               o                - print the leading char
                l[     ]p       - load the number, loop that many times
                  f             - pull the char to print forward
                   :o           - duplicate and print
                     f          - pull the iterator number forward
                      ,         - decrement
                         p      - delete the char
                          o     - print closing char
                           9`o  - push a LF and print it
\$\endgroup\$
0
\$\begingroup\$

Bash, 53 bytes

printf -v v %$1s;echo -e " ${v// /_} \n/$v\\\\\n|$v|"

Try it online!

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

Factor, + sequences.repeating 56 bytes

[ "_"over cycle " "rot cycle dup [I  ${}
/${}\
|${}|I] ]

Attempt This Online!

       ! 5
"_"    ! 5 "_"
over   ! 5 "_" 5
cycle  ! 5 "_____"
" "    ! 5 "_____" " "
rot    ! "_____" " " 5
cycle  ! "_____" "     "
dup    ! "_____" "     " "     "

And the rest just interpolates the strings on the data stack into the ${} and prints it out.

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.