# Expand a recursive pattern

Given a description of the base state of a recursive ASCII pattern, output an expanded state somewhere along the recursion steps.

More specifically: Let the following be an example:

##..
##..
..__
..__

Where # is filled, . is empty, and _ is recursive.

This describes a pattern wherein the top left quarter is filled, the top right and bottom left are empty, and the bottom right repeats the current pattern.

More rigorously, the pattern is a grid containing some number of #, ., and _. The grid will always be rectangular, and there will be at least one _ and all _ will be in a rectangular sub-grid such that the overall grid's (width, height) is an integer multiple of the sub-grid's (width, height).

Your task is, given such a pattern and a number of steps, build up an expanded form of this pattern. That is, each step, expand the grid by n times (where n is the ratio between the recursive sub-grid and the overall grid), and fill the _ sub-grid with the pattern. At the end, fill the base-state _ all with # or . - you choose which, but it must all be the same, and it must be consistently one or the other no matter the input.

To be VERY rigorous, f(g, n) where f is this challenge, g is the pattern grid, and n is the number of steps, then f(g, 0) == g (with the _ replaced by # OR .), and f(g, n) is the grid scaled up by r ** n times (where r is the ratio of the pattern to the recursive sub-grid), with _ replaced by f(g, n - 1).

Let's do an example:

#.
._

3

At 0 steps, the grid is this:

#.
._

At 1 step, the grid is this:

##..
##..
..#.
..._

At 2 steps, the grid is this:

####....
####....
####....
####....
....##..
....##..
......#.
......._

At 3 steps, the grid is this:

########........
########........
########........
########........
########........
########........
########........
########........
........####....
........####....
........####....
........####....
............##..
............##..
..............#.
..............._

Then, your output can either replace the _ with . or #, but again, all _ must become the same in the final output, and you must always fill it with . or # no matter the input.

# Examples

The _ are shown in this output - you are to replace them with # or ., by choice. They are simply shown as _ just to reduce confusion as to where the _ were and where pre-filled # and . are meant to be.

#.#.
.__#
#__.
.#.#

2

becomes

####....####....
####....####....
####....####....
####....####....
....##..##..####
....##..##..####
......#.#.######
.......__#######
#######__.......
######.#.#......
####..##..##....
####..##..##....
....####....####
....####....####
....####....####
....####....####

(Just gonna put this out there - this is NOT what I thought it would look like AT ALL)

A non-square non-double example:

##.
##.
##.
##.
.#_
.#_

2

becomes

##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
##################.........
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........###############...
.........#########...#####.
.........#########...#####.
.........#########...#####.
.........#########...#####.
.........#########...###.#_
.........#########...###.#_

Last example.

#__#
.##.

3

becomes

###############__###############
##############.##.##############
############..####..############
############..####..############
########....########....########
########....########....########
########....########....########
########....########....########
........################........
........################........
........################........
........################........
........################........
........################........
........################........
........################........

# Rules and Specifications

Input requires a grid and an integer. This grid can be taken in any reasonable, convenient format, and you can replace the characters with any three consistent, distinct values. These can be integers too, for example.

Output requires a grid. This grid can be given in any reasonable, convenient format, and you can replace the characters with any two consistent, distinct values. These do not have to be the same as the ones corresponding to the inputs (why???).

Standard loopholes apply.

This is a challenge, so the shortest program in bytes for each language wins. No answer will be accepted.

Happy golfing!

• @AdmBorkBork That's just to avoid confusion if I put # and then an answer has . and it looks different. It's going to be potentially confusing any way I put it :/ Unless you have a better suggestion :P I am not certain – HyperNeutrino Nov 11 '19 at 18:39
• @AdmBorkBork Fair enough. I'll do that instead. Thanks. – HyperNeutrino Nov 11 '19 at 18:42
• @LuisMendo Whoops - yes. Thanks for catching that. – HyperNeutrino Nov 11 '19 at 20:42
• @ChasBrown At stage 0, it's 2x2, and each time, it scales by x2, so wouldn't stage 1 be 4x4 (like shown) and stage 2 be 8x8 (like shown)? – HyperNeutrino Nov 11 '19 at 20:44
• Ah I see: and all _ will be in a rectangular sub-grid such that... I thought we were replacing each _ with a copy, not some sub-range. – Chas Brown Nov 11 '19 at 20:55

# MATL, 333027 26 bytes

ii:"l1G1=aYm/t&Y"1Gy1=(]Zc

Input is a numerical matrix with 0 for empty, 9 for filled and 1 for recursive.

Replaces recursive by filled at the end.

Output is a character matrix with  (space) for empty and # for filled.

### Explanation

i      % Take first input: matrix, M. This will be grown recursively
i      % Take second input: number, n
:      % Range [1 2 ... n]
"      % For each
l    %   Push 1
1G   %   Push first input, M
1=   %   Compare with 1
a    %   Any. This gives a vector with 1 for columns that contain
%   at least a 1 in input M, and 0 otherwise
Ym   %   Mean. This gives the proportion of columns with 1
/    %   Divide 1 by that. This gives the ratio r referred to in the challenge
t    %   Duplicate
&Y"  %   Repeat elements. This enlarges the current matrix by r along each dimension
1G   %   Push input M again
y    %   Puesh a copy of the current enlarged matrix
1=   %   Compare with 1. Gives a logical mask
(    %   Write M into the positions indicated by that mask
]      % End
Zc     % Convert nonzeros to character '#' and zeros to space. Implicitly display

# Jelly, 32 28 bytes

³,Z¬ÆmṀ\$€İḞ¤xZ¥ƒYṣ0ż³F¤FỴµ¡!

Try it online!

A full program that takes two arguments, a matrix of integers (0-2) and the number of steps and returns a matrix of integers (1-2). 0 is used for the recursive bit.

Thanks to @JonathanAllan for saving two bytes!

## Explanation (outdated)

µ¡ | Repeat the following the number of times indicates by the right argument
¤                | - Following as a nilad:
³                             |   - Original left argument (matrix of integers)
,Z                           |   - Paired with itself transposed
Ɗ€                 |   - For each of the pair, do the following as a monad:
¬                          |     - Not
ẸƇ                        |     - Keep only those with any True values
F                       |     - Flatten
Ɗ                   |     - Following as a monad:
L                      |       - Length
:                     |       - Divided by (integer)
S                    |       - Sum
¥ƒ            | - Reduce using the argument to this iteration as the initial argument and the following as a dyad:
x               |   - Repeat that many times
Z              |   - Transpose
Y           | Join with newlines
ṣ0         | - Split at zeros
ż  ¤     | - Zip with the following as a nilad:
³       | - Original left argument
F      | - Flattened
F    | - Flatten
Ỵ   | - Split at newlines
!| Factorial (0 becomes 1)
• Save a byte with o1 -> !, since $0!=1!$ and $2!=2$ :) ...and another as is implicit there. – Jonathan Allan Nov 11 '19 at 23:03

# Python 2, 250249280266250 248 bytes

def f(p,n):
s=p;Q=L(p[0])
for z in R(n):u,y=[(Q/r.count('_'),y)for y,r in enumerate(s)if'_'in r][0];s=[''.join(s[j/u][i/u]for i in R(u*L(s[0]))).replace('_'*Q,p[(j-y*u)%L(p)])for j in R(u*L(s))]
return[c.replace('_','#')for c in s]
R=range;L=len

Try it online!

Input and output are both lists of strings.

# Japt, 35 bytes

Ê/Uèø0
NÌÆ=c@VÇXmpV r0@NÎ¬gT°
®r0Q

Try it

• You may use <pre></pre> instead of indented text to preserve the leading newline. – Arnauld Nov 12 '19 at 1:20