.B€SðQ2Fø1δ.ø}©˜ƶ®gäΔ2Fø0δ.ø}2Fø€ü3}®*εεÅsyøÅsM]¤θ©δÜ€¦˜0K®Êðs.;ÐÏSāDΩQ·.;0ð:
Uses 2
as random character.
Try it online or verify all test cases.
Explanation:
Step 1: Pad the input with trailing spaces to make it a rectangle, and add an additional border of spaces. Then convert it to a matrix of 0s for |
and -
, and give each space an unique 1-based integer value.
.B # Blockify the (implicit) multi-line input by adding trailing spaces,
# and then split it on newlines
€S # Convert each line to a list of characters
ðQ # Check for each character whether it's a space (1 if space; 0 otherwise)
2Fø1δ.ø} # Add a border of 1s:
2F } # Loop 2 times:
ø # Zip/transpose; swapping rows/columns
δ # Map over each inner list/row:
1 .ø # Surround it with a leading/trailing 1
© # After the loop: store the matrix in variable `®` (without popping)
˜ # Flatten it to a single list
ƶ # Multiply each value by its 1-based index
®g # Push the length (aka amount of rows) of matrix `®`
ä # Split the list of integers back into a matrix of that many rows
Try just this first step online.
Step 2: Flood-fill the positive values in the matrix to identify the islands of spaces:
Δ # Loop until it no longer changes to flood-fill:
2Fø0δ.ø} # Add a border of 0s around the matrix:
2F } # Loop 2 times:
ø # Zip/transpose; swapping rows/columns
δ # Map over each row:
0 .ø # Add a leading/trailing 0
2Fø€ü3} # Convert it into overlapping 3x3 blocks:
2F } # Loop 2 times again:
ø # Zip/transpose; swapping rows/columns
€ # Map over each inner list:
ü3 # Convert it to a list of overlapping triplets
®* # Multiply each 3x3 block by the value in matrix `®`
# (so the 0s remain 0s)
εεÅsyøÅsM # Get the largest value from the horizontal/vertical cross of each 3x3
# block:
εε # Nested map over each 3x3 block:
Ås # Pop and push its middle row
y # Push the 3x3 block again
ø # Zip/transpose; swapping rows/columns
Ås # Pop and push its middle rows as well (the middle column)
M # Push the flattened maximum of the entire (scoped) stack,
# which is the flattened maximum of the cross of the current 3x3 block
] # Close the nested maps and flood-fill loop
Try just the first two steps online.
Step 3: Remove the border and all right-padded trailing space-integers. Then replace that same value to 0s and every other value to 1s in the input-string.
¤ # Push the last row (without popping the matrix)
θ # Pop and push its last item
© # Store this space-integer in variable `®` (without popping)
δ # Map over each row with this space-integer as argument:
Ü # Remove all trailing space-integers from the row
€ # Map over each row again:
¦ # Remove its first character (the leading column of space-integers)
˜ # Then flatten the matrix to a list
0K # Remove all 0s (the "-" and "|")
®Ê # Check for each remaining spaces-value that it's NOT equal to `®`
# (1 if it's a space inside a boundary; 0 if it's a space outside boundary)
ð # Push a space character " "
s # Swap so this list of 0s/1s is at the top
.; # Replace all spaces in the (implicit) input one by one with these 0s/1s
Try just the first three steps online.
Step 4: Transform all 1
s into 0
s, except for a random one, which we'll make 2
instead.
Ð # Triplicate the modified input-string
Ï # Pop two copies, and only keep all 1s
S # Convert this string of 1s to a list of 1s
ā # Push a list in the range [1,length] (without popping the list of 1s)
D # Duplicate it
Ω # Pop and push a random integer from this list
Q # Check which one in the list is equal to it
# (so we have a list of 0s with one random 1)
· # Double each, so the 1 becomes a 2 (0s remains 0)
.; # Then replace all 1s in the modified input one by one with these 0s/2s
Try just the first four steps online.
Step 5: Finally replace all 0
s back to spaces. After which we output the result.
0ð: # Replace every 0 back to a space
# (after which the result is output implicitly)