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 code-golf 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 :)
-
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– xnor2017年11月24日 18:22:15 +00:00Commented Nov 24, 2017 at 18:22
20 Answers 20
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≥⍵]}
{
...}
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
-
1\$\begingroup\$ {'#-|'[⊖(⍉+⍨)⍣(⍵≤50)⊢⍵>⍎¨∘.,⍨⎕d]} \$\endgroup\$ngn– ngn2017年11月24日 15:53:36 +00:00Commented Nov 24, 2017 at 15:53
-
1\$\begingroup\$ Very close to my approach:
{⊖⍉⍣c⊢10 10⍴(⍵/'-|'⊃⍨c←⍵≤50),100/'#'}
\$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年11月24日 18:41:32 +00:00Commented Nov 24, 2017 at 18:41 -
\$\begingroup\$ @EriktheOutgolfer you only need
99/'#'
\$\endgroup\$ngn– ngn2017年11月25日 09:18:41 +00:00Commented Nov 25, 2017 at 9:18 -
\$\begingroup\$ @ngn oh right,
⍴
\$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年11月25日 09:20:23 +00:00Commented Nov 25, 2017 at 9:20 -
1\$\begingroup\$ @ngn That's quite different. Why don't you post it? \$\endgroup\$Adám– Adám2017年11月25日 19:30:00 +00:00Commented Nov 25, 2017 at 19:30
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
-
\$\begingroup\$
{.
with an over the bounds argument is a nice trick. \$\endgroup\$Jonah– Jonah2017年11月24日 16:23:57 +00:00Commented Nov 24, 2017 at 16:23 -
2\$\begingroup\$ 31 bytes:
(]|.@|:_10{&'#|-'100円{.1+$)>&50
\$\endgroup\$FrownyFrog– FrownyFrog2017年11月24日 21:00:55 +00:00Commented Nov 24, 2017 at 21:00 -
\$\begingroup\$ @ FrownyFrog - Great code! \$\endgroup\$Galen Ivanov– Galen Ivanov2017年11月25日 08:38:01 +00:00Commented 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\$Galen Ivanov– Galen Ivanov2017年11月25日 08:47:03 +00:00Commented Nov 25, 2017 at 8:47
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
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)
-
1\$\begingroup\$ I think
[i*10:-~i*10]
can be[i*10:][:10]
. \$\endgroup\$Jonathan Frech– Jonathan Frech2017年11月24日 12:43:15 +00:00Commented Nov 24, 2017 at 12:43 -
\$\begingroup\$ @JonathanFrech Thanks :) \$\endgroup\$TFeld– TFeld2017年11月24日 13:36:26 +00:00Commented Nov 24, 2017 at 13:36
Jelly, 23 bytes
<©51ị)|-ẋḷ""#ẋ3¤s5Z®¡ṚY
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.
-
\$\begingroup\$ Very nice answer +1. 23 bytes as a monadic link (
ȷ2
->³
) \$\endgroup\$Mr. Xcoder– Mr. Xcoder2017年11月24日 19:53:17 +00:00Commented 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– Mr. Xcoder2017年11月24日 20:13:14 +00:00Commented 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\$Erik the Outgolfer– Erik the Outgolfer2017年11月25日 08:45:12 +00:00Commented Nov 25, 2017 at 8:45
-
\$\begingroup\$ See this discussion I had with Dennis. \$\endgroup\$Mr. Xcoder– Mr. Xcoder2017年11月25日 08:54:12 +00:00Commented Nov 25, 2017 at 8:54
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.
-
2\$\begingroup\$
G<51
should work instead ofG<=50
. \$\endgroup\$Laikoni– Laikoni2017年11月24日 12:30:56 +00:00Commented Nov 24, 2017 at 12:30
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
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
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.
-
\$\begingroup\$ Invalid! From input
51
and after, it misses a row. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年11月24日 18:02:55 +00:00Commented Nov 24, 2017 at 18:02 -
\$\begingroup\$ @EriktheOutgolfer Those edge cases. \$\endgroup\$xnor– xnor2017年11月24日 18:03:28 +00:00Commented Nov 24, 2017 at 18:03
-
\$\begingroup\$ @EriktheOutgolfer Thanks, I think this fixes it? \$\endgroup\$xnor– xnor2017年11月24日 18:05:18 +00:00Commented Nov 24, 2017 at 18:05
-
\$\begingroup\$ Looks like it's fixed. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年11月24日 18:08:09 +00:00Commented Nov 24, 2017 at 18:08
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]:?#}*''}}
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
Charcoal, 25 bytes
NθGTχ#↶F÷θχ⟦χ⟧%θχ¿›θ50‖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
¿›θ50 If q > 50
‖T↖ Reflect diagonally
-
1\$\begingroup\$ @StewieGriffin Oops, wrong diagonal. Sorry for not checking. \$\endgroup\$Neil– Neil2017年11月24日 13:49:49 +00:00Commented Nov 24, 2017 at 13:49
-
\$\begingroup\$ That's actually 25 characters, but 61 bytes, isn't it? \$\endgroup\$ZeroOne– ZeroOne2017年11月24日 18:57:16 +00:00Commented Nov 24, 2017 at 18:57
-
-
\$\begingroup\$ Oh, I see! Thanks for the explanation. :) \$\endgroup\$ZeroOne– ZeroOne2017年11月24日 19:32:28 +00:00Commented Nov 24, 2017 at 19:32
Husk, 24 bytes
↔?T†▼'-≤500S↑C10+R0'|∞'#
Explanation
↔?T†▼'-≤500S↑C10+R0'|∞'# Input is a number, say n=12
∞'# Infinite string of #s: "#######...
+ Prepend to it
'| the character |
R0 repeated n times: "||||||||||||####...
C10 Cut to pieces of length 10: ["||||||||||","||##########","##..
S↑ Take first 10 pieces.
? ≤500 If n is at most 50,
T then transpose,
†▼'- else take minimum with '-' for each character.
↔ Reverse, implicitly print separated by newlines.
SOGL V0.12, 21 bytes
┐* #M*+Mm√H.M»>?H§┐┌ŗ
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 "-"
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
APL (Dyalog Classic), 33 bytes
f←{'#-|'[⊖(⍉+⍨)⍣(⍵≤50)⊢⍵>⍎ ̈∘.,⍨⎕d]}
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
-
\$\begingroup\$ This explanation is excellent, imho. \$\endgroup\$Adám– Adám2017年11月26日 08:58:37 +00:00Commented Nov 26, 2017 at 8:58
q, 51 bytes
{-1@'reverse$[i;::;flip]10 10#@[100#"#";til x;:;"|-"i:x>50];}
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.
-
\$\begingroup\$ You don't need
#
on the firstO
stage, because$.%`
will be at most9
. 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 thatM
stage into the final shape. \$\endgroup\$Martin Ender– Martin Ender2017年11月27日 16:27:07 +00:00Commented Nov 27, 2017 at 16:27 -
\$\begingroup\$ Ah yeah, for example you can move the plain
O
stage to right after theM
stage, so that you can keep using a lookahead instead of a lookbehind. \$\endgroup\$Martin Ender– Martin Ender2017年11月27日 16:27:59 +00:00Commented Nov 27, 2017 at 16:27 -
\$\begingroup\$ @MartinEnder Thanks for your hints; I was able to golf a few more bytes off. \$\endgroup\$Neil– Neil2017年11月27日 22:00:15 +00:00Commented Nov 27, 2017 at 22:00
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
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.
Jelly, 24 bytes
3<51
ȷ2Ḷ<s5ZḤ$Ç¡Ṛị"-|#"Y
How it works
I use too many superscripts...
3<51 ~ Helper link.
3 ~ The input.
< ~ Is smaller than
51 ~ 51?
~ Yields 1 for truthy, 0 for falsy.
ȷ2Ḷ<s5ZḤ$Ç¡Ṛị"-|#"Y ~ Main link.
ȷ2 ~ 1e2 (i.e compressed 100).
Ḷ ~ Lowered range. Yields [0, 100) ∩ Z.
< ~ Is smaller than the input? (element-wise).
s5 ~ 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.
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,,"")
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