[Question]
  [
*(Essentially the inverse of [Find the needle in the haystack](https://codegolf.stackexchange.com/q/179351/42963))*
Given two tuples, `(w, h)` and `(x, y)`, generate a haystack composed of a single random [printable ASCII character](https://codegolf.meta.stackexchange.com/a/5869/42963) of `w` width and `h` height with a needle made of a different random printable ASCII character at `(x, y)` when measured from the upper-left.
For example, when given `(5,4)` for the width and height, and `(3,1)` (zero-indexed) for the location of the needle, a possible haystack could be the following:
```
#####
###N#
#####
#####
```
Another possibility could be
```
*****
***$*
*****
*****
```
among hundreds of others.
### Rules and Clarifications
* Input and output can be given by [any convenient method](http://meta.codegolf.stackexchange.com/q/2447/42963). This means you can take input as a list of list of integers, as a single string, as two integers via command-line and a tuple via function argument, etc.
* You can print the result to STDOUT or return it as a function result.
* Either a full program or a function are acceptable.
* You can choose whether the `(x, y)` tuple is zero-indexed or one-indexed, but please specify in your solution which you're using.
* You do *not* get to pick which characters to use. That's part of the challenge - randomly selecting the characters.
* Every possible output for a given input must have a non-zero chance of appearing, but the randomness doesn't need to be uniform.
* The haystack is guaranteed to be at least 2x2 in size, so it's unambiguous which is the needle and which is the hay.
* There is only ever one needle, and it's only ever one character in size, and it's guaranteed to be within the boundaries of the haystack.
* [Standard loopholes](http://meta.codegolf.stackexchange.com/q/1061/42963) are forbidden.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so all usual golfing rules apply, and the shortest code (in bytes) wins.
  
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~122 120 106~~ 103 bytes
Recursively builds the output character by character. The coordinates are 0-indexed.
```
(w,h,x,y)=>(s=new Date%9023,g=X=>Y<h?Buffer([X-w?(x-X|y-Y?s+1:s%96)%95+32:13])+g(X<w?X+1:!++Y):'')(Y=0)
```
[Try it online!](https://tio.run/##DcndCoIwGADQV6kL8fvYFv5koDgH0UNsRBdimxbiwllT6N1X5/Y820/ruvnxWthk7zoYHsDTga50Q96A45P2u0u76KhMspz2XPJG1YM4v43RM1wl8wJWJr8bU8KRtHJRecKoLEieVWl@Q9KDrL2Q/9oTorCKYwTFEwydnZwd9WG0PRgo6JHmNEUMPw "JavaScript (Node.js) – Try It Online")
## How?
### Problem
To generate the haystack and the needle, we could either:
* generate a random haystack and process some loop to generate a random needle until it's different from the haystack
* shuffle the whole range of printable characters and pick the first 2 of them
Unfortunately, both approaches are rather lengthy in JS.
### Solution
We use instead a method that guarantees to generate 2 distinct characters with a single random number and without any loop.
We pick a random seed \$s\$ in \$[0..9022]\$ and define the haystack \$h\$ and needle \$n\$ as:
$$\begin{align}&h=(s+1)\bmod 95\\
&n=(s\bmod 96)\bmod 95\end{align}$$
(we then need to add \$32\$ to turn them into printable ASCII codes)
Basically, \$h\$ follows the pattern:
$$1,2,3,...,94,0,1,2,3,...$$
while \$n\$ follows the pattern:
$$0,1,2,3,...,94,\color{red}0,0,1,2,3,...$$
The sequences are progressively shifted relative to each other because of the extra \$0\$ in the needle pattern.
[This code](https://tio.run/##TY7BTgMhFEX3fMVNEwM4SmprTaajcdFP6FJdkIHp0Eyh4WGbaPz28ZG4cAWcx7n3He3FUp/DudzH5Pw8ky94QfRX7H3phBhSVsRk2YHwjHa5WvOtaTS@BTDyhMcNHjRu0G46ZpEZ1dfTH2IWBsVfOVejjDldsQjxYqfgcLYhL6rGxcY6p/Ylh3gwQ06n3Wjzjrdit8F6dcfR9dS6Ez@iT5HS5M2UDqq6FL58rWg3uEX7iFdI@ux7TySxhRxsmLyTrP4X5XuUnPlmjOGMD3NMISoJyRXz/As) shows that it does eventually lead to all possible pairs \$(h,n)\$ with \$h\neq n\$ (there are \$95\times 94=8930\$ of them).
And because we need only one random number, we can afford to use the current timestamp in milliseconds as our entropy source with `new Date%9023` instead of the longer `Math.random()*9023`.
## Commented
```
(w, h, x, y) => (      // w = width, h = height, (x, y) = coordinates
  s = new Date % 9023, // s = random seed in [0..9022]
  g = X =>             // g = recursive function taking X
    Y < h ?            //   if we've not reached the end of the grid:
      Buffer([         //     append the next character:
        X - w ?        //       if we haven't reached the end of the line:
          ( x - X |    //         if this is not the position of the needle:
            y - Y ?    //
              s + 1    //           append the haystack character
            :          //         else:
              s % 96   //           append the needle character
          ) % 95 + 32  //
        :              //       else:
          13           //         append a linefeed
      ]) +             //
      g(X < w ? X + 1  //     append the result of a recursive call
              : !++Y)  //     with either (X+1, Y) or (0, Y+1)
    :                  //   else:
      ''               //     stop recursion
)(Y = 0)               // initial call to g with X = Y = 0
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~14~~ 13 bytes
```
p/⁼€ịØṖẊ¤s⁸Ḣ¤
```
[Try it online!](https://tio.run/##y0rNyan8/79A/1HjnkdNax7u7j484@HOaQ93dR1aUvyoccfDHYsOLfl/eLnSoa2RQPmsRw1zDm07tO1Rw9z//6OjTXUUzGN1FEC0KYi21FEwio0FShjqKBiDBIC0IZQGSgAA "Jelly – Try It Online")
-1 byte thanks to [Unrelated String](https://codegolf.stackexchange.com/users/85334/unrelated-string)
Returns a list of lines. The last line in the Footer section displays it as a square. Takes input as `[w, h]` and `[y, x]`, where `x` and `y` are 0-indexed.
## How it works
```
p/⁼€ịØṖẊ¤s⁸Ḣ¤ - Main link. Takes [w, h] on the left and [y, x] on the right
p/            - Reduce Cartesian product over the arguments.
                This yields a list of co-ordinates from (1, 1) to (h, w)
   €          - Over each list:
  ⁼           -   Is it equal to [x, y]?
              - This yields a list where every element except 1 is 0
        ¤     - Create a nilad:
     ØṖ       -   Printable ASCII characters
       Ẋ      -   Shuffled
    ị         - Index into the shuffled characters, replacing 1 with the first char in the shuffled list and 0 with the last. Therefore, the two characters will be distinct
            ¤ - Create a nilad:
          ⁸   -   Yield [w, h]
           Ḣ  -   Extract w
        s     - Split the list of characters into rows of length w
              - Implicitly output
```
[Answer]
# Excel VBA, ~~128~~ ~~118~~ ~~106~~ ~~94~~ 96 bytes
*-12 bytes inspired by agtoever*  
*-12 bytes thanks to Taylor Scott, VBA extraordinaire*  
*+2 bytes and -1 bug thanks to Taylor's unnecessary, intimidating, and [much appreciated work](https://pastebin.com/ftBs4Dn3)*
```
Sub n(w,h,x,y)
a=94*Rnd
[A1].Resize(h,w)=Chr(a+32)
Cells(y,x)=Chr(32+(a+93*Rnd+1)Mod 95)
End Sub
```
Input and output are one-indexed. Output is to the top left cell range of the active sheet.
`a=94*Rnd+32`: `(126-32)*Rnd+32` gives a number between 32 and 126, inclusive.
`Range(~)=Chr(a)`: Fills all the cells with the ASCII character.
`Cells(y,x)=Chr(~)`: Fills just that one cell with the other ASCII character.
`(a+62*Rnd)Mod 95+32`: `{(a+[94-32]*Rnd) Mod (126-32+1)}+32` gives a random number between 32 and 126 inclusive that is *not* the same as `a`. (I can't prove that mathematically but 100 million tests showed no collisions.)
Example output:
[![enter image description here](https://i.stack.imgur.com/FrCfb.png)](https://i.stack.imgur.com/FrCfb.png)
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell) v6, ~~102~~ 96 bytes
```
param($x,$y,$a,$b)$j,$k=' '..'~'|random -C 2
-join((,$j*$x+++'
')*$y|%{"$_$k"[$i++-eq$b*$x+$a]})
```
[Try it online!](https://tio.run/##HclLDoIwGEXheVfxh1wt0EIIjyEjl2GMKREib6wDIYBbr5WcyZecafyU@v0su86gylczKa16F7PEIqEkCg@NRJtz4mHIv3zTaniMPQUXilnQjPXguhKNj1kIwRn3fCzbaXVwR@tcUQsRlC8U/w912z2zM3ZGRbEtouhwShkllB7ObPaZHw "PowerShell – Try It Online")
This answer, thanks to mazzy, uses the character range feature added in v6 to save several bytes over the more flexible answer below. 
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~119~~..~~105~~ 102 bytes
-16 bytes thanks to mazzy  
-1 byte thanks to AdmBorkBork
```
param($x,$y,$a,$b)$j,$k=32..126|random -C 2
-join((,$j*$x+++'
')*$y|%{[char]($_,$k)[$i++-eq$b*$x+$a]})
```
[Try it online!](https://tio.run/##HYtLDoIwAAX3PUUXT6G0ECzgjpXHIMQUhQDysy6EAGevlcxmkjdvGr@l/tRl1xlU6WompVXvYhZYBJRAwdAKvNJIBsFFXjethufYU/9GJfHbsRlcV6D1MHPOHeIwD8t2WrNHrXTu4m6vLEPDuV@@UfwzqHxnZifkjIpKS0jDw2Oa0IjGhycWu5kf "PowerShell – Try It Online")
Gets two ints in the range of [32,126]. We first make a 1D array out of the first value, appending a new line after every `$x`chars. Doing this means we also have to increment `$x` so that our index math isn't affected. We then iterate through the array, and either yield a char-ified first value or the needle. Finally, we join all the yielded values and output it.
Answer is 0-indexed by the way.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~134~~ ~~133~~ ~~120~~ ~~112~~ 111 bytes
```
lambda w,h,x,y:zip(*[iter(chr(r[x+y*w==i]+32)for i in range(w*h))]*w)
from random import*
r=sample(range(95),2)
```
[Try it online!](https://tio.run/##JYpLDoIwFAD3nKI7@kpjIshCk54EWFSh9hn6ybNJwctXDauZTCbuyQbfFqPGsmp3nzXL0spN7rcPRi4GTAvxhyVOw9bsIiuFU9O1YAIxZOgZaf9ceBYWYBIZKkPB/eP8A7oYKImK1Fu7uC78mK89yBZKJPSJ1aOvT6@AnjsdeX24NLyXF9nJMwCULw "Python 2 – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 11 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
QŒṬƤSḂịØṖẊ¤
```
A monadic Link accepting a list of lists, `[[height, width], [row, column]]` (1-indexed), which yields a list of lists of characters.
**[Try it online!](https://tio.run/##ATMAzP9qZWxsef//UcWS4bmsxqRT4biC4buLw5jhuZbhuorCpP/Dh1n//1tbNSw3XSxbMywyXV0 "Jelly – Try It Online")** (The footer calls the link and joins with newlines.)
### How?
```
QŒṬƤSḂịØṖẊ¤ - Link: [[h, w], [r, c]]
Q           - de-duplicate (i.e. [[h, w]] if [r, c] == [h, w] else [[h, w], [r, c]])
   Ƥ        - for prefixes (of that list):
 ŒṬ         -   get a 2D array with ones at the coordinates specified
    S       - sum (vectorises) (giving us an h*w matrix with zeros almost everywhere,
                                except a 1 at our needle and, if [h, w] != [r,c], a 2 at
                                the bottom-right)
     Ḃ      - modulo two (replacing the 2 with a zero if it exists)
          ¤ - nilad followed by link(s) as a nilad:
       ØṖ   -   list of printable characters
         Ẋ  -   shuffled
      ị     - (left) index into (right) (vectorises)
```
[Answer]
# Dyalog APL, ~~24~~ ~~23~~ 21 bytes
```
⎕UCS(32+2?95)[⎕∘≡¨⍳⎕]
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qp/@jtgkGXI862hXSQPxQ52ANYyNtI3tLU81oIP9Rx4xHnQsPrXjUuxnIi/0PVPg/jctEwZTLUMEYAA "APL (Dyalog Unicode) – Try It Online") 0-indexed.
-1 thanks to ngn, -2 thanks to Adám suggesting to use a different I/O format.
[Answer]
# [Python 2](https://docs.python.org/2/), 133 bytes
```
from random import*
r=range
def f(h,w,x,y):
 p=sample(r(32,127),2)
 for i in r(h):
	print ''.join(chr(p[i==y and j==x])for j in r(w))
```
[Try it online!](https://tio.run/##JY3BCsIwEETP5iv21l1ZxKaIIORLxEOxjUmxSVgDbb4@RoSBgeE9JpXsYtC1WokryBimVn5NUfJRiWnDa1bTbMGi4413LnRTkMxnXNN7RsFBc6@vxJoU2CjgwQcQdA07JPEhQ9edlugDPp1guntjCrQbWIzZH/RTlr@yEVWL/ZlbLjxQ/QI "Python 2 – Try It Online")
-12 thanks to Value Ink for suggesting using a loop comprehension. -2 thanks to Unrelated String for suggesting python 2 instead of python 3 to get rid of parenthesis in the print function!
[Answer]
# [Python 2](https://docs.python.org/2/), 110 bytes
```
from random import*
w,h,x,y=input()
m,n=sample(map(chr,range(32,127)),2)
l=eval(`[[m]*w]*h`)
l[x][y]=n
print l
```
[Try it online!](https://tio.run/##DctBCsMgEEDRvafIUmU2MS1deRIRIq2tgo6DNU08vXX14cGn3kJBNca7lrxUh6@ZmKnUJtkJAS7oOiIdjQuWAfXXZUqeZ0f8GSrM4@P5pmBVDyFACZa0/7nEd2OylaeVYZ9mLmu61cioRmxLGuMON9hg/QM "Python 2 – Try It Online")
I copied [TFeld's solution](https://codegolf.stackexchange.com/a/194356/20260) and managed to golf a char using list assignment. The `eval()` trick is used to [make a mutable matrix](https://codegolf.stackexchange.com/a/51022/20260) to avoid the list mutation applying to every row.
**111 bytes**
```
lambda w,h,x,y:[[chr(r[x^i<1>y^j]+32)for i in R(w)]for j in R(h)]
from random import*
R=range
r=sample(R(95),2)
```
[Try it online!](https://tio.run/##JYhJDoIwFED3nKI7@vXHBJCFRjwEW4akCrVt6JAvCXD6imH1hrDNyrs8yqqNk7CvQbAFFa643ZvmrYhTs/b6kT233nTnIgfpiWmmHav5At2/zFEKukSSt4yEG3ZoGzzNp6Su9vEZE6q@woZp5DW/lYA5xEDazSxtXXoxXjtuReDp4Sh5iVcsMAOA@AM "Python 2 – Try It Online")
A smaller change that only tied. Calling the function multiple times always give the same random choices, which I hope is OK.
**109 bytes**
```
lambda w,h,x,y:[m*w]*y+[m*x+n+m*(w+~x)]+[m*w]*(h+~y)
from random import*
m,n=sample(map(chr,range(32,127)),2)
```
[Try it online!](https://tio.run/##JcqxDoMgEIDh3adwvINbxDZNmvgk1oFWKSQeEkqDLL46Nen0Df8fSrKbV9UMj7pqfs66zWRpp3IfWeRJFHm6Sy9ZQJbHjpP8B7DyKNiYuHEbtZ9PHIctJtEw@eGjOawLsA7wspHO471Ar6hTN0RSWEN0PrUGhPPhmwCxXulCPXU/ "Python 2 – Try It Online")
A shorter function making the list of lines via multiplication. Also generates the characters just once.
[Answer]
# [Perl 5](https://www.perl.org/), 86 bytes
```
($,,$b)=keys%{{map{chr,1}33..126}};$_=($,x$F[0].$/)x$F[1];s;(.*
){$F[3]}.{$F[2]}\K.;$b
```
[Try it online!](https://tio.run/##K0gtyjH9/19DRUdHJUnTNju1sli1ujo3saA6OaNIx7DW2FhPz9DIrLbWWiXeFqiqQsUt2iBWT0VfE8QyjLUuttbQ0@LSrAbyjGNr9UC0UWxtjLeetUrS//@mCiYKxgqG//ILSjLz84r/6/qa6hkY/tdNLAAA "Perl 5 – Try It Online")
[Answer]
# [Julia 1.0](http://julialang.org/), 71 bytes
```
f(w,h,x,y)=(z=unique(rand(' ':'~',9));g=fill(z[1],(h,w));g[y,x]=z[2];g)
```
`x,y` are one indexed. Returns a 2d array of characters, I spent the extra bytes to make sure the default printing has the right orientation (`'` for transpose no longer works because they stick to a strict mathematical meaning). Getting two distinct randoms is surprisingly verbose, this has about a 1e-18 chance of failing to do so, one more byte could make it 1e-196.
[Try it online!](https://tio.run/##FchLCoAgEADQq7RzBmaj1KLCk4gLwSxDog@SuujqVrzdW2PwhqdaHdy0UKKMEoqMmz/iBKfZLLCGDexh1COOs3Q@BCiKa4KF7r9UpqRlUUKPM1brrz2YDA46aj8Csb4 "Julia 1.0 – Try It Online")
[Answer]
# [J](http://jsoftware.com/), 21 bytes
```
u:@(32+2?95){~#.=i.@[
```
[Try it online!](https://tio.run/##y/pvqWhlGGumaGWprs6lpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/S60cNIyNtI3sLU01q@uU9Wwz9Ryi/2tycaUmZ@QrGANhmoKhgiGECzQJTBsaKBgZACWA0v8B "J – Try It Online")
Inspired by dzaima's APL answer. 
Thanks to Galen and Adam for the randomize fix.
[Answer]
# [Octave](https://www.gnu.org/software/octave/) with Statistics Package, 45 bytes
```
@(x)randsample(' ':'~',2)(sparse(x{:},0:1)+1)
```
The input is a cell array of 2 numeric vectors of length 2: `{[h y] [w x]}`, with `x`,`y` 1-based.
[Try it online!](https://tio.run/##y08uSSxL/Z9mq6en999Bo0KzKDEvpTgxtyAnVUNdQd1KvU5dx0hTo7ggsag4VaOi2qpWx8DKUFPbUPN/mkZ1tJmCUaxCtLmCcWyt5n8A)
[Answer]
# [Ruby](https://www.ruby-lang.org/), 62 bytes
```
->w,h,x,y{a,b=[*?\s..?~].sample 2;r=[a*w]*h*$/;r[y*-~w+x]=b;r}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf165cJ0OnQqeyOlEnyTZayz6mWE/Pvi5WrzgxtyAnVcHIusg2OlGrPFYrQ0tF37ooulJLt65cuyLWNsm6qPZ/QWlJsUJatKmOMRAaxv4HAA "Ruby – Try It Online")
[Answer]
# Pyth, 56 50 48 41 bytes
```
JEKE=TE=Yrd\~=Zh.SYVJVQ ?qHK?qNTpeYpZpZ)d
```
I'm somewhat struggling to golf Pyth, but posting this to force myself to learn.
Edit 1: Golfed it down a bit, and made it an actual solution -6 bytes
Edit 2: Looked at it after posting it and realized a few bytes save by ignoring space. -2 bytes
Edit 3: Today I learned about character ranges, which shortens things significantly. -7 bytes
[Answer]
# Excel + CSV, 104 bytes
```
,,,,=94*RAND()+32,=REPLACE(REPT(REPT(CHAR(E1),A1)&"
",B1),D1*A1+D1+C1+1,1,CHAR(MOD(E1+62*RAND(),95)+32))
```
Save as CSV, add input as `A1` - `D1`.
Output will be in `F1`.
Using @Engineer Toast's solutoin for generating 2 unique characters.
Needle position is 0-indexed, which is curious, as Excel itself if 1-indexed.
Changing to 1-indexed input adds 3 bytes (`(D2-1)*(A2+1)+C2` instead of `D1*A1+D1+C1+1`).
[Answer]
# [SOGL](https://github.com/dzaima/SOGLOnline), 18 [bytes](https://github.com/dzaima/SOGL/blob/master/chartable.md)
```
 ~Δψ] ~Δψ⁴⁴=}A*∙až
```
[Try it here!](https://dzaima.github.io/SOGLOnline/?code=JTIwJTdFJXUwMzk0JXUwM0M4JTVEJTIwJTdFJXUwMzk0JXUwM0M4JXUyMDc0JXUyMDc0JTNEJTdEQSoldTIyMTlhJXUwMTdF,inputs=NSUwQTQlMEEyJTBBNA__,v=0.12) 1-indexed.
[Answer]
# [Add++](https://github.com/cairdcoinheringaahing/AddPlusPlus), 65 bytes
```
D,g,?!,
L,c95Rdb[€BXd¦=BFV#@G+b[95€Ω%31€+€CA€RbU‽g$€=$€Ω:A$pbUp$T
```
[Try it online!](https://tio.run/##S0xJKSj4/99FJ13HXlGHy0cn2dI0KCUp@lHTGqeIlEPLbJ3cwpQd3LWToi1NgWLnVqoaGwJpbSB2dgQSQUmhjxr2pqsAmbYqYAVWjioFSaEFKiH/VXISc5NSEhUM7ezt7Lm4XHSy8jPzdLg4HeqAhBdIoKAotaQkM60SJGgFJIAGVIMU1SaF5nFxqcCk7Sr@/482VDCM/R9trGAcCwA "Add++ – Try It Online")
Takes input as `[y x]` and `[w h]`. `x` and `y` are 1-indexed. Outputs a list of lines.
Added 17 bytes to make sure the needle is distinct.
## How it works
We start by generating two ranges from \$1\$ to \$95\$ inclusive, before choosing a random value from each. If the two values are equal, we add one to the one of them. We then add \$31\$ to each, yielding two characters ord points in the ASCII range. Finally, we convert them to characters.
Next, we generate a list of all co-ordinates in the grid, and compare them with `[y x]`. If the co-ordinates match, we yield \$1\$, otherwise \$0\$. Next, we index each of these \$1\$s and \$0\$s into the two characters, creating a grid of \$0\$ characters with 1 \$1\$ character in it at `[y x]`. Finally, we retrieve the width and split the grid into that many rows.
[Answer]
# [PHP](https://php.net/), ~~113~~ 109 bytes
```
for([,$w,$h,$x,$y]=$argv,$a=range(' ','~'),shuffle($a);$i++<$h;print"
")for(;$$i++<$w;)echo$a[$i-$y||$$i-$x];
```
[Try it online!](https://tio.run/##JYzLCoMwEEX3/YoiF5LgdFPaVZR@iLgIkjiBoiF9qCD99VEpF86Bs7iJk1SPtDOMWTeEicCEmbC0NVzuvwRXZzf0XquzIvVThl78CeHpNZyxiGVZgW3KcXgXp8IcPxb/PFnjOx7hGsQLlnXF4bm1InKX277rBg "PHP – Try It Online")
Pass inputs as command arguments (`$argv`) in order of `w`, `h`, `x` and `y`. The `x` and `y` are one-indexed.
```
for(
  [,$w,$h,$x,$y]=$argv, // put inputs from $argv array into 4 short named variables
  $a=range(' ','~'),    // create $a array containing printable ASCII characters
  shuffle($a);          // shuffle the array
  $i++<$h;              // loop $h times (rows)
  print"\n"             // print a newline after every row
)
  for(;$$i++<$w;) // loop $w times (columns)
 echo // print
 $a[ // a character from $a (1st char for needle and 2nd for heystack)
 $i-$y || // when row and y don't match
 $$i-$x          //   or when col and x don't match (will be false only for needle)
      ];
```
[Answer]
# [C# (Visual C# Interactive Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), 145 bytes
```
(a,b,c,d)=>{int l=0;for(var j=Enumerable.Range(32,95).OrderBy(k=>Guid.NewGuid()).ToList();l<a*b;)Write((char)j[l==c*a+d?1:0]+(++l%a<1?"\n":""));}
```
[Try it online!](https://tio.run/##NYhBC4IwGEDv/YohBN@XS7LwkHNGQXSJggg6VIc5Z83WhGlFRL/d6tDhvQdP1n1Z63YqG11Zkmjb0D/kq7TgLQiaUUlz5Onru4jhA1ZUDu7CkZLP7e2qnMiMCjbCnhSMhnQcYbB2uXKzJ1x4urjpPFipx6@AGGyrpa4bQGYS0csY7pxuFIA8C4fl3nAue8LPJ2E8OPrg@6YrknDiHawXex4ie7esUxCI6IiGdIis/QA "C# (Visual C# Interactive Compiler) – Try It Online")
[Answer]
# [Icon](https://github.com/gtownsend/icon), 119 bytes
```
procedure f(w,h,x,y)
until m:=char(32+?95)&n:=char(32+?95)&m~==n
t:=[];1to h&put(t,repl(m,w))&\z
t[y,x]:=n
return t
end
```
[Try it online!](https://tio.run/##Xc7BTsMwDAbge57CXKpE@MJgQgRFvMDeYOxQpZ4a0TiVcek6BK8@SjcQwrf/s2U7xcKnLvELSM1NyadeSqRmEIK9HbHFA07ODKypg@xDbGuxt6vrp4e1q/hfzp8hsFEftrvHGy3QVv2gVlGo72zG0bnq@Wh0O@Fh5@dJIR2EQQ1x8@durhNbZ2Cu80/pSJe88WFv7xHWCHcIqzPSG8kE4sPVBpoC7wv@epxdvn2UpPRqo/vpL3BZ/LH88AU "Icon – Try It Online")
`x`and `y`are 1-indexed
[Answer]
# [Python 3](https://docs.python.org/3/), 137 bytes
```
lambda w,h,x,y,c=chr:"\n".join([c(a)*w,c(a)*x+c(n)+c(a)*(w-x-1)][r==y]for r in range(h));a,n=__import__("random").sample(range(32,127),2)
```
[Try it online!](https://tio.run/##JYrtCoIwFEBfZezXvXUV1CIo9iQqY01tC/fBEtSnX2G/zoFz4r6Y4Js8iS7Pyj0HxVYytNFOWmiT7rzzvHwH66HVoPC00oHtrMHj@XBYi62osG@TEHs/hcQSs54l5V8jGMSHIi@ktC6GtEgJ/FeG4DiWH@XiPML/bGqq6htSjTkm6xeY4EoXaqhCzF8 "Python 3 – Try It Online")
Uses zero-based indexing for the needle position.
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 57 bytes
```
{(' '..'~').pick(2)[0 xx$^a*$^b-1,1;*].pick(*).rotor($a)}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/WkNdQV1PT71OXVOvIDM5W8NIM9pAoaJCJS5RSyUuSddQx9BaKxYipaWpV5Rfkl@koZKoWftfrzixUiEtv0ghTcNUx0TzPwA "Perl 6 – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 17 bytes
```
ＵＯＮＮ‽γＪＮＮ‽Φγ¬⁼ιＫＫ
```
[Try it online!](https://tio.run/##S85ILErOT8z5/98/KSc/L13DM6@gtMSvNDcptUhDU0cBjRuUmJeSn6uRrqlpzeVVmlsQko9XA1BVQFFmXokGVJ9bZk4JUDxdR8Evv0TDtbA0MadYI1NHISA1NRuoGgSs//83VTBRMFYw/K9blgMA "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
ＵＯＮＮ‽γ
```
Draw a rectangle of the given width and height using a random printable ASCII character.
```
ＪＮＮ
```
Jump to the 0-indexed position of the needle.
```
‽Φγ¬⁼ιＫＫ
```
Print a random printable ASCII character, but filtering out the character under the cursor.
[Answer]
# [Red](http://www.red-lang.org), 156 bytes
```
func[w h x y][c: :collect p: take/part random c[repeat i 95[keep to sp 32 + i]]2
c[repeat i h[keep/only c[repeat j w[keep pick p i * w + j
=(y * w + x)]]]]]
```
[Try it online!](https://tio.run/##Tc69CsMgFIbh3av4xv4MgaQtNNCb6CoOokdikqoYi8nV27QptGf6hveBE0mXO2kuWJRO@0c1EWk4n5lpi3k6xTM6zFgEVy1a5ceRVEJokeRAVZAxYZNQPFIgmWBxPfOBKCB5TAFNjSOsEDX7S7pPUXk3Lj/ZI28wWDUgrNkBecU9u@2W75734n3F@EhSdUgwuOCMExoeonXrP9R765BEeQE "Red – Try It Online")
`x` and `y` are 1-indexed. Returns a list of strings.
## Readable:
```
f: func [w h x y] [
    c: take/part random collect [
        repeat i 95 [
            keep to sp 32 + i
        ]
    ] 2
    collect[
        repeat i h [
            keep/only collect [
                repeat j w [
                    keep pick c i * w + j = (y * w + x)
                ]
            ]
        ]
    ]
]
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~144~~ ~~132~~ 131 bytes
```
from random import*
i,j,k,l=input()
n,h=sample(range(32,127),2)
for x in range(j):a=[chr(n)]*i;a[k]=chr((n,h)[x==l]);print`a`[2::5]
```
[Try it online!](https://tio.run/##JYzLCsMgEEX3@QqXTphNTEPB4JeIEGmTah6jGAvp11tLV5fDOdz4yS6QKGVJ4WDJ0rOOP2JIuW08rrjhrjzFd@bQEDp12iPuM6/la@a9wE7cAQU0S0jsYp7Y36wgrdIPlziBaf1o9WbUD3k9AX0ptRsYY/KUJztpIeVgShnwhj12Xw "Python 2 – Try It Online")
Corrected the problem with the guaranteed uniqueness of the characters and saved 12 bytes along the way.
[Answer]
# [Forth (gforth)](http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/), 140 bytes
```
include random.fs
: x 95 random 32 + ;
: f x -rot 0 do cr dup 0 do 2over i j d= >r over r> if begin x 2dup - until nip then emit loop loop ;
```
[Try it online!](https://tio.run/##LU1bDoMwDPvvKbzviYnH0B5o3GWjKXSCFoUy7fZdCpOjxHYS2XgOQ9abNGK0rhtXTeCn0346mUXd8cWt/huoShzRiGnEztgH5NAeHUOv885L/yGGxRv6gZaxSW5hDV7UWyePZTrOsLpgRzg7IwzkQJMNGL2f99bEgZiwEGkcVAFBnsooSVO5hFWCpFQiZ8EmCtmUgk3UuOCKG0z8AQ "Forth (gforth) – Try It Online")
0-indexed
### Code Explanation
```
include random.fs        \ import the random library
\ Generate a random number in range 32 to 126 inclusive
: x                      \ start a new word definition
  95 random              \ generate a random number between 0 and 94
  32 +                   \ add 32
;                        \ end word definition
: f                      \ start a new word definition
  x -rot                 \ generate a random number for the haystack, then move it
  0 do                   \ loop from 0 to h-1 (inclusive)
    cr                   \ output a newline
    dup 0 do             \ loop from 0 to w-1 (inclusive)
      2over i j d=       \ check if this is the needle square
      >r over r>         \ hide result, grab a copy of the haystack char, then grab result back
      if                 \ if it is a needle
        begin            \ begin indefinite loop
          x 2dup -       \ generate a new random number and compare to haystack char
        until            \ only end loop when values differ
        nip              \ drop haystack char
      then               \ end if block
      emit               \ output ascii char for value on top of stack
    loop                 \ end row loop
  loop                   \ end column loop
;                        \ end word definition
```
[Answer]
# [C (clang)](http://clang.llvm.org/), 87 bytes
```
f(w,h,x,y){x+=y*w;h*=++w;for(y=time(0)%9023;h--;)putchar(h%w?(x--?y+1:y%96)%95+32:10);}
```
[Try it online!](https://tio.run/##DcpBCoQgFADQvadwI3xTwYqJqY90logahckGMUyiszu99ZvV/J38p5QVkrTylJlfpzC5SmgrI0TCdQ@QTXTbApqzXjctWqWQ/4442ymAZWmEU6kxi3rIrO@e9BJtM9Sa412cj3SbnAdOL7LCW3aylQ1HQh9hiUfwVCO5yx8 "C (clang) – Try It Online")
Stealing from [@Arnauld answer](https://codegolf.stackexchange.com/a/194361/84844)
[Answer]
# [K (oK)](https://github.com/JohnEarnest/ok), ~~27~~ 23 bytes
-4 bytes thanks to ngn!
```
{`c$(32+-2?95)x#&/y=!x}
```
[Try it online!](https://tio.run/##y9bNz/7/P82qOiFZRcPYSFvXyN7SVLNCWU2/0laxovZ/WrSZgrm1iYJx7H8A "K (oK) – Try It Online")
0-indexed `x` and `y`
Similar to Dzaima's APL and Jonah's J solutions.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 15 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
žQΩIP×žQΩIPǝ¹нô
```
Coordinates are 1-indexed. Outputs as a list of lines.
[Try it online](https://tio.run/##yy9OTMpM/f//6L7Acys9Aw5PhzKOzz2088Lew1v@H9r9P9pUxySWK9pExygWAA) (`»` in the footer joins the list of strings by newlines to pretty-print, feel free to remove it to see the actual output).
**Explanation:**
```
žQ              # Push all printable ASCII characters
  Ω             # Pop and push a random character
   IP           # Push the first input (rectangle-size), and take its product
     ×          # Repeat the random character that many times as string
      žQΩ       # Push a random character again
         IP     # Push the second input (1-based coordinate), and take its product as well
           ǝ    # Insert the random character at this (0-based) index into the string
            ¹н  # Push the first input again, and only leave its first value (width)
              ô # Split the string into parts of that size
                # (after which the resulting list of strings it output implicitly as result)
```
]