[Question]
  [
><>, or Fish, is a two-dimensional esoteric programming language where the instruction pointer (IP) toroidally moves around the codebox, wrapping when it hits an edge.
><> has four basic movement instructions - `<`, `>`, `^`, and `v`, which respectively mean to change the IP's direction to left, right, up and down. It also has the termination instruction `;`, which halts the program.
For any program, some characters may never have the IP move through them. For example, with the program
```
> v
   
; <
```
The program starts at the `>`, changes direction at the `v` and `<`, and halts at the `;`. The squares marked with `#` are never passed through:
```
> v
## 
; <
```
So if we wanted to obfuscate this program and make it harder to read, we could replace these with any printable ASCII characters and the program would still do exactly the same thing!
In this challenge, we will be working with a very limited set of <>< - Just the four movement instructions, spaces, the terminator (`;`) and newlines.
Your challenge is to, when given a program in this subset of ><> as input, output the same program with all characters that will never be passed through replaced with random printable ASCII characters - 0x20 to 0x7e. For each position, each printable ASCII character should have an equal chance of being printed, including ><> instructions and spaces.
Note that this means replacing *all* characters that are never passed through, not just spaces.
You can assume that the ><> program will always halt, and will always be a rectangle.
You may take input as a list of lines, a matrix of characters, ascii-art, etc.
The program will only ever contain said instructions.
The IP starts at 0,0, moving left to right.
# Scoring
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest wins!
# Testcases
In these testcases, `#` represent characters that should be replaced with random characters.
```
v; 
> v
 ^< =>
v;#
> v
#^<
; v
  v
<<< =>
;##
###
###
> v
 ; 
; < => 
> v
## 
; <
>  v
v  >
> ^ 
  >; =>
>  v
v# >
> ^#
##>;
>v> ^
v<^v<
> v>; =>
>v> ^
v<###
> v#;
```
  
[Answer]
# ><>, 555 bytes
```
ffv   $@$f$+1~<
 $>i:1+?!v:a=?^}$:@@:@{@p$1+
@@:@(?$&$>~&l1=?v:
^}f-&0~~~~&<    >&1+$ff0       v
:@@=?v:@@=?^:@@=?v:@@=?v:@@=?vv>}$:@@:@{@g::0$-:@(?$~&">v<;^"&  
v/~~&</     2~~~&/ 1~~&/  0~&/>~" "&>}$:@@:@{@0&-@p:&1$3=?v&:&1=?v$@&:&0=?+&:&2=?-$
v>~~~3>          >     >      !^  !0^!   <                >0$-   >+
>  :e=?v>:{:}=?v$>     :e=?v>:{{:@}}=?v$&^
^-1}:{~<^    f~< ^-1}}@:{{~<^       f~<
>$:{{:@}}=?v>$:@@:@4[1+r]g:0(?!v0$-o
^!}:{:$f+1~<^$oa;?=  >!   ]! o!0! 
r v >l7=?v0           >   ~l]0$>$~[r
$>x0^>@:@0~(@:@)@@+?!^^
p >1^^@"~ "<
}{2*+l1= >?^
```
[Try it online!](https://tio.run/##XVJRasMwDP3XKZQgTLcQaneDgZsovseooB9zNyi0dGAGIb56J6db203gJyGk92TL8ePz/XyOMSEiBYrUuNwBEn941wxV8tt@kIl8CD6M4UiugRIuBjLE2exdPyQPMsXW2KxmOiVCNq6hGC1eLIH2l8KCchf/YOKrws57S@0skE3NqVtLbRAhLQv3cqZbFZ0luhnRKnKusTY3FmvacPTG0ZOyGw3UUdDA9kOjbtUPLUFiJXpivBrfIVaix0qlYYf/jHXG4hrQYv@m7OxHPxWVS/dvbvRhmtNGQFo3@TF3Ugpi7rAkpqBFP7lLGphufXy50fOra06bnbcLXYlqH0Aq5fIUy7qEDtv10Os8ZdhNhYfKVggnTMj7F2Wx@PeOeb@xxJRfT0D8ZYVVwuaF4kMIunUROCI7kVBnrDuYxtVjo6tGHuR85nmjgDqz/hTkTh8S9CHW8A0 "><> – Try It Online")
Note that there is a trailing space on line 11 (after `o!0!`).
><> programs can only access a stack of stacks for data storage, which would be difficult to use as a 2d array. Thus, this modifies the program grid to use as a 2d array, storing the input & tracing the path through it.
Additionally, the only source of randomness in ><> is the `x` instruction, which sends the IP in one of 4 random directions. Printable ASCII has 95 (19 \* 5) characters, which is not divisible by numbers less than 5. Thus, to generate the random characters, it generates 7 random bits, joins them into a number from 0 to 128, and then checks if the number is within printable ASCII. If not, it discards it, generates a new random number, and repeats until it is.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~90~~ 55 bytes
```
ＷＳ⊞υιＰ⪫Ｅυ⭆ι‽γ¶≔¹ηＷ¬⁼;ψ«≔§§υⅉⅈψ≔∨⊕⌕>^<vψηη✳⊗⊖ηψＪ﹪ⅈＬθ﹪ⅉＬυ
```
[Try it online!](https://tio.run/##TY9BS8QwEIXPm18x9DSBePBcKSxUYReri3pwQRZqG5pAOum2SXURf3tNtnX1kmRm3nvfpFJlX9nSTNOH0kYCbqjz7tn1mhrkHHZ@UOgFaJ6ywhunuzBxuLWasCi7OJrFsdACnkqqbYsN51xA8kYJD8b1MOiG8FqACtUCerAOb4@@NAMmaSLgFCzwxVaLeO02VMvPyx1Ae4yhr@fzFIJ@pY992LrqZSvJyRrvNNWYZIebcU6N1Jm82p2Xz3UvK6ctYW79uwmWXP7ZFb/kb33bvVgsbO2NxQAWcC@pcQqPUbP09//6nsf/fk9TBjCyESBjGRyAhUfKpqvR/AA "Charcoal – Try It Online") Link is to verbose version of code. Takes input as a list of newline-terminated lines. Explanation:
```
ＷＳ⊞υι
```
Read the program.
```
Ｐ⪫Ｅυ⭆ι‽γ¶
```
Output a rectangle of random printable ASCII.
```
≔¹η
```
Start at the origin facing east.
```
Ｗ¬⁼;ψ«
```
Repeat until the end of the program is reached.
```
≔§§υⅉⅈψ
```
Get the current character of the program.
```
≔∨⊕⌕>^<vψηη
```
If the current character is a direction then update the direction variable.
```
✳⊗⊖ηψ
```
Replace the random character with the current character and update the position.
```
Ｊ﹪ⅈＬθ﹪ⅉＬυ
```
Wrap around the sides of the rectangle as necessary.
[Answer]
# [J](http://jsoftware.com/), 120 bytes
```
(([:u:32+94?@$~#@[)`[`]})~($#:,@i.@$);/@-.[:{."2]($@[|"1{.@](+,:])(]0,~((,-)=i.2),~{:){~' v>^<'i.({~<@{.))^:a:0 0,:0 1"_
```
[Try it online!](https://tio.run/##hY5BS8QwFITv@RVvu4XksemzrYvQl7QGBE@evJZ0d1lcrCCCaBCi@eu1da/CHmYOwzfDvEzNiit/s@JGSpGRPEHLIEFDCTyrILh7fLiflOr5k6/rTbO9dXlaux73/d7/YFL5mrUbyeVorlxBPUfKaq9y139nVSTn1UazR@VLnZTSBbYj1ahTZIxJQugGK0dSMVkXCXHgA5dQ6tmqbDeheD18vI9fLXlDu1o8HZ/f4ATncDlZimBAdBAEDFbgGZBFIf9DzYLNsvYi@rc4Lxu4jIYOBhHsEOxS68xcENMv "J – Try It Online")
It's late, and this one kind of got away from me, but, what the hell, looks like it works. I have some ideas to improve it tomorrow.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~253~~ 212 bytes
Takes input as a character matrix.
```
from random import*
def f(g):
 r=x=y=a=0;b=1;N=[[chr(randint(32,126))for _ in t]for t in g]
 while';'!=r:N[y][x]=r=g[y][x];a,b=[0,1,0,2,-1,a,-1,0,1,2,0,b][ord(r)%9%6::6];x=(x+b)%len(g[0]);y=(y+a)%len(g)
 return N
```
[Try it online!](https://tio.run/##NVBRjoMgEP3nFLMfjdCyjdqkyYp4hF7A2o2uaE0sGmCtnt4dbJeE4b03b2CGcXH3QZ/WtTHDA0ypazy6xzgYtye1aqChLUsIGDnLRZYyFJWMxEXm@c/dUO/vtKOnmEfxmbFmMPANnQZXeOg8bAsCz3vXq0AEH9Ikl3wp8rmQRrYvJEpeyTzkEQ95zD8jXvrgeYyxKvLB1NSw3dfunCTnQsySzoeK7XqlaZuHBROLpMuhfCsMm1Xu12i4rK9BwC6WEKessyA9OVqHbR@NKmvKjnbsO0eDq77qgBGyNY7ebQxfg9NDi4V531lH@04rBt7k0b/pdYlXLGU48GYww9Pn3z@IazT@s/aoc7BqlAG@96@ydRJAMpgI3FJChAe40xTJpmJWwEaQTQAZohugKRMoTkjIlN6m1Lsz8Qc "Python 3 – Try It Online")
**Commented:**
```
from random import*
def f(g):
  r=0    # last instruction
  x=y=0  # current position in the grid
  a=0    # y-direction
  b=1    # x-direction
  # grid of random characters of the same dimensions as g
  N=[[chr(randint(32,126))for _ in t]for t in g]
  # until the last instruction was a ;
  while';'!=r:
    # update instruction and random character
    N[y][x]=r=g[y][x]
    # update direction, ord(r)%9%6 maps
    # < -> 0, v -> 1, ^ -> 2, ^ -> 4, ' ' -> 5
    a,b=[0,1,0,2,-1,a,-1,0,1,2,0,b][ord(r)%9%6::6]
    # update position, modulo takes care of the wrapping
    x=(x+b)%len(g[0]); y=(y+a)%len(g)
  # return random matrix where visited indices are replaced with the program
  return N
```
[Try it online!](https://tio.run/##ZVP/jqJADP6fp@jFGGB3NOremZyIj@ALsHoZYYTJwUA6I8rTe@0od3EPA22/fv0x7dgNrmrNx/1@xrYBlKYgoZuuRfcWFOoM56iMNwEApgugZwK1tA60sQ4vudOtId8tHdg7gfyCqIyDrrWafcQDVykoURfEk2OOYVZoVGP4KV0@4NsLPPFh0J7HtvJKosydQssg57WyUVDoRhlLMRakhZIi92mW5RVGHKeNiz5WYrlax/G5RfjlezqwyseA8hD4WhfjdO2Tfj0gXCmthIRo10rXKkzCbynyTHxcV0inXvhU9b@WPXufDYfsdkgxLR/aa46/hxfQYhFhPP05XUMjO/vkbWG2g4WAnuVSwJHl6im/CwjpR9oPT5filGYLsRQLsRKzpZD8YXtF39Mh@1dis1l/6WTcn4CmLS51C07@VhZyiWoc/RVl12lT@sBbGt3eT/G0ViYqs8UhTmBIo@FdPqHYjxiVu6AZR9NIh/pGI1WUtNdUUBU0xkLnVIkLoepqmRN41a7yNTtsS5QN38ZHqv39cVXBDjYInLLOQsrG3Dra/ByVLKJ4brtauyj8NJ8mjIPA7175JXtpeZclBWa1ti6qtVExMIm1kfRIwoiNYh4XE7C9sn/8jwB1yPftjXABVnVpGPLRH2h87xMIdtAHcNwGQcIKvdstGR4lbwLeIKsH2JF2BCLtEgJ7MoJ@e@y3zN4lfwA "Python 3 – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~70~~ 59 bytes
```
O%19ịı*Ɱ6ḊḊŻƲÆiḞŻ¤4Ṭs2¤‘œị¥@ȯƭƒ+ḷƭⱮ⁸%⁹,ZẈW¤ʋƬḢ€‘ŒṬ¬aØṖX¤€€o
```
[Try it online!](https://tio.run/##y0rNyan8/99f1dDy4e7uIxu1Hm1cZ/ZwRxcQHd19bNPhtsyHO@Yd3X1oicnDnWuKjQ4tedQw4@hkoNJDSx1OrD@29tgk7Yc7th9bC9T2qHGH6qPGnTpRD3d1hB9acqr72JqHOxY9aloD0jIJqP3QmsTDMx7unBYBNAUo2rQm/7/1o4Y5h7Yd2qZrByIfNcy1frh7y@H2yGNdXEBbdi5@1LgPJHG4Hag6C6ZWVxeq@P//MmsFLjuFMi6FOBsuLmsQA4htbIAcsChQ1loBzAHyyhQU7ICsOAWgIjtroGAZkMNVZhNXZgNSbWcNAA "Jelly – Try It Online")
A link that is called as a monad with a list of Jelly strings and returns a list of Jelly strings.
[Here’s a version that shows # in place of the random characters.](https://tio.run/##y0rNyan8/99f1dDy4e7uIxu1Hm1cZ/ZwRxcQHd19bNPhtsyHO@Yd3X1oicnDnWuKjQ4tedQw4@hkoNJDSx1OrD@29tgk7Yc7th9bC9T2qHGH6qPGnTpRD3d1hB9acqr72JqHOxY9aloD0jIJqP3QmsRHDXOVQSJNa/L/Wz9qmHNo26FtunYgEihj/XD3lsPtkce6uIA27Fz8qHEfSOJwO1B1Fkytri5U8f//ZdYKXHYKZVwKcTZcXNYgBhDb2AA5YFGgrLUCmAPklSko2AFZcQpARXbWQMEyIIerzCauzAak2s4aAA) 
## Explanation (outdated)
### Helper link
Takes `[[pos_x, pos_y], [dir_x, dir_y]]` as its left argument and a converted grid as its right (see below) and returns an updated list of position and direction
```
   ¥1¦               | Do the following to the position component of the lost:
‘                    | - Add 1
 œị                  | - Multidimensional index into grid
      ȯ/             | Reduce using logical or
        ⁸            | Using the original left argument:
         +ṛƭ€        | - Add the new direction to the position, and append the new direction
             %       | Mod with:
              ⁹    ¤ | - The grid
               ,Z    | - Paired with its transpose
                 Ẉ   | - Lengths
                  W  | - Wrapped (which will mean only the position is affected)
```
### Main link
```
“;>^<v”iⱮⱮ                                  | Positions of each character in the grid in ";>^<v"
          ‘                                 | Increase by 1
           ị          ¤                     | Index into:
            ı                               | - i
             *Ɱ4¤                           | - ** each of 1..4
                 Ż                          | - Prepend zero
                  Æi                        | - Convert from complex
                    Ḟ                       | - Floor
                     Ż                      | - Prepend zero
                           ¤                | Starting with:
                       4                    | - 4
                        Ṭ                   | - Untruthy ([0,0,0,1])
                         s2                 | - Split into lists length 2 ([[0,0],[0,1]])
                            çƬ              | Call the helper link with the grid as the right argument until no new value encountered
                              Ḣ€            | Head of each (i.e. positions)
                                ‘           | Add 1
                                 ŒṬ         | Multidimensional untruthy
                                   ¬        | Not
                                    aØṖX¤€€ | And with a list of lists of random printable characters for each original character in the grid
                                           o| Logical or with original grid
```
[Answer]
# [R](https://www.r-project.org/), ~~217~~ ~~175~~ ~~178~~ ~~173~~ ~~155~~ 154 bytes
```
function(A,B=A,j=1:0,i=t(j+!j)){B[]=intToUtf8(runif(A,,95)+32,T);while(";"!=(B[i]=a=A[i]))i=(i-(j=switch(a,">"=1:0,"<"=1:2,v=0:1,"^"=2:1,j)))%%dim(A)+1;B}
```
[Try it online!](https://tio.run/##pY5Ba8JAEIXv@RWbAWGWbEFjC627E0h@gz2lCYTU4AaNEte1UPrb04la8CIeeni8w7z3zeuHhobm2NXO7jpMVUapamm2mCpLDtsobKX8zvKCbOeWu3fXvGJ/7GzDUfX2IqN5rJZSn9Z2s0LQEBJmuS2oopRNSkton7Clw8m6eo2VggTOdDCjx8rTdDFTUALF7PxMTiafdoupjGY6@xka3Faut19YI1cVeJZgaZAqVvxbBrcRfz5dIsnV/yoljF@lml9qgdvuabXBg@sP@411PF/4QLCMMRyFWzRnc1ZI8NFBcR@RjAgtAi3@gWCGFyIJElEKHpToB6jnuyjPiMCb0huG@Yeg66bhFw "R – Try It Online")
Thanks to [@Nick Kennedy](https://codegolf.stackexchange.com/users/42248/nick-kennedy) for very nice golfs resulting in -42 bytes (!) and clarifying some issues with the OP.
-5 bytes inspired by [@Neil's Charcoal answer](https://codegolf.stackexchange.com/a/233243/55372), but as I understand this approach is also used in some other answers.
Thanks to [@Dominic van Essen](https://codegolf.stackexchange.com/users/95126/dominic-van-essen) for -17 bytes.
[Answer]
# Excel VBA, 400 bytes
```
    Sub f()
    Set a=UsedRange
    m=a.Rows.Count
    n=a.Columns.Count
    r=1
    c=1
    Set u=[A1]
    While e=0
    Set x=Cells(r,c)
    Set u=Union(u,x)
    Select Case x
    Case">":s=0:d=1
    Case"<":s=0:d=-1
    Case"v":s=1:d=0
    Case"^":s=-1:d=0
    Case";":e=1
    End Select
    r=r+s
    c=c+d
    If r<1 Then r=m
    If r>m Then r=1
    If c<1 Then c=n
    If c>n Then c=1
    Wend
    For Each b In a.Cells
    If Intersect(b,u)Is Nothing Then b.Value=Chr(Int(113*Rnd+14))
    Next
    End Sub
```
Formatted code with comments explaining function:
```
    Sub f()
    
        Set a = UsedRange   'Save this here for shorter reference later
        m = a.Rows.Count    'Ditto
        n = a.Columns.Count 'Ditto
        r = 1               'Row
        c = 1               'Col
        Set u = [A1]        'Prime the collection with the first cell
        While e = 0
            ' Pick the cell we're going to examine and add it to the collection
            Set x = Cells(r, c)
            Set u = Union(u, x)
            
            ' Change the row / column shift if we hit a control character
            Select Case x
                Case ">": s = 0:  d = 1
                Case "<": s = 0:  d = -1
                Case "v": s = 1:  d = 0
                Case "^": s = -1: d = 0
                Case ";": e = 1   'Triggers the end of the While loop
            End Select
            
            ' Shift the row / cell and correct for edge (heh) cases
            r = r + s
            c = c + d
            If r < 1 Then r = m
            If r > m Then r = 1
            If c < 1 Then c = n
            If c > n Then c = 1
        Wend
        
        ' Loop through all the cells in the used range
        For Each b In a.Cells
            ' If that cell was not collected when moving through the program, fill it with a random character
            If Intersect(b, u) Is Nothing Then b.Value = Chr(Int(113 * Rnd + 14))
        Next
        
    End Sub
```
Input is one character per cell:
[![Input](https://i.stack.imgur.com/ovBn4.png)](https://i.stack.imgur.com/ovBn4.png)
Output is editing in-place:
[![Output](https://i.stack.imgur.com/1WeZr.png)](https://i.stack.imgur.com/1WeZr.png)
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~194~~ 188 bytes
Expects and returns a matrix of characters.
```
m=>m.map((r,Y)=>r.map((C,X)=>(g=x=>(x%=W)-X|(y%=H)-Y?~(c="^<v> ".indexOf(m[y][x]))?g(x+(c<4?(v=--c%2,h=~-c%2):h)+W,y+=v+H):Buffer([Math.random()*95+32])+'':C)(W=m[0].length,y=H=m.length)))
```
[Try it online!](https://tio.run/##TZBPb5wwEMXv/hSjrVb2FHBWaXroglmpUau9VD3ksIlYqChr/kRgtsaxQG3y1TeGRmoP9rzfzBvJfo@5zYdCN2cTqP4kL1dXIFX@s5Vg6mYA00MlDdB3FKSVejJNJ4nzfMtNzXWuTn0HAn6AiGHDNzeElOLSibjjXX5mTPsPKGL9F279ewesEqO7x7U4YHD/h01rscfgYffCCrHKIhvDijfqJMfvJeuSKU3GFHFXsdFjRXSzY1YEQbG@9mvxMlfc1ugd/MkT1tvj9vNTWUrNkv@ex/D9p4/eh@sUPUq3t8gOoks2KW@lqkztT2IvujdAxIuWv54aLRktB4pcy/z0tWnl3aQKtkFu@jujG1Ux5MO5bQxbHdVRrZCXvf6SFzUb5iR@E4A5luGfyVnmEJZxwjkfUgydS0vXAffThYpeDX0redtXzE2WDT1vaP7YN4pRivimjooieLBU8owXGwKJwRLIIkLCWbgTRQ6WrpuGsIAjCxA7lYEzxaFrutAzYqPMRrM7Dl8B "JavaScript (Node.js) – Try It Online")
]