g | x | w | all
Bytes Lang Time Link
025Vyxal 3 Mj241114T151325Zpacman25
013Vyxal241114T232311Zemanresu
033Japt h241114T170349ZShaggy
023Uiua SBCS240405T205049Zchunes
102Excel240405T233000Zz..
139JavaScript Node.js240405T115400Zl4m2
550Scratch240403T173023ZPatric
184Python 2160901T174930ZNeorej
051Perl160901T095857ZTon Hosp
050Pyth160830T140538ZLeaky Nu
153Python 3160826T223327ZRootTwo
139PowerShell v3+160825T142423ZAdmBorkB
155R160825T143140ZRudier
087Retina160826T085746ZMartin E
017Jelly160825T163252ZDennis
062Perl 6160825T210601Zsmls
070Mathematica160825T115129ZLegionMa
04005AB1E160825T134055ZEmigna
168JavaScript ES6160825T161741ZNeil
317Scala160825T160708ZAmazingD
212Python160825T150659ZJonathan
146VBA Excel160825T131242ZAnastasi
251C#160825T123027ZTheLetha

Vyxal 3 -Mj, 28 25 bytes

ᵛÞỊ∦ÞỊϩfSᵛэÞhᴴv/Rꜝ\Ẋ1ÞẠ“

Vyxal It Online!

neat

-3 by using 1 and 0 instead of . and *

ƛᵛ•=ÞỊ}∦ÞỊϩfSᵛэÞhᴴv/Rꜝ\Ẋ•ÞẠṠ­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢⁤‏⁠⁠‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏‏​⁡⁠⁡‌⁢⁡​‎‏​⁢⁠⁡‌⁢⁢​‎‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠‏​⁡⁠⁡‌⁢⁣​‎⁠‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏⁠‎⁡⁠⁢⁡⁣‏‏​⁡⁠⁡‌⁢⁤​‎‎⁡⁠⁢⁡⁤‏⁠‎⁡⁠⁢⁢⁡‏⁠‎⁡⁠⁢⁢⁢‏‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢⁢⁣‏⁠‎⁡⁠⁢⁢⁤‏⁠‏​⁡⁠⁡‌⁣⁢​‎‎⁡⁠⁢⁣⁡‏⁠‎⁡⁠⁢⁣⁢‏⁠‎⁡⁠⁢⁣⁣‏‏​⁡⁠⁡‌⁣⁣​‎‎⁡⁠⁢⁣⁤‏‏​⁡⁠⁡‌­
ƛᵛ•=ÞỊ}                       # ‎⁡positions of asterisks in each line
       ∦                      # ‎⁢parallel apply wrap
        ÞỊ                    # ‎⁣line has an asterisk
          ϩfS                 # ‎⁤flatten and sort
# ‎⁢⁡this gives a list with the lines and columns that contain asterisks
             ᵛэ               # ‎⁢⁢to each list
               Þhᴴv           # ‎⁢⁣get min/max and decrement the head
                   /Rꜝ        # ‎⁢⁤rangeify and increment
                      \Ẋ      # ‎⁣⁡cartesian product 
                        •ÞẠ   # ‎⁣⁢put an asterisk in the coordinates
                           Ṡ  # ‎⁣⁣vectorised sum to format properly
💎

Created with the help of Luminespire.

Vyxal, 13 bytes

⌊:ÞTƒṡvfΠÞǔ⋎⁋

Try it Online! Kinda clunky but it works, takes a char matrix of 1s/0s as input and outputs a grid of 1s/0s. This could be 1 bytes if taking a boolean matrix was allowed :\

Because of how it's written, this (with fluid I/O) actually works for multidimensional arrays of any size. That said, due to how it's written it'll perform badly on sufficiently large arrays - add a vU after the vf to fix this.

⌊             # Parse input
  ÞT          # Get the multidimensional indices of 1s in the input
    ƒṡ        # Reduce these coordinates by inclusive ranges, 
              # creating a ragged array with every number between the minimum and maximum (trick stolen from Dennis's Jelly answer)
      vf      # Flatten this, getting lists with every number in the range of each coordinate
        Π     # Get all pairs of coordinates
         Þǔ   # and create an array with 1s at these multidimensional indices
 :         ⋎  # and bitwise OR with the input
            ⁋ # Format as a grid

