18
\$\begingroup\$

We have a square 10x10 meter garden outside our house. We want to plant grass and make a terrace. We have decided how to divide the garden, but we haven't decided the ratio between amount of grass vs terrace.

We need help visualizing it, and ASCII-art is clearly the best way to do so.


Challenge:

Take an integer in the inclusive range [0, 100] (or optionally decimal [0, 1]) representing how many percent of the garden should be terrace.

One square meter of terrace will be represented by either a dash - or a bar |. One square meter of grass will be represented by a hash mark #.

  • If the amount of terrace is less than or equal to 50%, then the garden should be covered with bars, starting in the bottom left corner, and fill vertically, then horizontally.
  • If the amount of terrace is more than 50% then we want the decking to be the other way (dashes instead of bars), and starting in the bottom left corner, and fill horizontally, then vertically.

Examples:

N = 25%
||########
||########
||########
||########
||########
|||#######
|||#######
|||#######
|||#######
|||#######

N = 75%
##########
##########
-----#####
----------
----------
----------
----------
----------
----------
----------

N = 47%
||||######
||||######
||||######
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####

N = 50%
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####
|||||#####

N = 51%
##########
##########
##########
##########
-#########
----------
----------
----------
----------
----------

N = 0%
##########
##########
##########
##########
##########
##########
##########
##########
##########
##########

N = 100%
----------
----------
----------
----------
----------
----------
----------
----------
----------
----------

This is so the shortest code in bytes win. Standard rules regarding I/O. This is ASCII-art, so the output should look like the examples above. I.e. outputting ["|", "|" ...] is not OK.

Explanations are encouraged as always :)

\$\endgroup\$
1
  • 2
    \$\begingroup\$ My first impression was that the two cases would just mean solving two separate golfing tasks, but there's common structure to be found that makes it worth sharing code between them. \$\endgroup\$
    – xnor
    Nov 24, 2017 at 18:22

20 Answers 20

7
\$\begingroup\$

APL (Dyalog), 34 bytes

Anonymous prefix function expecting integer in range 0–100. Assumes ⎕IO (Index Origin) to be 0, which is default on many systems.

{'#-|'[⊖⍉⍣s⊢10 10⍴100↑⍵⍴1+s←50≥⍵]}

Try it online!

{} lambda; is argument:

'#-|[] index the string with the following array:

50≥⍵ 1 if 50 is greater than or equal to argument, else 0

s← store in s (for small)

1+ increment

⍵⍴ cyclically reshape to argument-length

100↑ take the first hundred of that, padding with zeros

10 10⍴reshape to ten rows and ten columns

 yield that (separates s from 10 10)

⍉⍣s transpose if small

 flip upside-down

\$\endgroup\$
9
  • 1
    \$\begingroup\$ {'#-|'[⊖(⍉+⍨)⍣(⍵≤50)⊢⍵>⍎¨∘.,⍨⎕d]} \$\endgroup\$
    – ngn
    Nov 24, 2017 at 15:53
  • 1
    \$\begingroup\$ Very close to my approach: {⊖⍉⍣c⊢10 10⍴(⍵/'-|'⊃⍨c←⍵≤50),100/'#'} \$\endgroup\$ Nov 24, 2017 at 18:41
  • \$\begingroup\$ @EriktheOutgolfer you only need 99/'#' \$\endgroup\$
    – ngn
    Nov 25, 2017 at 9:18
  • \$\begingroup\$ @ngn oh right, \$\endgroup\$ Nov 25, 2017 at 9:20
  • 1
    \$\begingroup\$ @ngn That's quite different. Why don't you post it? \$\endgroup\$
    – Adám
    Nov 25, 2017 at 19:30
5
\$\begingroup\$

J, 39, 38 37 bytes

