Grow Some Flowers!

11

2

Spring has recently arrived, and it is almost the time when flowers start to sprout. So I want you to help them grow.

Your task:

Given two numbers, m, and n, output m flowers randomly placed on an n*n grid.

A single flower looks like this:

&
|

A flower's position is defined by where its & is. When randomly placing two flowers, no two can be in the same place. If one flower's & overlaps another flower's |, display the &. The bottom row of flowers may not contain any &.

Input can be as a number or a string, through any of the standard methods.

Output can be a list of strings, each string representing one row of the grid, or a delimited string following the same guideline as the list. Standard methods of output. Trailing whatevers are allowed, and you can use tabs to separate your flowers. Note that every grid must be completely filled, with spaces or something.

Note that the input will always be valid, you will always be able to legally fit the m flowers into the n by n grid.

Test cases:

Since only very tight test cases can be guaranteed, due to the whole "random placement" bit, that will be the only kind of test case with an answer provided. But I will try all submissions online to make sure that they are valid using some test cases too.

Input for the test cases is given in the form m, n.

Input: 2, 2
Output:

&&
||
--------------
Input: 6, 3
Output:

&&&
&&&
|||

Note that the newline after the word Output: in the test cases is optional.

Other test cases:

  1. 1, 10
  2. 0, 100
  3. 5, 8
  4. 6, 3

Code golf so shortest code wins!

Thank you to ComradeSparklePony for making this challenge and posting it in the Secret Santa's gift box!. Sandbox post

Christopher

Posted 2017-04-21T20:57:26.273

Reputation: 3 428

2When you say "randomly", does every possible outcome need to have equal probability? – xnor – 2017-04-22T06:26:31.380

Answers

5

Jelly, 33 bytes

²‘;⁹R¤ṬṖs⁸×’¤Ẋ€ṙ2B¤F€ZḄị“&|& ”s⁸Y

Try it online!

How?

²‘;⁹R¤ṬṖs⁸×’¤Ẋ€ṙ2B¤F€ZḄị“&|& ”s⁸Y - Main link: n, m        e.g. 3, 2
²                                 - square n                    9
 ‘                                - increment                   10
     ¤                            - nilad followed by link(s) as a nilad:
   ⁹                              -     link's right argument   2
    R                             -     range                   [1,2]
  ;                               - concatenate                 [10,1,2]
      Ṭ                           - untruth (1s at indexes)     [1,1,0,0,0,0,0,0,0,1]
       Ṗ                          - pop                         [1,1,0,0,0,0,0,0,0]
            ¤                     - nilad followed by link(s) as a nilad:
         ⁸                        -     link's left argument    3
           ’                      -     decrement               2
          ×                       -     multiply                6
        s                         - split into chunks           [[1,1,0,0,0,0],[0,0,0]]
             Ẋ€                   - shuffle €ach       (maybe:) [[0,1,0,0,1,0],[0,0,0]]
                  ¤               - nilad followed by link(s) as a nilad:
                2B                -     2 in binary             [1,0]
               ṙ                  - rotate (vectorises)         [[[0,0,0],[0,1,0,0,1,0]],[[0,1,0,0,1,0],[0,0,0]]]
                   F€             - flatten €ach                [[0,0,0,0,1,0,0,1,0],[0,1,0,0,1,0,0,0,0]]
                     Z            - transpose                   [[0,0],[0,1],[0,0],[0,0],[1,1],[0,0],[0,0],[1,0],[0,0]]
                      Ḅ           - from binary (vectorises)    [0,1,0,0,3,0,0,2,0]
                        “&|& ”    - literal                     ['&','|','&',' ']
                       ị          - index into                  [' ','&',' ',' ','&',' ',' ','|',' ']
                               ⁸  - link's left argument        3
                              s   - split into chunks           [[' ','&',' '],[' ','&',' '],[' ','|',' ']]
                                Y - join with newlines          [' ','&',' ','\n',' ','&',' ','\n',' ','|',' ']
                                  - implicit print

Jonathan Allan

Posted 2017-04-21T20:57:26.273

Reputation: 67 804

