[Question]
  [
[Sandboxed](https://codegolf.meta.stackexchange.com/a/17913/75681)
Given a set of closed non-overlapping 2d contours (separated by at least one space even on diagonals) with arrows oriented consistently in the same clockwise or counter-clockwise direction (each contour has its own direction) and a positive number `n`, move the arrows `n` steps along the contours in the respective direction. 
The arrows are represented by `> v < ^` respectively for right, down, left and up directions. There the other characters are `-` (horizontal), `|` (vertical) and `+` (corner).
When an arrow is on a corner, it keeps its current direction and changes it only after the turn is taken.
There will always be a straight segment (or a space) between any two corners (like `+-+` for the horizontal and similar for the vertical) - in other words the sharp `U` turns are forbidden. The segments between the corners are either vertical or horizontal and the bend at a corner is always 90 degree.
# Input:
* a positive integer - `n` - number of steps
* an ASCII representation of the contours - it can be a multiline string, a list of strings, a list of characters and so on.
# Output:
The same contours with all arrows shifted `n` steps in each contour's overall direction.
# Test cases:
# 1.
Input: 
`n` = 1
```
 +----->->            
 |       |            
 |       v---+        
 |           |        
 +---<-------+      
```
Output:
```
 +------>+
 |       v
 |       +>--+
 |           |
 +--<--------+
```
# 2.
Input: 
`n` = 2 
```
 +-----+ +---+        
 |     | |   |        
 +-->--+ |   v  
         |   | 
 +--->---+   |        
 |           |         
 +------<<---+       
```
Output:
```
 +-----+ +---+
 |     | |   |
 +---->+ |   |
         |   | 
 +----->-+   v
 |           |     
 +----<<-----+        
```
# 3.
Input: 
`n` = 3
```
 +---+   +---+   +-------+      
 |   |   |   v   |       |      
 ^   |   |   |   +-<-+   |      
 |   |   ^   |       |   v      
 |   +---+   +-->----+   |      
 |                       |      
 |   +-------+   +---+   |      
 |   |       |   v   |   |      
 +---+       +---+   +---+      
```
Output: 
```
 +>--+   ^---+   +-------+
 |   |   |   |   ^       |
 |   |   |   |   +---+   |
 |   |   |   |       |   |
 |   +---+   v----->-+   |
 |                       |
 |   +-------+   +---+   v 
 |   |       |   |   |   |
 +---+       +-<-+   +---+  
```
# 4.
Input:
`n` = 1
```
+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 
```
Output:
```
+--+ 
|  |
|  +---+
|      |     
+----+ |
     | |
     +-+ 
```
# 5.
Input
`n` = 4 
```
^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v
```
Output:
```
^>>>>
^   v
^   v>>>>
^       v           
<<<<<<<<v
```
# 6.
Input:
`n` = 1
```
^->
^ v
<<v
```
Output:
```
^>+
^ v
<<v
```
Write a function or a program solving the above task. The shortest code in bytes in every language wins. Don't be discouraged by the golfing languages. Explanation of the algorithm and the code is highly appreciated.
  
[Answer]
# JavaScript (ES6), ~~210 ... 182~~ 180 bytes
Takes input as `(m)(n)`, where \$m\$ is a list of lists of characters. Returns the result in the same format.
```
m=>g=n=>n?g(n-1,m=m.map((r,y)=>r.map((c,x)=>(i=0,h=$=>~$?(m[Y=y+($-2)%2]||0)[X=x+~-$%2]>h?"-|+"[n+=`;m[${Y}][${X}]=S[${$}]`,i?2:$&1]:h($^++i):c)((S="<^>v").indexOf(c)))),eval(n)):m
```
[Try it online!](https://tio.run/##hVLBbuIwEL3zFaMou9iyHRW6JxqbT9hDL63SREVpgFTYqQKyqGr669QmsJsYVx3Jmczk5c2b8bwu9GJbtvXbjqnmpTou@VFyseKKCzVfIcUmVHKZyMUbQi19x1y0XVDSvQ1QzW/omsdcfMZzJLNH/k5QzKb41zQ35gZnD3xPPllsQ7GeR8yQKFOEP9/JLP54POT2@XDI@b318SF/pvV8Oot/T/LZGsUFITWelRihex6lhdARTmr1Uu3/LlGJrdFKLzZIYTyTx1213QEHJCkoDFzAB5SN2jabKtk0K7REElvkSXrrPrfJa1MrNB5jfH57UmMMBE7@Dg6jkaNE2QggS5IkIsyZYCLK6SVnoDMTyGmLJoG8j3e8KevM4kc5hQkO1iZAgpwGzDWncHiX1738v/oBDeJUIdxLSLOTnf7XPA1pdnx9zwL6L0efvV@r6GHMiScN6nSn6HN4vZuhFsF@6Be@6d30e@lxhvSA15s/Q3LGDGbVzfM2ME9vdF7F8HJc3xsZpC4b5KfIt8tYCGveBWk/DmDAw6Vn012dP1d12JBh@K@@qDt@AQ "JavaScript (Node.js) – Try It Online")
## How?
You can [follow this link](https://tio.run/##jVLbbqMwEH3nK0aI3dgyRk12n1ogn7APfWmVBTWipKUKUJEIparTX8@OuSTgDLs7Eox9PHPmzNhv63q9S6rsfS@L8jk9bYJTDkFoAbxAAEW7BFwsG48w6xYalDB3z1vMg9zL1@@MVS588D63tao9SVw4GCcAbLQDyJDpxjXAVwQdM1Pbl3MW9zfSTuSKhAEekf4DBDAHu1pw@AYLMjICpW6IE04TPyDtAWm/pDNBGUGIvS3JbFsqYU8pLkAE8HSXr5zPx2OE/4djFNyjd47RkzuRlMESFnCLk/wOc7pBAr0lI19xVjEIkXHrfxKSEcbN@2H3OCrbj8Pa5l5WPKeHXxuWjKmHu8uaX5pN6/WWFf1R63st@Wmf7vZYhOUuFPoRwickZbErt6m3LV/YhuUck5uHWunjynsrs4LNZpx3q9/FjONtNv4OjpalKZm@oZXnebaQ2kIZ2pHbY6qTpgisxmhB4Ga85vVlaxhvRS7MOVlbgCA5FahrzlDHa7we4Of6hIawqUD3QmnWsv2L5gWlWfMNvST091/debNWPIhRDY9P6tRfPOQweldjLaH8R78w0bsa9jLgpPSA0Zs5Q9HFjGbVzvMHMU9jdEZF@nFc35sYQf0LMiEx@RjjEM24oNrcEzFgxPmd1W2dn1d15JhhnFv36k5/AA) to see a formatted version of the source.
### Wrapper
The recursive function \$g\$ is just used as a wrapper that invokes the main code to move all arrows by 1 step and keeps calling itself with \$n-1\$ until \$n=0\$.
### Update method
We can't safely move each arrow one at a time because we would run the risk of overwriting non-updated arrows with updated ones. Instead, we first remove all arrows and compute their new positions. We apply the new positions in a second time.
This is done by re-using \$n\$ as a string to store the position updates as JS code.
For instance, in the first test case, \$n\$ is set to:
```
"1;m[0][7]=S[2];m[1][8]=S[3];m[2][9]=S[2];m[4][3]=S[0]"
```
(Note that the leading number -- which is the original value of \$n\$ -- is harmless.)
The new positions are applied by just doing `eval(n)`.
### Directions
Each arrow is converted into a direction \$d\$ (named `$` in the code), using the following compass:
$$\begin{matrix}
&1\\
0&+&2\\
&3
\end{matrix}$$
The corresponding values of \$dx\$ and \$dy\$ are computed this way:
```
 d | dx = (d - 1) % 2 | dy = (d - 2) % 2
---+------------------+------------------
 0 |        -1        |         0
 1 |         0        |        -1
 2 |        +1        |         0
 3 |         0        |        +1
```
### Corners
If the next character in the identified direction is a space or is out of bounds, it means that we're located on a corner and we need to take a 90° or 270° turn. This is why the helper function \$h\$ is testing up to 3 distinct directions: \$d\$, \$d\operatorname{xor}1\$ and \$d\operatorname{xor}3\$.
If we're located on a corner, we overwrite the cell with `+`. Otherwise, we overwrite it with either `-` or `|`, depending on the parity of \$d\$.
**Note**: The parameter of \$h\$ is not named `$` just because it looks uber l33t but also because it allows us to compare a given character with \$h\$ (implicitly coerced to a string) to know if it's a space (below `"$"`), a contour character (above `"$"`) or another arrow (also above `"$"`).
## Animated version
```
f=
m=>g=n=>n?g(n-1,m=m.map((r,y)=>r.map((c,x)=>(i=0,h=$=>~$?(m[Y=y+($-2)%2]||0)[X=x+~-$%2]>h?"-|+"[n+=`;m[${Y}][${X}]=S[${$}]`,i?2:$&1]:h($^++i):c)((S="<^>v").indexOf(c)))),eval(n)):m
m = [
  [..."+---+   +---+   +-------+"],
  [..."|   |   |   v   |       |"],
  [..."^   |   |   |   +-<-+   |"],
  [..."|   |   ^   |       |   v"],
  [..."|   +---+   +-->----+   |"],
  [..."|                       |"],
  [..."|   +-------+   +---+   |"],
  [..."|   |       |   v   |   |"],
  [..."+---+       +---+   +---+"]
];
(F = _ => (o.innerHTML = m.map(r => r.join('')).join('\n'), m = f(m)(1), window.setTimeout(F, 100)))()
```
```
<pre id=o></pre>
```
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~183 161 157~~ 155 bytes
```
{A:"^>v<";D,:-D:(-1 0;!2);s:#'1*:\x;r:" -+|"r*+/'3':|0,|0,r:~^x;$[p:+s\&~^t:A?,/x;;:r];s#@[,/r;s/+q;:;A@D?-p-q:q@'*'&'~^x ./:/:q:+p+/:D@4!(t^0N)+/:0 1 3]}/
```
[Try it online!](https://ngn.bitbucket.io/k#eJy9VMtuwjAQvOcr3BSRhMUECqfdyAWJc0/caKz2glS1UiGgKFVTvr2xgciOk4pD21UsK6P17sz4scHPBfpS5IlPyyHyJYZ8wsZ0cxfRHm+DyQAfC8rQZxxKPxtAHEwDLMfD6svwKAvqrbcI+8f+UR5wcT+MCyLMUtrfztfDOKN9DDtCWsyX93zLd7ibB4OgH1Qr2SjGGHcIW4hxOZ/dhAc5foiqnzGbsGn6FXveCj97649jhhs2YgU9vb9S+LR5fnmjgj4oi9Ivb7UOJxT6wFUILlgVvsd0+OVpZmUrmlcrwEF1fo2qugk/BfhRdMIv/biA9sqtKIir+l3aqX6p0ndX6wMGLZxLrc+qoTppNK/RupejT+jKJtrthbIjafXiam7aNRvt5qbYgaXjB25JYvk2Pfum1pszd3heRn6e7drSyCh1jaTFLzWkud5hbXAQ/EfPzSidGryhyeVR92/1FM4ZljfmfooTLq/y7KLb5Wp71sW1ydnVq/ffOAu/4Vne6Vk9OjxLTM9S4/1xngLn1Wm7IM0zDM1rUTYBaF6+f22sFc8qxVJUYTVSpyB3EZVnIczyPzlHboj6g9r1TklurjBzbQbQnZV631VLRgo=)
`{` `}/` when called with an int left arg n, this will apply the function in `{` `}` n times to the right arg
`A:"^>v<"` arrows
`D,:-D:(-1 0;!2)` ∆y,∆x for the 4 cardinal directions
`s:#'1*:\x` shape of the input: height,width
`r:~^x` countours - boolean matrix showing where the non-spaces are
`r:" -+|"r*+/'3':|0,|0,r` recreate the character matrix with a countour but without arrows, by counting self+upper+lower for each cell in `r` and replacing 1->`-`, 2->`+`, 3->`|`
`t:A?,/x` types of arrows: 0 1 2 3 for `^>v<`, all other cells are represented as `0N` (null)
`p:+s\&~^t` coordinates of the arrows
`$[#p` `;;:r]` if there aren't any arrows, return `r`
`q:+p+/:D@4!(t^0N)+/:0 1 3` all 3 possible new positions for each arrow - if it keeps going forward, if it turns left, and if it turns right
`q:q@'*'&'~^x ./:/:q` for each arrow choose the first option that lands on the countour
`@[,/r;s/+q;:;A@D?q-p]` flatten `r` and put on it the arrows at their new positions and with their new directions
`s#` reshape to the original shape
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 105 bytes
```
Ｗ¬ΦυΣκ⊞υＳ≔⊟υη≔⪫υ⸿θ≔⟦⟧υ≔>^<vζＰθＦθ¿№ζι«⊞υ⟦⌕ζιⅉⅈ⟧§+|-↨ＥＫＶ›κ ²»ιＦυ«Ｊ⊟ι⊟ι≔⊟ιιＦＩη«≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§ＫＶ⁻⁵λ ιＭ✳⊗ι»§ζι
```
[Try it online!](https://tio.run/##ZVHBSsNAED03XzHkNEvTi9STRagtlRYiBUWUWiEmW7N0uxuT3Soavz3ubFpTdA6ZzLy8mfcmaZ6UqU5k07znQnLAG21wJqThJdoIbu0Ot4wxWNoqp8ZcFdbcmlKoV2TsIhhXlXhVuNQFWhZB3rUWWihihE9l6JC3DlmtI7BdGV4@j/ZhBJ@uFVtpROGmGyTCRpfgXkBsACfauu5nBMLJ@Qp6R0WrmVBZ24/gEd3jAdnakXtLP2ds5irjHxj264HbcpVUHOOkwCXn23utbrjdJUoR77rkCfneOtEQMtc5Y@TxO@Cy4tCOE0dZ1qtY2F1xp71/2t9mWn5yGAKI1vO8SVIZzFsPp18djj6MYOz8xDqzUmMslK1wytOS77gyPPPD5qqrJekcnqg/@v3vrx12HoHneIvsKK0X6z3HqSh5aoRWONX2Rfp13s3332u2/8Hdpmn6A4o@UO4HNVDUQLkOXO@SMKr2ARziFyPQoVTV0EWLuRiN/MyzZrCXPw "Charcoal – Try It Online") Link is to verbose version of code. Includes 22 bytes used to avoid requiring a cumbersome input format. Explanation:
```
Ｗ¬ΦυΣκ⊞υＳ≔⊟υη≔⪫υ⸿θ≔⟦⟧υ
```
Conveniently input the contours and the number of steps.
```
≔>^<vζ
```
The direction characters are used several times so the string is cached here. The index of a direction character in this string is known as its direction.
```
Ｐθ
```
Print the original contours without moving the cursor.
```
Ｆθ
```
Loop over the characters in the contour.
```
¿№ζι«
```
If the current characters is a direction character...
```
⊞υ⟦⌕ζιⅉⅈ⟧
```
... then save the direction and position in a list...
```
§+|-↨ＥＫＶ›κ ²
```
... and replace the character with the appropriate line character.
```
»ι
```
Otherwise output the character and move on to the next character.
```
Ｆυ«
```
Loop over the saved positions.
```
Ｊ⊟ι⊟ι
```
Jump to the saved position.
```
≔⊟ιι
```
Extract the saved direction.
```
ＦＩη«
```
Loop over the appropriate number of steps.
```
≔⊟Φ⁴∧﹪⁻⊖ι⊕λ⁴›§ＫＶ⁻⁵λ ι
```
Find the direction of the next step, which is any direction that is neither reverse nor empty.
```
Ｍ✳⊗ι
```
Take a step in that direction. (Charcoal direction indices for the `Move` command are twice the value of my direction.)
```
»§ζι
```
Print the appropriate direction character.
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 111 bytes[SBCS](https://github.com/abrudz/SBCS)
```
{A[D⍳q-p]@q⊢' |+-'[c×3+/0,c,0]⊣q←⊃¨(⍸c←' '≠⍵)∘∩¨↓⍉D[4|0 1 3∘.+4~⍨,t]+⍤1⊢p←⍸4>t←⍵⍳⍨A←'v>^<'⊣D←9 11∘○¨0j1*⍳4}⍣⎕⊢⎕
```
[Try it online!](https://tio.run/##rVRfaxNBEH@/TzFvq27O5kxelGOxkI/Qt5CDkDZSLeYP4UCy8UWJSdotipT6Ikjbh@irBEpBhPhN5ovEmb07s3dNFNSFy@3szPx@v5mbTbN75O@/aB51nqzw9Oywg@O3ZQ8nb9qr4W69huZrz@82HvdwdiFAS1/UWz/OK3KnXGqVyg2cXfYoAWevlvM7aK5bZAgQOP2EZnEXJx9w8nk5x/F7NNNavarLEECFju/L6ks089KgIdFcBQTeZRhzXVUDu1kQMQXsMl6solAQU42MhxAEDHt@vJyXnwb3KKw6QnNJ0gmEflck3WtbjNMAT76J0VCUxC837/oCzQ2bZiFwMuPdyXc6b/VFWwCajzDoN/fbz2HQAXp5e4Q2ZEnTi35SbHuHEB4xKPPckK@Px69F55kYrZp0BgA4fiekz0v5imygtmhIli7YMUVJx7YxZHN@6CdLCi@AJuytcX0lizgFW6qtuBks43q3JEuQOUnaSk5TGdTaMdnglJRJVhYhsTeVxFWFCfWDfEm/5bUFZ/YmXmaWqa6NvGG4rWROc9@@IyN74uzLpZCR49M2L8yVzU/k5lhpxGy@WHLm1nle5W9pHRTK0a5OB8PlhoLurA0ymw43V3gHTkdU4on@0JGsQigwrztyW1VRnWbmLR2JnY/6tx2JN3REb@1I6HakwsMJB8VhcW6dc5Hzg7ueObkeV73eyuJ9/m@grthI0UrRIuf/we7Zl@4h7VOYLprSaqbtHzByUvwkMAmJneIjJXOenw "APL (Dyalog Unicode) – Try It Online")
similar to [my k answer](https://codegolf.stackexchange.com/a/188981/24908)
]