Japt -h, 33 bytes

Started out at well over 40 bytes, so I'll have to be happy with this for now.

Takes input as an array of lines, using 0 for . and 1 for #.

4Æ=ËhV=UËbÍÃfÌrm VnUËaÍÃrÔ çDÍÎÃz

Try it

Uiua SBCS, 28 23 bytes

⍜⊙↻⍜↙∵⋅@#-,+1⊃/↥/↧⊚=@#.

Try it!

⍜⊙↻⍜↙∵⋅@#-,+1⊃/↥/↧⊚=@#.­⁡​‎‎⁡⁠⁢⁢⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢⁡⁤‏⁠‎⁡⁠⁢⁢⁡‏⁠‎⁡⁠⁢⁢⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁡⁣‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁢⁤​‎⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌⁣⁢​‎‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌­
                      .  # ‎⁡‎⁡duplicate
                   =@#   # ‎⁢‎⁢mask of hash characters
                  ⊚      # ‎⁣‎⁣coordinates
             ⊃/↥/↧       # ‎⁤‎⁤maxes and mins of both columns
           +1            # ‎⁢⁡increment the maxes
         -,              # ‎⁢⁢‎⁢⁢subtract mins from maxes non-destructively
⍜⊙↻                      # ‎⁢⁣start in upper left of bounding box...
   ⍜↙                    # ‎⁢⁤‎⁣⁡...taking a rectangle of the specified size...
     ∵                   # ‎⁣⁡‎⁣⁢for each character in this rectangle...
      ⋅@#                # ‎⁣⁢‎⁣⁣pop it and push a hash character

Excel, 102 bytes

=LET(a,A1:J5,x,ROW(a),y,COLUMN(a),r,IF(a,x),c,IF(a,y),(x>=MIN(r))*(x<=MAX(r))*(y>=MIN(c))*(y<=MAX(c)))

enter image description here

JavaScript (Node.js), 139 bytes

s=>(L=R=U=D=a=>a.replace(/[^]/g,c=>c<1?X=++Y&&c:c<'$'?(L=L<X?L:X,R=R>++X?R:X,U=U<Y?U:Y,D=D>Y?D:Y,c):X<R&++X>L&Y>=U&Y<=D?'#':c,X=Y=0))(L(s))

Try it online!

Run the unnamed function twice,

Scratch, 550 bytes

(Hardly a golf, rather an exercise in Scratch to operate on strings and matrices)

Instructions:

Create a sprite with two costumes. Replace Costume 1 with a dot . and Costume 2 with a hash #.

The program asks for two inputs: the "flat" matrix s as a string and k - number of columns. This allows to reconstruct a 2D matrix in Scratch (since there are no arrays in Scratch).

Variables m and p were initialized to 1000 assuming that the matrice would not be larger than 999x999

The pseudocode as well as the code in blocks are following below (the blocks have to be joined together. Here they were separated for making screenshots):
erase all
ask s? and wait
set s to answer
ask s? and wait
set k to answer
set j to 1
set m to 1000
set n to 0
set p to 1000
set q to 0
repeat length of s
 if letter j of s = # then
  set d to (j-1) mod k+1
  set c to (j-d)/k+1
  if c>q then
   set q to c
  if c<p then
   set p to c
  if d>n then
   set n to d
  if d<m then
   set m to d
 change j by 1
set j to 1
show
repeat length of s
 set d to (j-1)mod k+1
 set c to (j-d)/k+1
 if c>(p+1) and d>(m-1) and c<(q-1) and d<(n+1) then
  switch costume to 2
 else
  switch costume to 1
 go to x: d*20 y: c*-20
 stamp
 change j by 1
hide

enter image description here

enter image description here

enter image description here

Test Cases

(Left side - input, right side - output)

enter image description here

Python 2, 184 bytes

def c(i):
 m=n=();e,z=enumerate,'for j,r in e(i):\n for k,c in e(r):%s'
 exec z%'\n  if"#"==c:m+=j,;n+=k,'
 exec z%'\n  if min(m)<=j<=max(m)<[]>min(n)<=k<=max(n):i[j][k]="#"'
 return i

Input and output are a list of strings.