My mind has been blown – Christopher – 2017-04-22T00:31:16.483

Did You swap meanings of m and n or why do you square m? wth is a nilad? – Titus – 2017-04-22T00:55:01.827

Are these 33 characters really only 33 bytes? – Titus – 2017-04-22T00:56:51.830

1

@Titus I did not swap the meanings, I swapped the input order (and in doing so messed up the explanation), so thanks for catching that. A nilad, (as opposed to a monad or a dyad or ...) is a function that takes no inputs and returns a value - as such a constant is a nilad, as is a single input to a function or program. These really are 33 different bytes - the characters are just an encoding of the 256 bytes Jelly uses as linked to by the word bytes in the header.

– Jonathan Allan – 2017-04-22T01:11:36.657

You almost lost me at rotate. Great job; excellent breakdown! – Titus – 2017-04-22T02:07:01.870

@Titus rotate takes a list and moves everything left, circling back around, so [3,1,4,1,5,9]ṙ2 would yield [4,1,5,9,3,1]. It vectorises, so, for example, [3,1,4,1,5,9]ṙ[2,4] would yield [[4,1,5,9,3,1],[5,9,3,1,4,1]]. I hope that de-mystifies it! – Jonathan Allan – 2017-04-22T02:12:04.240

4

PHP (>=7.1), 135 131 128 116 110 109 bytes

for([,$m,$n]=$argv,$z=$q=$n*$n;$q;)echo" |&"[$m&&rand(0,--$z-$n)<$m?$s[$q]=2+!$m--:$s[$q+$n]/2],"
"[--$q%$n];

takes input from command line arguments; run with -nr or test it online.

breakdown

for([,$m,$n]=$argv,     # import arguments
    $z=$q=$n*$n;        # $q = number of total fields, $z-$n = available for flowers
    $q;                 # loop $q down to 0
)   
    echo" |&"[              # print:
        $m&&rand(0,--$z-$n)<$m  # if (probability $m/($z-$n)), decrement $z
            ?$s[$q]=2+!$m--     # then index 2 (flower), set $s[$q], decrement $m
            :$s[$q+$n]/2        # else if flower above, then 1 (stalk), else 0 (space)
        ],
        "\n"[--$q%$n]           # print newline every $n characters
    ;

Titus

Posted 2017-04-21T20:57:26.273

Reputation: 13 814

1You did add the bytes for the flag right? – Christopher – 2017-04-21T21:25:01.547

@Christopher -r is free; it tells PHP to run code from command line argument. -n resets PHP to default settings.

– Titus – 2017-04-21T21:47:11.163

1@JonathanAllan The version preset there seems to depend on your previous visit; probably a cookie. – Titus – 2017-04-22T00:12:46.353

3

Python 2, 150 bytes

from random import*
n,m=input()
b=[1]*m+[0]*(n*~-n-m)
shuffle(b)
for r in range(n):print''.join(' &|'[f^-s]for s,f in zip([0]*n+b,b+[0]*n)[r*n:r*n+n])

Try it online!

How?

Takes input() from STDIN and unpacks the tuple provided (a comma separated string of decimal integers like 3,6) into n and m.

Creates an ordered, one dimensional n*(n-1) long "flowerbed", b, by concatenating:
- a list containing a "flower" [1] repeated m times; and
- a list containing a "space" [0] repeated n*~-n-m times*.

* The tadpole operator ~ (~x=-1-x) saves 2 bytes with n*~-n-m in place of the more normal looking n*(n-1)-m.