[:|.>&50|:'#-|'"0{~_10]\100{.]$1+51>]

How it works:

                     _10]\100{.]$1+51>] - prepares a 10x10 array of 0, 1 or 2
                                 1+51>] - 1 if N<=50 otherwise 2
                               ]$       - list of N copies of the above (1 or 2)
                          100{.         - the above list filled to 100 items with 0
                     _10]\              - reshape the list to a 10x10 array
           '#-|'"0                      - constant array of chars
                   {~                   - replaces each digit 0, 1 or 2 with #, - or |     
     >&50                               - is N>50 ? 
         |:                             - if not, transpose the array
                                          (in fact |: here is rearrange axes
                                           0 - transpose
                                           1 - leave it intact)        
 |.@                                    - reverse the order ot the rows

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ {. with an over the bounds argument is a nice trick. \$\endgroup\$
    – Jonah
    Nov 24, 2017 at 16:23
  • 2
    \$\begingroup\$ 31 bytes: (]|.@|:_10{&'#|-'\100{.1+$)>&50 \$\endgroup\$
    – FrownyFrog
    Nov 24, 2017 at 21:00
  • \$\begingroup\$ @ FrownyFrog - Great code! \$\endgroup\$ Nov 25, 2017 at 8:38
  • \$\begingroup\$ @Jonah - Yes, it's very handy sometimes. I also tried _100{. which puts the fills at the beginning, but then I needed to reverse each row, so I gave it up. \$\endgroup\$ Nov 25, 2017 at 8:47
5
\$\begingroup\$

JavaScript (ES6), 84 bytes

Takes input as an integer in [0...100].

n=>(y=9,g=x=>~y?'|-#'[[x,y][k=n/51|0]*9+x+y<n?k:2]+[`
`[x-9]]+g(x++-9?x:!y--):'')(0)

Test cases

let f =

n=>(y=9,g=x=>~y?'|-#'[[x,y][k=n/51|0]*9+x+y<n?k:2]+[`
`[x-9]]+g(x++-9?x:!y--):'')(0)

;[25, 75, 47, 50, 51, 0, 100]
.forEach(n => O.innerText += n + '%:\n' + f(n) + '\n')
<pre id=O></pre>

Formatted and commented

n => (                          // given the terrace percentage n
  y = 9,                        // and starting with y = 9
  g = x =>                      // g = recursive function taking x:
    ~y ?                        //   if y is greater than or equal to 0:
      '|-#'[                    //     pick the relevant character:
        [x, y][k = n / 51 | 0]  //       using k = 1 if n > 50, 0 otherwise
        * 9 + x + y             //       and comparing either 10 * x + y or 10 * y + x
        < n ?                   //       with n; if we're located over the terrace area:
          k                     //         append either '|' or '-'
        :                       //       else:
          2                     //         append '#'
      ] +                       //     end of character insertion
      [`\n`[x - 9]] +           //     append a linefeed if x == 9
      g(x++ - 9 ? x : !y--)     //     update (x, y) and do a recursive call
    :                           //   else:
      ''                        //     stop recursion
)(0)                            // initial call to g with x = 0
\$\endgroup\$
4
\$\begingroup\$

Python 2, 121 117 116 bytes

def f(n):
 s=[('-|'[n<51]*n+'#'*100)[i*10:][:10]for i in range(10)]
 for l in[s,zip(*s)][n<51][::-1]:print''.join(l)

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think [i*10:-~i*10] can be [i*10:][:10]. \$\endgroup\$ Nov 24, 2017 at 12:43
  • \$\begingroup\$ @JonathanFrech Thanks :) \$\endgroup\$
    – TFeld
    Nov 24, 2017 at 13:36
4
\$\begingroup\$

Jelly, 23 bytes

<©51ị⁾|-ẋḷ"”#ẋ³¤s⁵Z®¡ṚY

Try it online!

Change the number before Ç in the footer to change the input. Works as a monadic link in a program without command-line arguments, which is allowed.

\$\endgroup\$
4
  • \$\begingroup\$ Very nice answer +1. 23 bytes as a monadic link (ȷ2 -> ³) \$\endgroup\$
    – Mr. Xcoder
    Nov 24, 2017 at 19:53
  • \$\begingroup\$ I managed to get 24 bytes too, thought it might be a source of inspiration here too. \$\endgroup\$
    – Mr. Xcoder
    Nov 24, 2017 at 20:13
  • \$\begingroup\$ @Mr.Xcoder I did think of that, but I'm not really sure if I can assume such a thing (would only work in niladic programs? hmm...) \$\endgroup\$ Nov 25, 2017 at 8:45
  • \$\begingroup\$ See this discussion I had with Dennis. \$\endgroup\$
    – Mr. Xcoder
    Nov 25, 2017 at 8:54
3
\$\begingroup\$

SWI Prolog, 249 bytes

p(X):-write(X).
r(X,Y,G):-G=<50,10*X-Y+1=<G,p('|').
r(_,_,G):-G=<50,p('#').
r(X,Y,G):-(10-Y)*10+X>G,p('#').
r(_,_,_):-p('-').
l(_,11,_):-nl.
l(X,Y,G):-r(Y,X,G),Z is Y+1,l(X,Z,G).
a(10,G):-l(10,1,G).
a(Y,G):-l(Y,1,G),Z is Y+1,a(Z,G).
s(G):-a(1,G),!.

The solution is pretty straightforward. Procedure a creates rows, l writes chars to columns in a row and r decides what character should be printed out.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ G<51 should work instead of G<=50. \$\endgroup\$
    – Laikoni
    Nov 24, 2017 at 12:30
3
\$\begingroup\$

MATL, 26 bytes

'|-#'100:i>~o10eG50>?!E]P)