Try it on Ideone (fork of Jonathan Allan's test page)

Perl, 51 bytes

Includes +2 for -0p

Give input on STDIN, off character is A, on character is a, e.g.:

bounding.pl
AAAAAAAAAA
AAaAAAAAAA
AAAAaAAaAA
AAAaAAAAAA
AAAAAAAAAA
^D

bounding.pl:

#!/usr/bin/perl -0p
s%(?=\D*a).+%$a|=$&%eg;s%.*a.*%$a%g;s/a.*a/\L$&/g

Same length:

#!/usr/bin/perl -0p
s%.+%${a./a/g}|=$&%eg;s%.*a.*%$a1%g;s/a.*a/\L$&/g

Pyth, 50 bytes

L}hbebjuXGhHX@GhHeH\#*yhMJs.e,Lkfq\#@bTUb.zySeMJ.z

Try it online!

Python 3, 153 bytes

r=lambda w:list(zip(*w[::-1]))
f=lambda w,n=4:list(map(''.join,n and(('#'in w[0])and r(r(r(f(r(w),n-1))))or[w[0]]+foo(w[1:],n))or['#'*len(w[0])]*len(w)))

Input and output are a list of strings.

ungolfed

r=lambda w:list(zip(*w[::-1]))   # rotate grid cw 90 degrees

def f(w,n=4):
    if n:
        if '#' in w[0]:
            u = r(r(r(f(r(w), n-1))))

        else:
            u = [w[0]] + foo(w[1:], n)

    else:
        u = ['#'*len(w[0])]*len(w)

 return list(map(''.join,u))

theory of operation

The main idea is to remove rows and columns around the outside of the array if they don't have a '#'. Whatever is left should be filled in with '#'s.

It is implemented using a recursive function.

Case 1: row 0 doesn't contain a '#'. Result is row 0 + recursive call on remaining rows.

Case 2: row 0 does contain a '#'. No more rows can be removed. Rotate array cw so that column 0 is now row 0. Then recursively process the rotated array. The result is rotated ccw.

Base case: The array has been rotated 4 times, meaning that all outer rows/columns have been removed if possible. Whatever remains should be filled in with '#'s

PowerShell v3+, 215 162 148 144 139 bytes

param($n)$n|%{(((-join(0..($n[0].length-1)|%{$i=$_;+('1'-in(0..($n.length-1)|%{$n[$_][$i]}))}))-replace'(?<=1.*?).(?=.*?1)',1),$_)[0-ge$_]}

Takes input as an array of strings $n, with 0 instead of . and 1 instead of #. Then, we loop through $n, each iteration testing whether the current string is smaller than 0 (i.e., there's a 1 in it), and if so, output a string. Uses a pseudo-ternary in place of an if/else operation.

The string is constructed from loops through the width of the input string. Each iteration, we tack on a 0 or a 1 depending upon if 1 is found somewhere in the corresponding vertical column. For the last test case, for example, this will result in a string like 0011001001. Requires v3+ for the -in operator. That string is paired with a fancy-dancy regex replace to replace any "inner" 0s with 1s. Much thanks to Business Cat in chat for the assist on that. Our string would be 0011111111 at this point.

Else, output the current (all-zeros) string $_.

The resulting strings are left on the pipeline, and output is implicit. The default Write-Output for an array of strings is with a newline between each element, so that's visually what happens.

Examples

PS C:\Tools\Scripts\golfing> .\highlight-the-bounding-box-cartesian.ps1 '0000000001','0010000000','0000100100','0001000000'
0011111111
0011111111
0011111111
0011111111

PS C:\Tools\Scripts\golfing> .\highlight-the-bounding-box-cartesian.ps1 '0000000000','0000000000','0000100000','0001000000'
0000000000
0000000000
0001100000
0001100000

R, 158 155 bytes

This program takes in input points . and hashtags #, line by line.

v=c();f=which((d=matrix(strsplit(paste0(a<-scan(,""),collapse=""),"")[[1]],nr=sum(a<0),b=T))=="#",a=T);d[min(f[,1]):max(f[,1]),min(f[,2]):max(f[,2])]="#";d

Ungolfed :

a<-scan(,"")             #Input

v=c()                   #Empty vector
f=which((d=(matrix(strsplit(paste0(a,collapse=""),"")[[1]],nr=length(a),b=T)))=="#",a=T) #Main work is here !


d[min(f[,1]):max(f[,1]),min(f[,2]):max(f[,2])]="#"                        #Creates 
                                                                          #the new figure

