[Question]
  [
Write a function that accepts a rectangular grid of ids in any reasonable format, for example a multi-line string:
```
IIILOO
ILLLOO
```
and a string or list of box drawing charcters such as:
```
' ═║╔╗╚╝╠╣╦╩╬'
```
or
```
[0x20, 0x2550, 0x2551, 0x2554, 0x2557, 0x255a, 0x255d, 0x2560, 0x2563, 0x2566, 0x2569, 0x256c']
```
(see below for more details) and returns a pretty printed version, as such:
```
╔═══════════╦═══╦═══════╗
║           ║   ║       ║
║   ╔═══════╝   ║       ║
║   ║           ║       ║
╚═══╩═══════════╩═══════╝
```
i.e. a rectangle made out of the box drawing characters, where each border indicates the border of each polyomino.
```
╔═══════════╦═══╦═══════╗
║ I   I   I ║ L ║ O   O ║
║   ╔═══════╝   ║       ║
║ I ║ L   L   L ║ O   O ║
╚═══╩═══════════╩═══════╝
```
# Rules
Shortest submission in bytes per language wins. Standard rules apply.
Note that to leave room for annotations and as the characters used are half width each unit square is 2x4 (3x5 but boundary fields are shared with neighbouring squares) characters in the output.
You may assume that input is clean rectangular and ids are unique to orthogonally connected regions.
To avoid any unicode related issues I have decided to provide the box drawing characters as an input. This may be any flat container holding the characters in any order as long as it contains
1. each character exactly once and
2. only these characters (no fillers)
3. access is sequential or per index only (no sophisticated lookup tables)
# More examples:
In:
```
XXXSS
RXSSL
ROOOL
RROLL
' ═║╔╗╚╝╠╣╦╩╬'
```
Out:
```
╔═══════════╦═══════╗
║           ║       ║
╠═══╗   ╔═══╝   ╔═══╣
║   ║   ║       ║   ║
║   ╠═══╩═══════╣   ║
║   ║           ║   ║
║   ╚═══╗   ╔═══╝   ║
║       ║   ║       ║
╚═══════╩═══╩═══════╝
```
In:
```
1220003
2240503
2444666
' ═║╔╗╚╝╠╣╦╩╬'
```
Out:
```
╔═══╦═══════╦═══════════╦═══╗
║   ║       ║           ║   ║
╠═══╝   ╔═══╣   ╔═══╗   ║   ║
║       ║   ║   ║   ║   ║   ║
║   ╔═══╝   ╚═══╬═══╩═══╩═══╣
║   ║           ║           ║
╚═══╩═══════════╩═══════════╝
```
  
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~147~~ ~~129~~ ~~80~~ ~~78~~ ~~76~~ ~~75~~ ~~71~~ 65 bytes
```
≔⁺ＳψθＷＳＦ²⊞υ⁺⭆ι×⁴λψ⊞υ⭆⌊υψＥυ⭆ＥιＥ⁴§§υ⁻κ÷ν²⁻μ∨⁼ν¹⁼ν²§θ﹪×⁷↨²Ｅλ⁼ν§λ⊕ξ⁹⁵
```
[Try it online!](https://tio.run/##VY/BSgMxEIbvfYo5TiDCNm4r0lNFDz0UC/oCSzd2g9lsd5PU@hYKBkEQBEEQfKq8yDbputYewiR8/3wzWRZZs6wy2bZTrcVK4UJajTO1tubGNEKtkFB4DKcmk8FDISSHY0rgrmoAGYGF1QVaCntDh@fZGgWFW1FyjSkFSfa2oOrDh9xcKFHaEu1fJBCDER3nOmcswTg1M5XzLfY1RIMoLHBPYabMpdiInKOiwEic3bGSwnWDV7XNpI5sGMjhFZMx2yvr0FblVlbY/eOMwkWmObJuCfm/t@@Rcfqy4SVXhue4/VWej/YXMmlb7368@/Luw7sX7769e/LuzbtP7169ewbv3gdDxpIkOR0wliajWNM0HY/H7clG7gA "Charcoal – Try It Online") Link is to verbose version of code. Expects the box-drawing characters first in the order `╬╦╠╔╩═╚╣╗║ ╝` followed by the newline-terminated grid of strings. Edit: Saved 6 bytes by stealing @Arnauld's cool mapping. Explanation:
```
≔⁺Ｓψθ
```
Append a null byte to the box drawing character string as this gives us a free modulo 13 due to Charcoal's cyclic indexing.
```
ＷＳＦ²⊞υ⁺⭆ι×⁴λψ⊞υ⭆⌊υψ
```
Read in the grid, duplicating it vertically and quadruplicating it horizontally, plus suffix a row and column of null bytes of padding.
```
Ｅυ⭆ＥιＥ⁴§§υ⁻κ÷ν²⁻μ∨⁼ν¹⁼ν²§θ﹪×⁷↨²Ｅλ⁼ν§λ⊕ξ⁹⁵
```
Map over the expanded grid, collecting a `2×2` square for each character, then comparing the characters in that square pairwise, treating the comparison results as base 2, and hashing into the box-drawing characters.
Previous 129 byte canvas-based version:
```
≔⁺ＳψθＷＳ⊞υιυＵＥ¹¦¹Ｆ⊕⊗ＬυＦ⊕⊗Ｌη«Ｊ⊖κ⊖ι≔ＫＭζ¿﹪ⅉ²¿﹪ⅈ²§θ﹪×⁷↨²Ｅ⁴⁼§ζ⊗λ§ζ⊗⊕λ⁹⁵Ｆ¬⁼§ζ¹§ζ⁵§θ⁵¿﹪ⅈ²Ｆ¬⁼§ζ³§ζ⁷§θ⁹»ＵＭＫＡ⎇№θιιψＵＥ¹Ｆ⊕ＬυＦ⊗Ｌη«Ｊ⊖⊗κ⊖⊗ι§ＫＶ⊕⊗κ
```
[Try it online!](https://tio.run/##hVLdSsMwGL22T5HLFCpstdsYXs3phaJj4BC9rOu3rSxNtrbRqewdFAyCIAiCIPhUeZH6pdu006qFkOT7OTnn6@mP/LgvfJZlrSQJh5x2mUzoPp/I9DiNQz6ktkOucE3tbetyFDIg61mbdGUyotIhIVZ0MZhSiae9WQo8oFWHVPE2ELHp68cQAU8hoLtCnjPcD4EPU2y38SP/VY3yqhtr40BGk56gu/BVOkaOxXto47MbK1EA4yMhYjBqrk0iHBB6JALJBD0zQReBC7HTVWwhqJXu8wBmdOqQZUEvjCChDYfs@AlQF@P@hHoO2ZtKnyWfDddIaqmB2QhZEi/qZQ5p1pAdsAQW0@iIlP7ErK5D1fK5/KBay0eQY5VJ@wN/ax2/UY7fNPhzC5W3RRT5@LfNnFuMmRd6EHM/vqJtIbFrauyBy3ipYI4yZxQcsaBYYoJfPLCqHNvfzLBKoCnMSNaVGNIngndAogZuuJdZcGznvfMs0@pdqzetXrR60upVq1utHrR61upRqzui1b1Vdd1KpbJlua5XqZnd87x6vW5lmxfsAw "Charcoal – Try It Online") Link is to verbose version of code. Expects the box-drawing characters first in the order `╬╩╣╝╦═╗╠╚║ ╔` followed by the newline-terminated grid of strings. Explanation:
```
≔⁺Ｓψθ
```
Append a null byte to the box drawing character string as this gives us a free modulo 13 due to Charcoal's cyclic indexing.
```
ＷＳ⊞υιυ
```
Read and print the grid.
```
ＵＥ¹¦¹
```
Double-space the grid horizontally and vertically.
```
Ｆ⊕⊗ＬυＦ⊕⊗Ｌη«Ｊ⊖κ⊖ι
```
Loop through each cell of the extended grid, including the border.
```
≔ＫＭζ
```
Get the contents of the adjacent cells.
```
¿﹪ⅉ²¿﹪ⅈ²§θ﹪×⁷↨²Ｅ⁴⁼§ζ⊗λ§ζ⊗⊕λ⁹⁵
```
If this is a cell e.g. between 4 ids then calculate which box-drawing character to draw.
```
Ｆ¬⁼§ζ¹§ζ⁵§θ⁵
```
If this is a row divider and the two ids differ then print a `═`.
```
¿﹪ⅈ²Ｆ¬⁼§ζ³§ζ⁷§θ⁹
```
If this is a column divider and the ids differ then print a `║`.
```
»ＵＭＫＡ⎇№θιιψ
```
Delete all non-box-drawing characters.
```
ＵＥ¹
```
Double-space the grid horizontally.
```
Ｆ⊕ＬυＦ⊗Ｌη«Ｊ⊖⊗κ⊖⊗ι§ＫＶ⊕⊗κ
```
Duplicate the row dividers.
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~282~~ ~~243~~ 219 bytes
Thanks @Arnauld for the idea that the values can be directly mapped to the output characters! I've made a code that finds such an expression by brute force. The `*7%95%13` is single shortest expression.
-24 bytes thanks @Arnauld for "width 4w+1 and height 2h+1" before sliding over the input string.
```
param($t,$s)$n=($s=$s-replace'.',('$0'*4)|%{$_;$_})|% Le*|Sort -b 1
$s=$s+,''|% *ht($n+1)
$s|%{-join(0..$n|%{$x=$_,--$_
$b,$a,$d,$c=$s[--$y,++$y]|%{$_[$x]}
$t[(!($a-$b)+2*!($a-$c)+4*!($b-$d)+8*!($c-$d))*7%95%13]});$y++}
```
[Try it online!](https://tio.run/##ZVJdi9pAFH2fXzEN105iJpJJov1YBMuyD0IgoC@CiB01Yko2SZORKpr/0EJDoVAoFAqF/qr8ETszu0jbzcPcc@eec@4dbor8Q1xWuzhNL7Adni4FL/m9CYJCZUE2NKEaQuWUcZHydUx6hJoEXNINrHPnBMsbWNYS4TDunqd5KbCzwgxpjU0JkZXuTpiQ2cySt1LivMuTzHR7PciUwWEIS@o4sESwosApbCispXgu747UtuG40H3mcFjUCMTcfGYCd2Bl2V73Aa4tO1Bw5cDGsl8quFbQ6r7ovOp3mL@orRs42nZ9qREamQjJJ9wd@H2RxpgROiJoPB6HUYTGYagCGVn/cDzNmc1m0ymayCNEkyiK5DmJwvAJ29ds5nmu6/rI8wK3r2IQBIPB4Mrm2RFXO17EFGe5wPsseb@PcbKpCMUjA2Et12rP87Q6QMaj9rUlWxiIMaZa@L70ZViSfOb6ku4zds2x68u@/T5j11zzlam2s/AZd04Iyw82cbUuk0IkeUYxyFnwEMvF6NpjpoJTFWkisPE2Mx5q25SL2zwTPMniUrJI2/xum@9t86NtPrXNr7b52jbf2uZn23xumy@4bT6qH0PktztevilLfpQrNmBpyPVowzKu9qmQTs9h@7@9GgE9mfdvHaovfwA "PowerShell – Try It Online")
Less golfed:
```
param($t,$s)
$s=$s-replace'.',('$0'*4)|%{$_;$_}  # magnify to 4*width and 2*heght
$n=$s|% Length|sort -b 1            # find max length
$s=$s+,''|% PadRight($n+1)          # add +1 to width and height
$s|%{                               # (in addition, we got a rectangle)
    -join(0..$n|%{
        $x=$_,--$_
        $b,$a,$d,$c=$s[--$y,++$y]|%{$_[$x]}           # I need to golf
        $i=!($a-$b)+2*!($a-$c)+4*!($b-$d)+8*!($c-$d)  # this 2 lines  cxxx|;:;:;:;:;:;:>
        $t[7*$i%95%13]
    })
    $y++
}
```
## Main idea
Let a square of 4 characters slide over the input string "magnified 4 times in width and twice in height".
```
..
..IILOO
 ILLLOO
 ..
 ..ILOO
 ILLLOO
  ..
 I..LOO
 ILLLOO
.~.~.~.~.~.
..IILOO
..LLLOO
 ..IILOO
 ..LLLOO
 I..ILOO
 I..LLOO
 II..LOO
 IL..LOO
.~.~.~.~.~.
 IIILOO
..LLLOO
..
.~.~.~.~.~.
 IIILOO
 ILLLO..
      ..
```
Let's name the points in the square as a,b,c,d.
The expression `(a=b)+2*(a=c)+4*(b=d)+8*(c=d)` returns numbers in range 0..15, which correspond to the border chars:
```
 0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
----------------------------------------------------------------
 ab  aa  ab  aa  ab  aa  ab  aa  ab  aa  ab  aa  ab  aa  aa  aa
 cd  cd  ad  ad  cb  ca  ab  aa  cc  cc  aa  aa  bb  aa  aa  aa
 0   1   2   3   4   5   6   15  8   9   10  15  12  15  15  15  - the expression results
 ╬   ╦   ╠   ╔   ╣   ╗   ║       ╩   ═   ╚       ╝               - related border chars. the space char for 15
 0   7   1   8   2   9   3       4   11  5       6           10  - *7%95%13 - index in the "flat container"
 012345678901
 ╬╠╣║╩╚╝╦╔╗ ═    - the flat container
```
The script draws the border char for each position of the sliding square. Plus draws middle row between input lines.
The script expectes the flat container with border chars in order `╬╠╣║╩╚╝╦╔╗ ═`.
[Answer]
# JavaScript (ES6), ~~164 154~~ 143 bytes
Expects `(a)('╬╩╠╚╣╝║╦═╔ ╗')`, where `a` is a list of strings.
```
a=>c=>[...a,...a,a[0]].map((r,y)=>[...r+r+r+r+0].map((v,x)=>c[g=d=>v==(v=(a[y-d%2>>1]||0)[x-~x-d>>3]),(g``,8*g(1)|g(3)|4*g(2)|2*g``)*7%95%13]))
```
[Try it online!](https://tio.run/##RZDdSsNAEIXv9ymWQslOmyxpmlZFNncKhUCguSmkhS75M5ImNYmlxegzKLgIgiAIguBT7YvUNC3IwDkHvjMMzC3f8NIvknWlZXkQ7iO258zymeVRSrnaCvf0xYKu@JqQQt3BkRX94@gnslG3DfG9mAXM2jBGNoxwb6cFXcOyBou61sHbak9bLbCs4QJUEi@X6nkvJgOoYzKE2myyAbXRawD0zroXo@6gKcK@CO/ukyIkSlQqQIuQB9dJGrq7zCc60Cp3qyLJYgK0XKdJRTrzbJ51gEZ5ccX9G1JiZuEHhHEaVphjhsv/YgcuT2DVgIhwIIoUv1L8SPEpxbsUX1J8SPEixbcUz1K8YinelHbLz7MyT0Oa5jFZtT9oL5X0Nk8yoigApzTPFMB93Dp6hP1kMrEdB01s@2BoNpu5Lpo2YqOp4ziNTh3bRmhgGLquD5FhmPro4KZpjsfjPw "JavaScript (Node.js) – Try It Online")
### How?
Given a matrix \$M\$ of size \$w\times h\$, we build an expanded matrix \$M'\$ of width \$4w+1\$ and height \$2h+1\$ filled with the original values of \$M\$ magnified 4 times in width and twice in height. The extra column and extra row are filled with undefined values.
For instance:
```
AB  ==> AAAABBBB?
CD      AAAABBBB?
        CCCCDDDD?
        CCCCDDDD?
        ?????????
```
For each cell \$(x,y)\$ in \$M'\$, we extract \${M'}\_{x,y}\$ and 3 adjacent cells:
$$\begin{pmatrix}v\_3={M'}\_{x-1,y-1}&v\_1={M'}\_{x,y-1}\\
v\_2={M'}\_{x-1,y}&v\_0={M'}\_{x,y}\end{pmatrix}$$
Using these results, we build a 4-bit value as follows:
```
8 4 2 1
| | | |
| | | +--> set if v3 = v1
| | +----> set if v2 = v0
| +------> set if v3 = v2
+--------> set if v1 = v0
```
We may get all values from \$0\$ to \$15\$ except the ones with exactly 3 bits set: \$7\$, \$11\$, \$13\$ and \$14\$ (because if 3 equalities are satisfied, the 4th one must be satisfied as well).
The 12 remaining values can be directly mapped to the output characters. We use the expression \$((n\times7)\bmod 95)\bmod 13\$
to force all them into \$[0\dots 11]\$ ([Try it online!](https://tio.run/##y0osSyxOLsosKNHNy09J/f8/2kDHUMdIx1jHRMdUx0zHQsdSxxAoZKRjaBqrl5Zf5JqYnKGRp2Brp5Ccn1ecn5Oql5OfDhTQVlBX0LUDEtoKQJ6WgrmCqoKlKZAwNNbU1Pz/HwA "JavaScript (Node.js) – Try It Online")).
]