Shuffles (using random's shuffle function) this flowerbed to place the flowers and spaces randomly amongst the n*(n-1) positions.

Steps through the 0-indexed rows, r, and prints each in turn to create a two dimensional flowerbed from the one dimensional one...

The final two dimensional (n*n) flowerbed has stalks, s, one row below flower heads, f, if and only if there is no flower head to show. This is achieved by XORing (^) f with -s where f and s are the 1s and 0s from before and using the result to index into the length 3 string ' &|':

f   s   f^-s   ' &|'[f^-s]
0   0    0     ' '
0   1   -1     '|'  < negative indexing used here
1   0    1     '&'
1   1   -2     '&'  < ...and here.

To get f and s the zip function is used with two copies of the one dimensional flowerbed, one with n trailing spaces (the flower heads) and one with n leading spaces (the stalks). The whole thing is created for each row (to save bytes), and the row required is sliced out using [r*n:r*n+n].

Jonathan Allan

Posted 2017-04-21T20:57:26.273

Reputation: 67 804

2

Python 2, 184 179 bytes

from random import*
m,n=input()
s,a=' &'
l=[s]*n*-~n
while s.count(a)<m:x=randrange(n*n-n);l[x]=a;l[x+n]='|&'[l[x+n]==a];s='\n'.join(''.join(l[i*n:][:n])for i in range(n))
print s

Try it online!

ovs

Posted 2017-04-21T20:57:26.273

Reputation: 21 408

2

Python 2, 129 bytes

from random import*
n,m=input();d=n*n-n
s=''
while d+n:b=0<random()*d<m;m-=b;d-=1;s+=' |&'[-b|(s[~n:-n]=='&')]+'\n'[d%n:]
print s

Try it online!

Generates the output string one character at a time. Randomly chooses whether the current cell is a flower with probability equal to the number m of remaining flowers divided by the number of remaining spaces. Adds a newline every n characters. A blank cell is filled with a stem | if the symbol n from the end is a &.

xnor

Posted 2017-04-21T20:57:26.273

Reputation: 115 687

1

PHP, 111 Bytes

for([,$b,$s]=$argv;$i<$s**2;)echo${+$i}="| &"[(rand(1,$s**2-$s-$i)>$b?0:$b--)>0?2:${$i-$s}!="&"],"\n"[++$i%$s];

Online Version

-1 Byte for a physical Newline

a solution 115 Bytes using max

for([,$b,$s]=$argv;$i<$s**2;)echo${+$i}="&| "[rand(1,max($s**2-$s-$i,1))>$b?1+(${$i-$s}!="&"):!$b--],"\n"[++$i%$s];

This way with 137 Bytes shuffles the first part of the string

for([,$b,$s]=$argv,$a=str_shuffle(($p=str_pad)($p("",$b,_),$s**2-$s));$i<$s**2;)echo$a[$i]<_?" |"[$a[$i-$s]==_&$i>=$s]:"&","\n"[++$i%$s];

Jörg Hülsermann

Posted 2017-04-21T20:57:26.273

Reputation: 13 026

1

JavaScript (ES6), 157 bytes

f=(n,m,a=[...(` `.repeat(n)+`
`).repeat(n)],r=Math.random()*-~n*~-n|0)=>m?(a[r]==` `?a[m--,r]=`&`:0,f(n,m,a)):a.map((c,i)=>c==` `&&a[i+~n]==`&`?`|`:c).join``
<div oninput=o.textContent=f(n.value,m.value)><input id=n type=number min=2 value=2><input id=m type=number min=1><pre id=o>

Explanation: Creates an array representing the grid of flowers plus newlines. Recursively randomly searches for empty squares in which to place flowers until the desired number of flowers is reached. Finally the stems of the flowers are generated where there is space for them.

Neil

Posted 2017-04-21T20:57:26.273

Reputation: 95 035

For some reason this throws an error when n=2 and m=3. – Shaggy – 2017-05-30T11:36:29.680

@Shaggy That's because there's only room for 2 flowers. – Neil – 2017-05-30T12:10:35.663

Ah, I was reading it the wrong way 'round. Apologies. – Shaggy – 2017-05-30T12:14:29.743

1

Charcoal, 27 bytes

Nθ↷FN«J‽θ‽⊖θW⁼KK&J‽θ‽⊖θ&¬KK

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

Nθ

Input n.

Change the default printing direction to downwards.

FN«

Input m and loop that many times.

J‽θ‽⊖θ

Jump to a random location on the grid.

W⁼KK&J‽θ‽⊖θ

If there is already a flower, keep jumping to random locations until a suitable spot is found.

&

Print the flower head.

¬KK

Print the stalk if there is not already a flower head below.

Neil

Posted 2017-04-21T20:57:26.273

Reputation: 95 035