d                       #Displays it

Here are the details of the third line :

paste0(a,collapse="") 
#Collapses the input into a single string

strsplit(paste0(a,collapse=""),"")[[1]] 
#Split this string character-wise

matrix(strsplit(paste0(a,collapse=""),"")[[1]],nr=sum(a<0),b=T) 
#Creates and fills (by row) a matrix with number of row the number of line of the input

which((d=(matrix(strsplit(paste0(a,collapse=""),"")[[1]],nr=l,b=T)))=="#",a=T)
#Gives the index of the matrix's elements that are "#"

Retina, 87 bytes

Byte count assumes ISO 8859-1 encoding.

Tm`A` `^\GA+¶|(¶A+)+\Z|^(A+?)(?<=(?=\D*^\2Z)\A\D*)|(A+)$(?=\D*\Z(?<!(?<!\3)$\D*))
T`p`L

Uses A for . and Z for #.

Try it online!

Jelly, 21 19 18 17 bytes

|/Tr/FṬ|
ỴµZÇZ&ÇY

This is a full program. Input and output are strings of 0's and 1's, delimited by linefeeds.

Try it online! or verify all test cases.

How it works

ỴµZÇZ&ÇY  Main link. Argument: s (string)

Ỵ         Split s at linefeeds into the array A.
 µ        Begin a new, monadic chain. Argument: A
  Z       Zip/transpose A.
   Ç      Apply the helper link to the transpose.
    Z     Zip/transpose to restore the original order.
      Ç   Apply the helper link to A.
     &    Take the bitwise AND of both results.
       Y  Join, separating by linefeeds.

|/Tr/FṬ|  Helper link. Argument: A (array of strings)

|/        Reduce A columnwise by bitwise OR. This casts to integer.
  T       Truth; yield the indices of 1's.
   r/     Reduce by range. This yields an exponentially growing, nested, ragged
          array that contains all integers between the lowest and highest index
          in the previous result, at least once but possibly multiple times.
     F    Flatten the result.
      Ṭ   Untruth; yield an array with 1's at the specified indices.
          Multiple occurrences of the same index are ignored.
       |  Take the bitwise OR of the result and each row of A.

Perl 6, 62 bytes

{.[.grep(/a/,:k).minmax;$_».grep('a',:k).flat.minmax]='a'xx*}

An anonymous routine that can be passed an array of arrays of characters (representing the matrix) as argument, and modifies it in-place so that the calling scope has the modified array afterwards.

Uses a instead of # as the "on" character. The "off" character can be anything, it doesn't care.

Mathematica, 91 70 bytes

21 bytes saved due to @MartinEnder.

ReplacePart["."+0#,Tuples[Range@@@MinMax/@(#~Position~"#")]]->"#"]&

Anonymous function. Takes a character matrix as input an returns a character matrix as output. The Unicode character is U+F3C7 for \[Transpose].

05AB1E, 70 68 69 61 58 60 40 bytes

€S`¹gG~}Dg©L*0KŸ<U¹v¼y1åi®FXNå}ë0®×}J}¾ä

Explanation