Try it online! Or verify all test cases.

Explanation

'|-#'     % Push this string
100:      % Push array [1 2 ... 100]
i         % Input a number and push it
>~        % Less than or equal (element-wise)? This transforms the
          % array into [true ... true false ... false]
o         % Convert to double. True becomes 1, false becomes 0
10e       % Rehaspe into 10-row matrix, in column-major order
G         % Push input
50>       % Greater than 50?
?         % If so
  !       %   Transpose
  E       %   Multiply by 2 (element-wise). So 0 remains as 0, and
          %   1 becomes 2
]         % End
P         % Flip vertically
)         % Index into string, modularly. So 1 corresponds to '|',
          % 2 to '-', and 0 to '#'
          % Implicitly display
\$\endgroup\$
3
\$\begingroup\$

Python 2, 85 bytes

T=j=10
n=input()+T
while j:print([(n-j)/T*'|',min(n-T*j,T)*'-'][n>60]+'#'*T)[:T];j-=1

Try it online!

In both cases each line is padded on the right by # to length 10, which lets us share that code between the two cases. The number 10 was used often enough that aliasing T=10 saved a decent number of bytes.

\$\endgroup\$
4
  • \$\begingroup\$ Invalid! From input 51 and after, it misses a row. \$\endgroup\$ Nov 24, 2017 at 18:02
  • \$\begingroup\$ @EriktheOutgolfer Those edge cases. \$\endgroup\$
    – xnor
    Nov 24, 2017 at 18:03
  • \$\begingroup\$ @EriktheOutgolfer Thanks, I think this fixes it? \$\endgroup\$
    – xnor
    Nov 24, 2017 at 18:05
  • \$\begingroup\$ Looks like it's fixed. \$\endgroup\$ Nov 24, 2017 at 18:08
2
\$\begingroup\$

Ruby, 92 82 bytes

