g | x | w | all
Bytes Lang Time Link
267AWK241118T191425Zxrs
092Perl 5 lF191004T051103ZXcali
017Japt hR191003T111929ZShaggy
078Ruby221019T164021ZJordan
274C# .NET Core200130T215258ZDestroig
156C clang191004T123322ZAZTECCO
025APL Dyalog Unicode191003T094203ZVen
094PHP 7.4191003T145204Zmanatwor
178Java JDK191004T201548ZAvi
093PowerShell191003T183150ZAdmBorkB
110Python 3191003T093923ZJitse
028k4191003T215346Zscrawl
118Icon191003T131848ZGalen Iv
232TSQL 2017191004T115431Zt-clause
067Perl 6191003T183901Znwellnho
112Red191003T091042ZGalen Iv
029J191003T104853ZGalen Iv
121Ruby191004T011538ZValue In
023APL Dyalog Extended191003T192824ZAdá
019MATL191003T135742ZSanchise
019MATL191003T123818Zflawr
01405AB1E191003T085510ZKevin Cr
016Jelly191003T120024ZJonathan
125Bash + coreutils191003T105338Zmanatwor
125JavaScript ES7191003T101758ZArnauld
027Charcoal191003T090041ZNeil

AWK, 267 bytes

BEGIN{FPAT="[[:alnum:]]+"}
{srand();g=$2+2;h=$3+2
for(;i++<g;)a[i][1]=a[i][h]="#"
for(;j++<h;)a[1][j]=a[g][j]="#"
for(l=split($1,b,X);l;){while(a[x=int(rand()*$2+2)][y=int(rand()*$3+2)]!="");a[x][y]=b[l--]}for(;m++<g;print"")for(n=0;n++<h;)printf a[m][n]?a[m][n]:" "}

Try it online!

BEGIN{FPAT="[[:alnum:]]+"}      # can be done at command line
{srand();g=$2+2;h=$3+2          # seed random
for(;i++<g;)a[i][1]=a[i][h]="#" # build bowl
for(;j++<h;)a[1][j]=a[g][j]="#" # more bowl
for(l=split($1,b,X);l;)         # split input string
{while(a[x=int(rand()*$2+2)][y=int(rand()*$3+2)]!="");
a[x][y]=b[l--]}                 # fill only empty spaces
for(;m++<g;print"")for(n=0;n++<h;)
printf a[m][n]?a[m][n]:" "}     # print finished array

Perl 5 -lF , 99 97 92 bytes

-2 bytes courtesy of @NahuelFouilleul