€S`                                       # split each string in input to a charlist and place separately on stack
   ¹gG~}                                  # OR the char arrays to produce a single list with 1's in the columns that have 1's and 0 in the rest
        Dg L*                             # multiply by indices (1-indexed)
          ©                               # store row length in register
             0K                           # remove 0's (the indices which should not have 1's
               Ÿ<U                        # store a list of the indices that should have 1's in X
                  ¹v                 }    # for each string in input
                    ¼                     # increase counter
                     y1åi      ë   }      # if the row contains at least one 1
                         ®FXNå}           # push 1 for indices which should have 1 and else 0
                                0®×       # else push a row of 0's
                                    J     # join into a string
                                      ¾ä  # split the string in rows

Try it online

JavaScript (ES6), 168 bytes

s=>/^#/gm.test(s)?/#$/gm.test(s)?s.replace(/^.*#[^]*#.*$/m,s=>s.replace(/./g,'#'))?f(s.replace(/.$/gm,'')).replace(/$/gm,'.'):f(s.replace(/^./gm,'')).replace(/^/gm,'.')

Takes input as a multiline string. Works by recursively stripping leading and trailing .s from all lines until at least one line begins and one ends with a #, then selects as many lines as possible but starting and finishing on lines containing # and changes all the .s to #. Probably readily golfable.

Scala, 317 characters

val a=input.split("\n");val e=a.map{s=>(s.indexOf("#"),s.lastIndexOf("#"))}.zipWithIndex.filter(_._1._1!= -1);val b=(e.map{s=>s._1._1}.min,e.map{s=>s._1._2}.max,e.head._2,e.last._2);print((0 to a.length-1).map{y=>(0 to a(y).length-1).map{x=>if(x>=b._1&&x<=b._2&&y>=b._3&&y<=b._4)"#" else "."}.mkString+"\n"}.mkString)

More readable version, could probably have golfed it more:

val a=input.split("\n")
val e=a.map{s=>
    (s.indexOf("#"),s.lastIndexOf("#"))
}.zipWithIndex        // Need the indexes for the Y values
.filter(_._1._1!= -1) // Ugly because of tupleception: (actual tuple, index)

val b=(
    e.map{s=>s._1._1}.min,
    e.map{s=>s._1._2}.max,
    e.head._2,
    e.last._2)

print(
    (0 to a.length-1).map{y=>
        (0 to a(y).length-1).map{x=>
            if(x>=b._1&&x<=b._2&&y>=b._3&&y<=b._4)"#" 
            else "."
        }.mkString+"\n"
    }.mkString
)

Python, 219 212 bytes

def b(a):j=len(a[0]);g=range;z=g(len(a));h=[i for i in z if'#'in a[i]];w=[i for i,c in[(i,[r[i]for r in a])for i in g(j)]if'#'in c];return[[any((r<h[0],h[-1]<r,c<w[0],w[-1]<c))and'.'or'#'for c in g(j)]for r in z]

(Although I think another method may well be shorter)

Takes and returns a list of list of chars.

Test it on ideoone

VBA Excel, 150 bytes 146 bytes

Instruction:

Create a workbook with two blank worksheets: Sheet1 and Sheet2. Set the input in Sheet1 and then put the following code in the Sheet1 code module

Sub A:For Each C In UsedRange:If C.Value="#"Then Sheet2.Range(C.Address)="#"
Next:For Each C In Sheet2.UsedRange:Range(C.Address)="#":Next:End Sub

Ungolfed the code:

Sub A()

For Each C In UsedRange
    If C.Value = "#" Then Sheet2.Range(C.Address) = "#"
Next

For Each C In Sheet2.UsedRange
    Range(C.Address) = "#"
Next

End Sub

Explanation:

  1. Loop through every cell in the used range Sheet1
  2. Set the conditional statement to copy every cell contains character hashtag (#) in the used range Sheet1 and paste it to the cell in Sheet2 with the same address as Sheet1.
  3. Loop through once again every cell in the used range Sheet2 to copy every cell address in it and then use it to assign character hashtag (#) to the cell in Sheet1 with the same address as the used range Sheet2.

Example I/O:

INPUT

OUTPUT

Caveat: Make sure every cell in Sheet2 always blank every time you run the program.

C#, 262 251 bytes

s=>{int l,t,r,b,i,j,k;l=t=r=b=i=-1;for(;++i<s.Length;){j=s[i].IndexOf('#');if(j>-1){k=s[i].LastIndexOf('#');l=l==-1|j<l?j:l;t=t==-1?i:t;r=k>r?k:r;b=i;}}for(i=t;i<=b;++i)for(j=l;j<=r;){var c=s[i].ToCharArray();c[j++]='#';s[i]=new string(c);}return s;};

Will golf it further when I have more time.

It compiles into a Func<string[], string[]>.

Formatted version:

s =>
{
    int l, t, r, b, i, j, k;
    l = t = r = b = i = -1;

    for (; ++i < s.Length;)
    {
        j = s[i].IndexOf('#');
        if (j > -1)
        {
            k = s[i].LastIndexOf('#');

            l = l == -1 | j < l ? j : l;

            t = t == -1 ? i : t;

            r = k > r ? k : r;

            b = i;
        }
    } 

    for (i = t; i <= b; ++i)
        for (j = l; j <= r;)
        {
            var c = s[i].ToCharArray();
            c[j++] = '#';
            s[i] = new string(c);
        }

    return s;
};