->n{puts (r=0..9).map{|y|r.map{|x|n>(n>50?100-y*10+x:x*10+9-y)?"|-"[n/51]:?#}*''}}

Try it online!

How it works:

Every cell in the grid has a progressive number starting from the bottom left corner and proceeding horizontally or vertically depending on the value of n:

If n>50, the number is 100-y*10+x otherwise it's x*10+9-y

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

Charcoal, 25 bytes

NθGTχ#↶F÷θχ⟦χ⟧﹪θχ¿›θ⁵⁰‖T↖

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

Nθ                          Input integer into q
  G                         Draw filled polygon
   T                        Directions Right, Down, Left
    χ                       Size 10
     #                      Filled with `#`
      ↶                     Rotate cursor left (now points up)
       F÷θχ                 Repeat q/10 times (integer divide)
           ⟦χ⟧              Print 10 `|`s and move to the next column
              ﹪θχ           Print (q mod 10) `|`s
                 ¿›θ⁵⁰      If q > 50
                      ‖T↖   Reflect diagonally
\$\endgroup\$
4
  • 1
    \$\begingroup\$ @StewieGriffin Oops, wrong diagonal. Sorry for not checking. \$\endgroup\$
    – Neil
    Nov 24, 2017 at 13:49
  • \$\begingroup\$ That's actually 25 characters, but 61 bytes, isn't it? \$\endgroup\$
    – ZeroOne
    Nov 24, 2017 at 18:57
  • \$\begingroup\$ @ZeroOne Charcoal uses its own code page. \$\endgroup\$
    – Neil
    Nov 24, 2017 at 19:30
  • \$\begingroup\$ Oh, I see! Thanks for the explanation. :) \$\endgroup\$
    – ZeroOne
    Nov 24, 2017 at 19:32
2
\$\begingroup\$

Husk, 24 bytes

↔?T†▼'-≤50⁰S↑C10+R⁰'|∞'#

Try it online!

Explanation

↔?T†▼'-≤50⁰S↑C10+R⁰'|∞'#  Input is a number, say n=12
                     ∞'#  Infinite string of #s: "#######...
                +         Prepend to it
                   '|     the character |
                 R⁰       repeated n times: "||||||||||||####...
             C10          Cut to pieces of length 10: ["||||||||||","||##########","##..
           S↑             Take first 10 pieces.
 ?     ≤50⁰               If n is at most 50,
  T                       then transpose,
   †▼'-                   else take minimum with '-' for each character.
↔                         Reverse, implicitly print separated by newlines.
\$\endgroup\$
1
\$\begingroup\$

SOGL V0.12, 21 bytes

┐* #M*+Mm√H.M»>?H§┐┌ŗ

Try it Here!

Explanation:

┐*                     push a vertical bar repeated input times
   #M*                 push "#" repeated 100 times
      +                add the two together
       Mm              mold to a length of 100
         √             convert to a square
          H            rotate clockwise
           .M»>?       if the input is greater than 50
                H        rotate the array clockwise again
                 §       reverse it horizontally
                  ┐┌ŗ    replace "|" with "-"
\$\endgroup\$
1
\$\begingroup\$

dc, 210 197 bytes

[256r^1-255/]sx?dddI/dsT9r-sYI%ddIr-sqdsesm-I/sN[[lNlxx124*PIlN-lxx35*PIPlq1-dsq0<o]dsoxlN1+sNledsq0<oq]sJ50!<J[Ilxx35*PIPlY1-dsY0<E]sElY0<E[lmlxx45*PIlm-lxx35*PIP]sClTI>C[Ilxx45*PIPlT1-dsT0<Z]dsZx

Try it online!

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

APL (Dyalog Classic), 33 bytes

f←{'#-|'[⊖(⍉+⍨)⍣(⍵≤50)⊢⍵>⍎¨∘.,⍨⎕d]}

Try it online!

based on Adám's answer

⎕d is the string '0123456789'

∘., Cartesian product

with itself

⍎¨ evaluate each - get a 10x10 matrix of 0..99

⍵> boolean matrix for where the argument is greater

acts as separator

(⍉+⍨)⍣(⍵≤50) if ⍵≤50 double the matrix (+ with itself) and transpose ()

vertical reverse

'#-|'[ ] index the string '#-|' with each element of the matrix

\$\endgroup\$
1
  • \$\begingroup\$ This explanation is excellent, imho. \$\endgroup\$
    – Adám
    Nov 26, 2017 at 8:58
1
\$\begingroup\$

q, 51 bytes

{-1@'reverse$[i;::;flip]10 10#@[100#"#";til x;:;"|-"i:x>50];}
\$\endgroup\$
1
\$\begingroup\$

Retina, 72 62 bytes

.+
$*|
T`|`-`.{51,}
$
100$*#
M!10`.{10}
O$s`(?<!-.*)\S
$.%`
O`

Try it online! Link includes test cases. Edit: Saved 10 bytes with some help from @MartinEnder. Explanation:

.+
$*|

Repeat | the given number of times

T`|`-`.{51,}

But if the input was at least 51, change them to -s.

$
100$*#

Append 100 #s.

M!10`.{10}

Split into 10 groups of 10, discarding anything left over.

O$s`(?<!-.*)\S
$.%`

If the the input was at least 51, transpose the result.

O`

Sort the result.

Alternative solution, also 62 bytes:

.+
$*|
T`|`-`.{51,}
$
100$*#
M!10`.{10}
O`
O$^s`\S(?!.*-)
$.%`

Sorting before transposing allows a byte saving on the condition for the transposition but costs a byte to get the result in the correct order.

\$\endgroup\$
3
  • \$\begingroup\$ You don't need # on the first O stage, because $.%` will be at most 9. You can also save some byte by avoiding the loop at the cost of another sort stage at the end, like this: tio.run/##K0otycxL/… There's probably even a shorter way to rearrange the result of that M stage into the final shape. \$\endgroup\$ Nov 27, 2017 at 16:27
  • \$\begingroup\$ Ah yeah, for example you can move the plain O stage to right after the M stage, so that you can keep using a lookahead instead of a lookbehind. \$\endgroup\$ Nov 27, 2017 at 16:27
  • \$\begingroup\$ @MartinEnder Thanks for your hints; I was able to golf a few more bytes off. \$\endgroup\$
    – Neil
    Nov 27, 2017 at 22:00
0
\$\begingroup\$

Python 2, 106 103 bytes

n=input();x=n>50;k=x*81+10
while k>0:s='';exec"s+='|-##'[x::2][n<k];k+=x or 10;"*10;print s;k+=x*81-101

Try it online!

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

PHP, 119+1 bytes

$r=str_pad("",100,"#");for($x=50<$n=$argn;$n--;)$r[90+($x?$n%10*2-$n:$n/10-$n%10*10)]="|-"[$x];echo chunk_split($r,10);

Run as pipe with -nR or try it online.

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

Jelly, 24 bytes

³<51
ȷ2Ḷ<s⁵ZḤ$Ç¡Ṛị“-|#”Y

Try it online!

How it works

I use too many superscripts...

³<51 ~ Helper link.

³    ~ The input.
 <   ~ Is smaller than
  51 ~ 51?
     ~ Yields 1 for truthy, 0 for falsy.

ȷ2Ḷ<s⁵ZḤ$Ç¡Ṛị“-|#”Y ~ Main link.

ȷ2                  ~ 1e2 (i.e compressed 100).
  Ḷ                 ~ Lowered range. Yields [0, 100) ∩ ℤ.
   <                ~ Is smaller than the input? (element-wise).
    s⁵              ~ Split into sublists of length 10.
         Ç¡         ~ Repeat <last link as a monad> times (either 1 or 0 times).
      ZḤ$           ~ Zip (transpose) and unhalve element-wise.
           Ṛ        ~ Reverse.
            ị       ~ Modular, 1-based indexing into...
             “-|#”  ~ The literal string "-|#".
                  Y ~ Join by newlines.
\$\endgroup\$
0
\$\begingroup\$

R, 102 bytes

n=scan();m=matrix("#",y<-10,y);m[0:n]="if"(n<51,"|","-");write("if"(n>50,m[,y:1],t(m[y:1,])),"",y,,"")

Try it online!

Reads n from stdin and prints the garden to stdout.

Explanation:

n=scan()               # read from stdin
m=matrix("#",10,10)               # create 10x10 matrix of "#"
m[0:n]="if"(n<51,"|","-")         # set the first n entries in m to the appropriate character
m="if"(n>50,                      # prepare for printing using write
       m[,10:1],                  # reverse m left to right
       t(m[10:1,]))               # flip m top to bottom and transpose
write(m,"",10,,"")                # write m to stdout in 10 columns with no separator

\$\endgroup\$

Your Answer

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

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