%k=map{$_=>$F[$_]||$"}0..<>*($n=<>)-1;say+($p='#'x($n+1)),map"#
#"x!($i++%$n).$_,values%k,$p

Try it online!

Japt -hR, 21 18 17 bytes

úV× ö¬òVÌ
4Æ=z mÄ

Try it

úV× ö¬òVÌ\n4Æ=z mÄ     :Implicit input of string U=S and integer array [M,N]
ú                      :Right pad U with spaces to length
 V×                    :  V reduced by multiplication
    ö¬                 :Random permutation
      ò                :Partitions of length
       VÌ              :  Last element of V
         \n            :Reassign to U
           4Æ          :Map the range [0,4)
             =         :  Reassign to U
              z        :    Rotate clockwise
                m      :    Map
                 Ä     :      Append "1"
                       :Implicit output of last element joined with newlines

Ruby, 105 78 bytes

Takes an array of characters and two integers; returns a string.

->s,h,w{((e=?#*w)+(s+[" "]*(h*w-s.size)).shuffle*""+e).gsub /.{#{w}}/,'#\&#
'}

Attempt This Online!

C# (.NET Core), 274 bytes

[Without LINQ]

Embarrassing number of bytes, but, this is what I got.

(x,y,z)=>{var f=new string('#',x+2)+'\n';char[] b=new string(' ',y*x).ToCharArray();Random r=new Random();while(z.Length>0){var d=r.Next(0,y*x);if(b[d]==' '){b[d]=z[0];z=z.Substring(1);}}z=f;for(var j=1;j<y*x+1;)z+=(j%x==1?"#":"")+b[j-1]+(j++%(x)==0?"#\n":"");return(z+=f);}

Try it online!

C (clang), 169 ... 156 bytes

i,b;f(n,m,s)char*s;{char o[b=i=-~++n*(m+=3)],*a=o;for(srand(&a);--i;)*a++=i%m?-~i%m<3|i<m|i>m*n?35:32:10;for(*a=0;*s;*a=*a-32?*a:*s++)a=o+rand()%b;puts(o);}

Try it online!

Saved 7 @ceilingcat suggestion to use -~variable and auto storage for string o plus many improvements.

Saved 4 again from @ceilingcat

Degolf :

char*a,// pointer for set operations 
*o=malloc(b=i=(m+=3)*(n+=2));  => o[b=i=(m+=3)*-~++n]
// before allocating for the whole bowl as a char array
// increments m by 3 (2 for rims and 1 for '\n') and n by one but allocates for 2(rims)
// and assigns bowl size to i and b.
srand(time(0));// seeds rand function 
for(// loop to make empty bowl 
a=o;// using pointer as iterator
 --i ;)//  i decremented as a counter

 *a=// sets every char to..
 i%m?// if(not) over right side of bowl (m+3)
   -~i%m<3|i<m|i>m*n-m?35// if on rim '#'//-~i == (i+1)
   :32 // else ' ' 
  :10;// i%m==0

for(*a=0;// before loop terminates bowl with \0
 *s;// for every letters(exit on '\n')
 *a=*a-32?*a:*s++)
 // puts letter if bowl at a is a space and
 // go to next letter

 a=o+rand()%b; 
 // sets a to o offsetted by random

puts(o);// prints bowl 

APL (Dyalog Unicode), 25 bytesSBCS

'#',∘⌽∘⍉⍣4{⍵⍴⊃¨↓∘⍺¨?⍨×/⍵}

Try it online!

-22 thanks to @ngn, -7 thanks to @ngn and @Adám

Explanation:

'#',∘⌽∘⍉⍣4{⍵⍴⊃¨↓∘⍺¨?⍨×/⍵}
          {            ⍵} ⍝ Function that generates the content
                          ⍝  argument: ⍵ (width and height), ⍺ (string)
                     ×/   ⍝ get the product
                   ?⍨     ⍝ For each randomized elements
               ↓∘⍺¨       ⍝ take the character in ⍺
           ⍵⍴⊃¨           ⍝ turn it back into a matrix of shape ⍵
    ∘ ∘ ⍣4                ⍝ Then, 4 times, do these 3 things:
'#',                      ⍝ - prepend a # to the axis
     ⌽                    ⍝ - reverse the columns
       ⍉                  ⍝ - swap columns and lines

APL (Dyalog Extended), 21 bytesSBCS

The rim's angles are different characters

{⌂disp⊂⍵⍴⊃¨↓∘⍺¨?⍨×/⍵}

Try it online!

Using the dfn to display the box.

PHP 7.4, 107 99 94 characters

fn($s,$r,$c)=>_.chunk_split(($b=str_pad(_,$c,_)).str_shuffle(str_pad($s,$r*$c)),$c,"_
_").$b._

Thanks to:

Try it online!

PHP 7.3, 117 112 108 characters

function s($s,$r,$c){echo _.chunk_split(($b=str_pad(_,$c,_)).str_shuffle(str_pad($s,$r*$c)),$c,"_
_").$b._;}

Thanks to:

Sample run:

php > function s($s,$r,$c){echo _.chunk_split(($b=str_pad(_,$c,_)).str_shuffle(str_pad($s,$r*$c)),$c,"_
php " _").$b._;}
php > s('HELLO', 4, 11);
_____________
_  L        _
_        L  _
_E          _
_    OH     _
_____________

Try it online!

Java (JDK), 180 178 bytes

Not a single extra import:

(y,m,n)->{for(m*=n;y.length()<m;y+=" ");var s="";for(;m-->0;y=s)for(var c:y.split(s=""))s=Math.random()<.5?s+c:c+s;s="#".repeat(n);return(s+y+s).replaceAll(".{"+n+"}","\n#$0#");}

Try it online!

It was quite the struggle to get this golfed down. In particular, the imports involved with Collections.shuffle()/Arrays methods were too much to accept, so I had to create my own String shuffling algorithm (probably neither efficient nor uniformly distributed). Massive thanks to Steven for proving any set of positions can be generated from the algorithm.

Formatted (with explanation):

(y, m, n) ->                                                   // y = yummies in the soup,
{                                                              // m = height, n = width
    for (m *= n; y.length() < m; y += " ")                     // set m to m*n and
        ;                                                      // add spaces to y to fill up
    var s = "";                                                // the rest of the soup
    for (; m-- > 0; y = s)                                     // for m*n iterations, scramble y
        for (var c : y.split(s = ""))                          // with random appends
            s = Math.random() < .5 ? s + c : c + s;
    s = "#".repeat(n);                                         // create the top/bottom of the rim
    return (s + y + s).replaceAll(".{" + n + "}", "\n#$0#"); // add all sides of the rim
};

PowerShell, 163 111 93 bytes

param($w,$h,$s)'#'*$w+-join($s|% *ht($w*$h)|% t*y|sort{Random})+'#'*$w-replace".{$w}",'#$0#
'

Try it online!

Takes input as $width, $height, $string.

Constructs a string of # of the appropriate $width, string-joins that with some computation, and then that same # string again. The computation starts with taking the input $string, and doing a .padRight up to the $width by $height length (i.e., make a string long enough to completely take up the rectangular space. We then convert that string toCharArray, and sort it Randomly. That gives us the mixed-up middle portion. Finally, we -replace it into chunks of equal $width, and surround those chunks with #s.

-52 thanks to inspiration from AZTECCO
-18 bytes thanks to mazzy

Python 3, 110 bytes

lambda s,m,n,r=['#']:[r+(n*r+[i for i,j in{*zip(s+m*n*' ',range(m*n))}]+n*r)[k*n:-~k*n]+r for k in range(m+2)]

Try it online!

Randomizes by using a set comprehension and returns a 2D character array.

k4, 32 28 bytes

{4{|+x,'"#"}/y#a?(a:-*/y)$x}

edit: -4 thanks to Galen Ivanov!

called like

f["hey";3 3]

explanation:

                 (a:-*/y)    / neg product of y and assign to a 
                         $x  / left pad x so we have char vector the length of the inner area
               a?            / take `a` random drawings. if a is negative, draw with no duplicates/replacements
             y#              / reshape to y's dimensions
 4{        }/                / do {} 4 times 
   |+x,'"#"                  / append "#" along right-side of x then transpose (+) and reverse (|)

Icon, 136 133 131 118 bytes

procedure f(s,n,m)
s||:=repl(" ",m*n-*s)
!s:=:?s&\z
write(t:=repl(0,m+2))
write(0,s[1+(0to n)*m+:m],0)&\z
write(t)
end

Try it online!

T-SQL 2017, 232 bytes

Testing this online is an older version of sql-server costing another character. I posted the shorter version.

Golfed:

DECLARE @ varchar(max)=''SELECT top 999 @+=substring(@i,number+1,1)FROM spt_values
WHERE type='P'and number<@a*@b
ORDER BY newid()WHILE-@b<1SELECT @=stuff(@+' ',@b*@a+1,0,'#
#'),@b-=1PRINT stuff(replicate('#',2+2*@a),2+@a,0,trim(@))

Try it online

Ungolfed:

DECLARE @ varchar(max)=''

SELECT top 999 @+=substring(@i,number+1,1)
FROM spt_values
WHERE type='P'and number<@a*@b
ORDER BY newid()

WHILE-@b<1
SELECT @=stuff(@+' ',@b*@a+1,0,'#
#'),@b-=1
PRINT stuff(replicate('#',2+2*@a),2+@a,0,trim(@))

Perl 6, 74 67 bytes

-5 bytes thanks to Jo King

{0 X~0 x$^n,|comb($n,[~] $^s.comb[pick *,^$^m*$n]X//' '),0 x$n X~0}

Try it online!

Explanation

{                                                                 }
                                         ^$^m*$n  # Range 0 .. M*N-1
                                  pick *,  # Shuffle
                         $^s.comb  # Split S into chars
                                 [              ]  # Pick shuffled elements
                                                 X//' '  # undef to space
                     [~]  # Join
             # Split into n-character strings
             comb($n,                                  )
            |  # Flatten
     # Add top and bottom of bowl
     0 x$^n,                                            ,0 x$n
 # Add left and right of bowl
 0 X~                                                          X~0

Red, 120 116 114 112 bytes

-2 bytes thanks to @Kevin Cruijssen!

func[s m n][random pad s m * n insert/dup t: copy"00"0 n
print t loop m[print rejoin[0 take/part s n 0]]print t]

Try it online!

J, 30 29 bytes

-1 byte thanks to Jonah

'#'|.@|:@,^:4[$*/@[(?~@[{{.)]

Try it online!

Ruby, 121 bytes

Creates the bowl, queries the indices of all spaces within the bowl, samples a number of spaces equal to the size of the string, and fills them in. sample does not return a sorted list, so there is no need to shuffle. Searching indices up to 9*m*n (which almost certainly goes out of range) will still get all spaces and is 1 byte shorter than r.size.

->s,m,n{r=[t=?@*(n+2),*["@#{' '*n}@"]*m,t]*$/;i=-1;(0..9*m*n).select{|j|r[j]==' '}.sample(s.size).map{|j|r[j]=s[i+=1]};r}

Try it online!

APL (Dyalog Extended), 23 bytesSBCS

Anonymous tacit infix function. Takes [M,N] as left argument and S as right argument.

'#',∘⌽∘⍉⍣4⊣⍴×/⍛(?⍨⍤⊣⊇↑)

Try it online!

×/⍛() apply the following function between the arguments, replacing the left argument with its product:

 take M×N characters from S, padding with spaces on the right

 reorder that to the following order:

?⍨⍤ the shuffled indices 1 through…
 the left argument (M×N)

reshape that to the following shape:

 the left argument (i.e. M rows and N columns)

'#'⍣4 apply the following function four times, each time with the hash character as left argument:
∘⍉ transpose the right argument
∘⌽ mirror the right argument
, concatenate a column of hashes to the left side of that

MATL, 22 19 bytes

tZ"ibpyn&Z@(TT35&Ya

Try it online!

Thanks @LuisMendo for saving 3 bytes, so now it has the same bytecount as @flawr's answer, but sufficiently different to post anyway. High-level agorithm overview:

 Z"                  % Create n x m matrix of spaces
           (         % Index into this matrix:
   i                 %  The alphabet vermicelli (explicit input)
        &Z@          %  at a random locations (randperm), which are
      yn             %   length(S) numbers, ranging
t   bp               %   from 1 to n*m
            TT35&Ya  % And finally add a border

MATL, 29 27 19 bytes

pZ@iy~hw)1GeTT35&Ya

Try it online!

Thanks @LuisMendo for -8 bytes!

Explanation: p computes the number of soup-pixels. Then Z@ produces a random permutation of size of number of soup pixels. We will use this as indices to iy~h which is the input string with enough spaces added. w) swaps the two and indexes one with the other. We then reshape 1Ge the shape into the desired rectangle and #-pad it using TT35&Ya.

05AB1E, 20 18 16 15 14 bytes

*j.rS²ô2Føε8.ø

Takes three inputs in the order: height, width, string. Output as a 2D list of characters.
Uses 8 as border, but could be any digit.

-1 byte thanks to @Grimy.

Try it online or verify all test cases. (TIO contains }}J» in the footer to pretty-print the result; feel free to remove it to see the actual output 2D list of characters instead.)

Explanation:

*               # Multiply the (implicit) width and height inputs
 j              # Pad the (implicit) input-string with up to that amount of leading spaces,
                # so the total string-length is equal to that value
  .r            # Shuffle the characters in the string
    S           # Convert the string to a list of characters
                # (edge-case for the zip below with strings of size 1 with 1x1 dimensions)
     ²          # Push the width input again
      ô         # Split the list of characters into parts of that size
       2F       # Loop 2 times:
         ø      #  Zip/transpose the 2D list; swapping rows/columns
          ε     #  Inner map over each line:
           8.ø  #   And surround this line-list with a leading/trailing "8"
                # (after the loop, the result is output implicitly)

Jelly, 16 bytes

P⁶ẋaẊs⁸ṪṾ€«”~ZƊ⁺

A dyadic Link accepting a list of integers, [M, N], on the left and a list of characters, S, on the right which yields a list of lists of characters, the lines. Uses the tilde character, ~, as the border.

Try it online!

All possible outputs have a non-zero chance of being yielded since we shuffle () a list of the characters of S along with the appropriate number of spaces.

The code Ṿ€«”~ZƊ⁺ saves the byte which I imagine would be required to join with newlines that full programs using an integer such as zero would need to employ (e.g. P⁶ẋaẊs⁸Ṫ;€0ZUƊ4¡Y or P⁶ẋaẊs⁸Ṫj@€Ø0Z$⁺Y). Maybe there's a way to save more...?

Bash + coreutils, 139 125 characters

r=`printf %$3s@@|tr \  @`
echo $r
printf %$[$2*$3]s $1|fold -1|shuf|tr -d \\n|fold -$3|paste -d@ <(:) - <(:)|head -$2
echo $r

Sample run:

bash-5.0$ bash soup.sh HELLO 4 11
@@@@@@@@@@@@@
@  H        @
@      OE   @
@    L      @
@          L@
@@@@@@@@@@@@@

Try it online!

Bash + coreutils + boxes, 97 characters

printf %$[$2*$3]s $1|fold -1|shuf|tr -d \\n|fold -$3|boxes -dsimple -s$[$3+2]x$[$2+2] -pa0 -itext

Sample run:

bash-5.0$ set -- HELLO 4 11

bash-5.0$ printf %$[$2*$3]s $1|fold -1|shuf|tr -d \\n|fold -$3|boxes -dsimple -s$[$3+2]x$[$2+2] -pa0 -itext
*************
* O   L  E  *
*      H    *
*           *
*     L     *
*************

Try it online! (Partially, as boxes is not installed on TIO.)

JavaScript (ES7), 125 bytes

Returns a string. Uses 0 as the frame character.

(s,h,w)=>(a=[...s.padEnd(w++*h++)].sort(_=>Math.random()-.5),g=x=>y+~h?(x%w&&y%h&&a.pop())+[`
`[x-w]]+g(x<w?x+1:!++y):a)(y=0)

Try it online!

Commented

(s, h, w) => (               // s = string; h = height; w = width
  a =                        // build an array a[] consisting of:
    [...s.padEnd(w++ * h++)] //   all original characters in s padded with spaces for a
    .sort(_ =>               //   total length of w * h, in a random order
      Math.random() - .5     //   (this is not guaranteed to be uniform, but it is not
    ),                       //   required to be)
  g = x =>                   // g is a recursive function taking x:
    y + ~h ?                 //   if we haven't reached the end of the grid:
      ( x % w &&             //     if we're not located on a vertical border
        y % h &&             //     nor on a horizontal border,
        a.pop()              //     extract the last character from a[]
      ) +                    //     (otherwise, append '0')
      [`\n`[x - w]] +        //     if we've reached the end of the row, append a linefeed
      g(                     //     append the result of a recursive call:
        x < w ? x + 1 : !++y //       using either (x+1, y) or (0, y+1)
      )                      //     end of recursive call
    :                        //   else (end of grid):
      a                      //     a[] is now empty and can be used as an empty string
)(y = 0)                     // initial call to g with x = y = 0

Charcoal, 27 bytes

NθNη↖B⁺²θ⁺²η#FS«W℅KKJ‽θ‽ηPι

Try it online! Link is to verbose version of code. Takes input in the order width, height, string. Explanation:

NθNη

Input the width and height.

↖B⁺²θ⁺²η#

Frame the bowl.

FS«

Loop over the characters in the string.

W℅KKJ‽θ‽η

Jump to a random position in the bowl until an empty spot is found.

Pι

Print the current character without moving the cursor.