[Question]
  [
## Overview
The cover of a book will be provided in the following ASCII format:
```
______
|    |
|    |
|    |
|    |
------
```
The input can be in any reasonable format (eg. a list of strings, a nested list of characters, etc.)
Inside the "borders" of the cover, other printable ascii characters might appear, which contribute to the "popularity index" (the definition of which has been completely made up for this challenge).
### Popularity Index
Let the *popularity index* of a book be the number of unique characters that appear on the book cover (this does not include space characters or the edges of the cover). A book may have no unique characters on the cover (the cover is blank), in which case the popularity index is **0**.
**Examples**
```
______
|\/ /|
|/\/ |
| /\/|
|/ /\|
------
```
Two unique characters (`/` and `\`) so the popularity index is **2**.
```
______
| / /|
|/ / |
| / /|
|/ / |
------
```
One unique character (`/`), so the popularity index is **1**
```
______
|    |
|    |
|    |
|    |
------
```
No unique characters, the popularity index is **0**
```
______
|\^$@|
|/\/ |
| 456|
|/ /\|
------
```
8 unique characters, so the popularity index is **8**.
```
______
|\^$@|
|987 |
| 456|
|/hi!|
------
```
14 unique characters, so the popularity index is **14**.
```
______
|////|
|////|
|////|
|////|
------
```
One unique character (`/`), so the popularity index is **1**.
### Damaged Books
The edges of the book might also be damaged:
```
Top         Left        Right       Bottom
_~____      ______      ______      ______
|    |      |    |      |    |      |    |
|    |      |    |      |    |      |    |
|    |  or  {    |  or  |    }  or  |    |
|    |      |    |      |    |      |    |
------      ------      ------      ---~--
```
The book may have several of these "scratches". The scratches at the top and bottom will always be represented by a `~`, while the scratches on the left and right will always be represented by a `{` and `}` respectively. Each scratch will decrease the popularity index by **1**. 
As a result, it is possible for a book to have a **negative** popularity index.
## Task
Given an ASCII representation of a book cover in the format described above, determine the "popularity index" of the book
### Assumptions
* You can assume that the characters `|`, `_`, and `-` will not appear elsewhere on the book cover (only on the edges). However, the scratch characters (`{`, `}`, and `~`) **may** appear on the book cover in which case they should be treated as any other unique character on the cover.
* All characters appearing on the cover will be printable ascii
* Note that spaces do not count as a unique character. As the examples above show, a "blank" cover is one that only contains spaces.
* The book will always be the same size (height and width are fixed). Hence, the popularity index will never exceed **16**.
### Scoring
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"). Happy golfing!
**More Examples**
```
______
|{. }|
|/. /|
|/. /}
|/. /|
------
```
4 unique characters (`{`, `}`, `.` and `/`) and one scratch (`}` on the right) so the popularity index is **3**.
```
______
{    |
| .. |
|    }
{    |
--~~--
```
One unique character (`.`) and 5 scratches so the popularity index is **-4**.
### Test Cases
```
______
|    |
|    |
|    |
|    |
------    ->    0
______
|\/ /|
|/\/ |
| /\/|
|/ /\|
------    ->    2
______
| / /|
|/ / |
| / /|
|/ / |
------    ->    1
______
|\^$@|
|/\/ |
| 456|
|/ /\|
------    ->    8
______
|!!!!|
|+  +|
| ** |
|<**>|
------    ->    5
______
|\^$@|
|987 |
| 456|
|/hi!|
------    ->    14
______
|THIS|
| is |
| a. |
|BOOK|
------    ->    11
______
|////|
|////|
|////|
|////|
------    ->    1
______
|abcd|
|efgh|
|ijkl|
|mnop|
------    ->    16
______
|{. }|
|/. /|
|/. /}
|/. /|
------    ->    3
______
{    |
| .. |
|    }
{    |
--~~--    ->    -4
~~~~~~
{    }
{    }
{    }
{    }
~~~~~~    ->    -20
______
|~~~~|
|.   |
{....}
|.   |
------    ->    0
______
|{~~}|
|    |
|    |
|    |
------    ->    3
__~~__
|{~~}|
|    |
|    |
{    |
-----~    ->    -1
```
  
[Answer]
# JavaScript (ES6), ~~75 74~~ 73 bytes
Takes a single string of 36 characters as input, i.e. without any line feed.
```
s=>s.replace(o=/[^ |_-]/g,(c,n)=>t+=n*9%56%37%9&1?o[c]^(o[c]=1):-1,t=0)|t
```
[Try it online!](https://tio.run/##jZJdb9owFIbv8ytcqTR2wA5pgZapSatKnTb1ohfsrpQqCwmYZTaNs0lVPv46Ow4EIhqknQu/Oc55zmtbZ@X/9VWQ8HVKhZyHm8jdKNdTLAnXsR@EWLr2ywzlb/TVXvRw0BPE9dKuK6xxZzjqXF13xhfOnXwJXmdYr65DvlCnl7p9kqebJHz/w5MQm5EyCbT05195HE4@RID7hKVykiZcLDBhah3zFNuoSz1mTcWdDVsxB/t@D1GHsEgmj36wxAq5noFQIIWScchiucARVjvcnApwWUkusGkSQgyyeavCyBFE3i60Cv1NPb32jRqa2siGMhtUV4PqDPQzdLmH0A5CO6iRHUPOwWl2ft9wGgxHJ51u9tAZBJR1EepqyLI0e2tZ3mdoeOw0vrluOi35WcvxBnvqx7fvE13OVUX5TMvD8/NTC3W4lQ2Rt8vpp/B/BnMoC6PFEoSvfsUgv4Vct0CjPZUxVOjmbPvcIEWdHVNXNZTVY8BYPQ1FvUlpWTYhOjDKKrYFRbtsSxrU5WGY9B9wYVX7jEEUdXZ6ArOyLP5zbPW1yvIUlDWg5gGdfw "JavaScript (Node.js) – Try It Online")
### How?
We filter out spaces, pipes, underscores and hyphens:
```
/[^ |_-]/g
```
It means that we're going to match only:
* scratches on the border (-1 point)
* or non-space characters on the cover (+1 point the first time each of them appears)
Given the 0-indexed position \$n\$ of the character in the input string, the shortest solution I've found so far to figure out if we're located on the border or on the cover is the following convoluted modulo chain:
$$\big(((9\times n)\bmod 56)\bmod 37\big)\bmod 9$$
which gives:
$$\begin{pmatrix}
0&1&2&3&4&5\\
6&7&8&9&10&11\\
12&13&14&15&16&17\\
18&19&20&21&22&23\\
24&25&26&27&28&29\\
30&31&32&33&34&35
\end{pmatrix}
\rightarrow
\begin{pmatrix}
\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}0&\color{blue}8\\
\color{blue}8&7&7&7&7&\color{blue}6\\
\color{blue}6&5&5&5&5&\color{blue}4\\
\color{blue}4&3&3&3&3&\color{blue}2\\
\color{blue}2&1&1&1&1&\color{blue}0\\
\color{blue}0&\color{blue}0&\color{blue}8&\color{blue}8&\color{blue}8&\color{blue}8
\end{pmatrix}$$
With even numbers on the border and odd numbers on the cover.
### Generalization of the formula
Given a square matrix of width \$w>3\$ whose cells are indexed from \$0\$ to \$w^2-1\$, the \$n\$-th cell is located on a border iff the result of the following expression is even:
$$\big(((p\times n)\bmod m\_0)\bmod m\_1\big)\bmod p$$
with:
$$p=2w-3$$
$$m\_0=2\cdot (w-1)^2+w$$
$$m\_1=2\cdot (w-2)^2+w-1$$
[Try it online!](https://tio.run/##TZBBboMwEEX3nGIWQbExQZB2UxF6iWy7CA0koiK25TiBCvnsdMZOSrzwzHy9P/r2T32vr0fTabuRqmnn@VuZpjXd6RcqGKD6hCkC6FsLGlDZQoLqBt5SVOlc8ofKSC44JAmOAoZ/oHgFtgtAeBkhdVTyqvo269WZHTTSq0m7NGxeTZec@iL0hfuSB@5dJ2UYxaKceQqSSonTDgYsQnAfPERXN6tvFon1uvTi0zwG1xhc4@KCp0dUwCSm1xBTopiixKB5ZtXemk6eGc903extbSx75@XDLYUIrfP36xPDYk@6yC3/zT74/Ac "JavaScript (Node.js) – Try It Online")
NB: This is an empirical result that I didn't attempt to prove.
[Answer]
# [Python 2](https://docs.python.org/2/), 73 bytes
Input is taken as a 2D list \$ b \$. Output is the popularity index of \$ b \$.
```
lambda b:len({j.pop(1)for j in b[1:5]*4}-{' '})-sum(map(`b`.count,'{}~'))
```
[Try it online!](https://tio.run/##fZJLT8JAFIX3/RWXxKQdcaYWAZFYY1xpXLDQnSi00NJiX2lLiCnTv17vlD4IoGfRk3vnm5M7nYl@UicMeoWtTwvP8M2lAebYswIlW7MojBSN2GEMa3ADMD@08eDzss9pJoPMCU02vuIbkTI352wRboL0Ss54LhNSbB3Xs0AbS7gvAh08N0mV8hMb2xn2NqlCCIhoV0THRrCylCEhEoSbVOyoGAmMJLHiFGwFOwR0vQSKWSlpB6jdeaOlpGupZqcqqLiqogsIXVToDdtrWKhYqNiDqmK1Nvfr4vEgtz8YHueOGraDwtUuQFewlIot95Q@NOzgOPdudHuY67iddoZ@A78/v7wJyk1K2GDCniaT1xZuJ1ZRu/N2cjrDXCxx1bJXDpq7/vbQ/CCMWnbYwBkDLqLY/n@h8bqq4JuazerLYqy@M143Kc1zZGlfykvt@/y8VQjttTctGpjJyrCMoXhdnbyKLM/5/y9IjJznf7HZAYtTaL8 "Python 2 – Try It Online")
---
The left part of the expression does two things: adds up the popularity index inside the cover, and removes its characters. The right part subtracts the damaged characters from the remaining characters.
[Answer]
# [J](http://jsoftware.com/), 51 41 40 bytes
```
_1#.1#.(+./~#:33)e.&'{}~'`(' '~:~.)/.&,]
```
[Try it online!](https://tio.run/##hY@xCsIwEIb3PMWPhabB5lJbp0gnwcnJvVSQFnFx6dYkrx7T2CKCxY@E48Ldx5@H3xDvUWtw5Cigw5WE4@V88u0uoXCyLSmX6KoSHaV8tI5fMw7utCOhKM0bL9hQE7LmQG0pJknB2ggzI8EaZhRBzcUunYwwwbrb/YkKNXoMbFU1IhAcIIolYJdHKZ37qNr9qstF3mv2d5lHFldZ/AtmpvmQiGKUkQJ26b7/OKv8Cw "J – Try It Online")
*-11 bytes thanks to Bubbler!* 
*Both the function table trick to compress `#:@68208171135` down to `+./~@#:@33`, and the "negative one base trick" are due to them.*
## how
1. `+./~@#:@33` Let's begin with this phrase, which produces:
```
1 1 1 1 1 1
1 0 0 0 0 1
1 0 0 0 0 1
1 0 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
```
How? 33 in binary `#:@33` is `1 0 0 0 0 1`. Then create an "or" function table `+./` of this list with itself. It is easy to verify this will be 1 exactly on the border cells.
2. `/.&,]` Flatten the input and use the mask above to split the input into two groups, using J's Key `/.` adverb:
```
Apply this verb to the              Damage:
1st group, the edges:    -------->  Is each character an 
     |                              element of '{}~'?
 ___/____                           Returns a 0-1 list.
 e.&'{}~'`(' '~:~.)
          ^^^^^^^^^
               |                    Reputation:
    And this one to the second -->  Is space not equal 
    (the interior)                  to each character
                                    of the uniq? Also
                                    a 0-1 list.
```
We now have two 0-1 lists. For example: 
```
Reputation: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
Damage:     1 1 0 1 1
```
J will extend the shorter list to the length of the longer, filling it with zeros:
```
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
```
3. `1#.` Sum rowwise:
```
1 4
```
4. `_1#.` This uses a -1 base as a golfy way to subtract 1 from 4. By definition of base:
```
(1 * -1^1) + (4 * -1^0)
(1 * -1) + (4 * 1)
3
```
[Answer]
# [Python 2](https://docs.python.org/2/), 68 bytes
```
lambda s:len(set((s[8:-6]*4)[::7])-{' '})-20+sum(map(s.count,'_|-'))
```
[Try it online!](https://tio.run/##fZJPT8JAEMXv/RQDMWFb6PJHBGzEGE8aDxz0BkoWKFAs26ZbQkxpvzrOlt2WKDqXl3nz25dpd8OveB3wznE5nBx9tp0tGAjHdzkRbkyIGA8cu/dudc2x4/TfTTupQS017U6rLnZbsmUhEXQe7HjcqE0Pds00j/u157vQdgzweAhDqE54lW4Cj5OI7afo7WJiwjKIwEMCIsZXLumZpgExi1ZujEcUZEDkip0vnSVBDw0mhBvF2ofhUB1qgAQaatBQLh4II49r/jjNyzgA1uGy2HkZLUOzkyY0cdpElRCq7FALtlOwoFhQ7Fmn2HaZ@3H1cJbbven9zB0UbAULp3WAumQtSx65s6z7gr35mXs76J/nrr1KuUO3gN@enl8l5YkcZlTK42j0UsLlxk2sw2X59XVsNl/g1F2u1ije5tNH2fIgLNleAScUUhlFT/8LJdWdgq81m@jLolTfWapN284yZO2ukeV18tPLohB8yMUa0sBMmoclFCvV3a9XkWRZ@v8Lkitn2V9scsbiFu1v "Python 2 – Try It Online")
Instead of counting defects on the borders, counts non-defects `_|-` throughout and subtract from 20, using the rule that only the borders can contain these characters. The `(s[8:-6]*4)[::7]` is a nice string-slicing way to extract the characters on the cover without borders.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~25~~ 22 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
4Fćˆøí}˜ðKÙg¯˜…~{}S¢O-
```
-3 bytes by taking inspiration of [*@JonathanAllan*'s Jelly answer](https://codegolf.stackexchange.com/a/205323/52210), so make sure to upvote him!
Input as a matrix of characters.
[Try it online](https://tio.run/##yy9OTMpM/f/fxO1I@@m2wzsOr609PefwBu/DM9MPrT8951HDsrrq2uBDi/x1//@PjlaKV9JRwEHE6ihEK9WA2NUgQg9EKICIWhBRgySvjyqvT4x8LXH6dUFs7ERsLAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V@m5JlXUFpipaCkU@l1aLeOkn9pCYRvX/nfxO1I@@m2wzsOr609PefwBu/DM9MPrT8951HDsrrq2uBDi/x1/@sc2vI/OjpaKV5JBwuO1YlWqgGyFNBwDQ1kdIEsTBwLlCLkupgYIKEPNUwfxSp9dGlUV6BIo@pCkabUhQp4HaiA133E6qEw/OKAWAWIHUgJPxMgNgViM9oGnyIaRliljZSMtDGcpwXFqA63QZKxo23wWQKxBRCbkxh6GUCcieJZ8p0XAsQeQOwJxMEYbgDZUozVdYlArIch4wTE/lDsTQXX6aPhGhrIkO86UBgkAXEyEKeg2JQKxGlAnA6NLYQMKESzgDgbiHNQZHKBOA@I84G4gAquq0aKoVqMcNDDWXYgy9QS0EOe66oJlv96WFMXup5aAqbBXFQHxciuq0MSR2Bc5tXSQAaHC4iIWXRdiBDSwxoO1UghCsO1BPRQlu5gLqsdwNYAzA20cl01Sa4DxWwsAA).
**Original 25 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage) approach:**
```
|¦¨ε¦¨}ðýê¦gIJ…_|-S¢O20-+
```
Default input as loose lines in STDIN.
[Try it online](https://tio.run/##yy9OTMpM/f@/5tCyQyvObQWRtYc3HN57eNWhZemeXo8alsXX6AYfWuRvZKCr/f9/PBhw1VTrKdTWcNXo6ynoQ6laGE8XDAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V@m5JlXUFpipaCkU3lot46Sf2kJhGtf@f/QskMrzm0FkbWHNxzee3jVoWXplV6PGpbF1@gGH1rkb2Sgq/1f5390tFI8GCjpKNUoAEENfoYuGCjF6iDri4nRV9AHK9MHMSEaQEyIGIiJU68CXKsCXCeaCA4741Qc0O00MTUjwkpFIAAr01ZQ0IZo1NKCmGCjpWVHhJWWFuboNmZkKuLUGOLhGQxRnlkM1ZeoB2E4@ft749SnDwQ1@BlY9SUmJaeAVaWmpWeAGZlZ2TlgRm5efgFOfdV6CrUQ0/VgUQBk1CKLYNNXjUglenqI5FKLLKWrW1cH1VcHBjDJWvwMqGJUd4KEwNboQU2v1gOCWmQR7P6rq6slJX3X1RHSV42iD@jOWAA).
**Explanation:**
```
4F            # Loop 4 times:
  ć           #  Extract head; pop and push remainder-matrix and first line separately
   ˆ          #  Pop and add this first line to the global array
    ø         #  Zip/transpose the remaining matrix; swapping rows/columns
     í        #  Reverse each line
              #  (`øí` basically rotates the matrix once clockwise)
}˜            # After the loop: flatten the remaining matrix
  ðK          # Remove all spaces
    Ù         # Uniquify it
     g        # And pop and push the amount of remaining unique (non-space) characters
¯˜            # Push the global array, and flatten it as well
  …~{}        # Push string "~{}"
      S       # Convert it to a list of characters: ["~","{","}"]
       ¢      # Count each in the flattened global array
        O     # Sum those
-             # Subtract the two from one another
              # (after which the result is output implicitly)                  
|             # Push all lines of inputs as a list of strings
 ¦¨           # Remove the first and last lines
   ε  }       # Map over each line:
    ¦¨        #  And also remove the first and last character of each line
       ðý     # Join everything together with space delimiter
         ê    # Uniquify and sort the characters
          ¦   # Remove the first character (the space)
           g  # And pop and push its length
I             # Push the input-list of lines again
 J            # Join them all together
  …_|-        # Push string "_|-"
      S       # Convert it to a list of characters: ["_","|","-"]
       ¢      # Count each in the joined input
        O     # Take the sum of those counts
         20-  # Subtract 20 from this
+             # Add the two together
              # (after which the result is output implicitly)
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 25 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
Ḣ;ɼȧZṚµ4¡FQḟ⁶,®f“~{}”¤Ẉ_/
```
A full program accepting a single argument as a list of Python strings which prints the result.
**[Try it online!](https://tio.run/##y0rNyan8///hjkXWJ/ecWB71cOesQ1tNDi10C3y4Y/6jxm06h9alPWqYU1dd@6hh7qElD3d1xOv///8/Wj0@vq4uPl6dS0e9prqurrYGzFIAAjRWNZylCwJ16rEA "Jelly – Try It Online")** Or see the [test-suite](https://tio.run/##y0rNyan8///hjkXWJ/ecWB71cOesQ1tNDi10C3y4Y/6jxm06h9alPWqYU1dd@6hh7qElD3d1xOv/Nzi08sT6w@1cD3dvKTZ/uHPao6Y1D3csBpJAZHa4HUj@/x8PBlw1CkBQg53SBQMQW9cORBpwccF0xegr6APV6QNpkHIgDeIBaUxdRghdClBdClBdSDx0XYZIdsWpOCDZZWJqhtMuC4QuRSAAqtNWUNAG6dLSAmm20dKyw9RlimGXpYU5sl0ZmYpYXGiC0Bbi4RkMUp9ZDNaWqAeinPz9vbFoQ/KZPhDUYKfwhEdiUnIKUF1qWnoGkMrMys4BUrl5@QVYdJkhtFXrKdSCjNeDhDqQqoXx0LUZw3VVwxKEnh4sXdTCBHV16@qQdekCA6QODCAqarFTECVI2oyQ0hVICmiPHtiCaj0gqIXx8KTG6rq6WiLTMNhrdXW4dFUj6UJ2oyEXAA "Jelly – Try It Online").
### How?
```
Ḣ;ɼȧZṚµ4¡FQḟ⁶,®f“~{}”¤Ẉ_/ - Main Link: list of lists of characters (the lines)
      µ4¡                 - repeat this monadic chain four times:
Ḣ                         -   head (gives us the head AND modifies the chain's input)
  ɼ                       -   recall from the register (initially 0) and apply & store:
 ;                        -     concatenate
    Z                     -   transpose the chain's (now modified) input
   ȧ                      -   logical AND (the concatenate result with the transpose, to get us the transpose of the chain's input)
     Ṛ                    -   reverse (together with the transpose this is rotate one quarter)
         F                - flatten (what we have left is the cover's inner characters)
          Q               - de-duplicate
           ḟ⁶             - discard spaces
                     ¤    - nilad followed by link(s) as a nilad:
              ®           -   recall from the register (the cover's edge characters)
               f“~{}”     -   keep only "~{}" characters
             ,            - pair (the two lists of characters)
                      Ẉ   - length of each
                        / - reduce by:
                       _  -   subtraction
                          - implicit print (a list containing only one entry prints just that entry)
```
[Answer]
# [Python 2](https://docs.python.org/2/), 66 bytes
```
lambda s:len(set((s[8:-6]*4)[::7]+' '))-21+sum(map(s.count,'_|-'))
```
[Try it online!](https://tio.run/##fZJBT8JAEIXv/RUjMWFb6CIIBRsxxpPGgwe9AZJVClTLtumWGFPav46zdbdtAJ3Ly7z59mXa3eg7WYe8t1@Op/uAbd4WDIQbeJwILyFETEau7cysvjlx3eGs1YSmadq9bktsN2TDIiLoe7jlSbs539k42n@t/cCDrmuAzyMYQ2PKG/Qj9DmJ2dccvW1CTFiGMfhIQMz4yiOOaRqQsHjlJXhEQQbEntgG0lkS9NBgQnhxon0Yj9WhNkigrQZt5eKBKPa55vfzoowdYO1Oi12UcWFodtqBDk47qBJClR1qyfZKFhQLiq11iu1Wua/nt7Xc/sA5zB2V7BkWTlsALclaljxybVk3JTs4zL0aDeu5a/@s2qFfwi/3D8@S8kUBMyrl7unpsYKrjTtYu9Ny9HXs7X2BU2@5WqP4H58ByoaHUcU6JZxSyGQU/f1fKJnuFHyp2VRfFqX6zjJt2naeI2v3jbyoXz87LQqxe9VNSwMzaRGWUqxMd0evIs3z7P8XJFfO87/YtMbiFt0f "Python 2 – Try It Online")
---
A slight improvement over [@xnor's answer](https://codegolf.stackexchange.com/a/205369/88546). Instead of removing spaces from the cover, we *add* spaces to the cover, and then subtract 1.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~106~~ ~~102~~ 80 bytes
```
lambda b:len({*(b[8:12]+b[15:19]+b[22:26]+b[29:33])})-21+sum(map(b.count,"-|_"))
```
[Try it online!](https://tio.run/##dYxLDoIwFEXnrqISB/2IhCJEGjXug6KhKtEEClEYGMBlsQA2VktNjAM9k3tfcs8rH9WlkJ5KN1xlSS5OCRAsO0vYYCiiFXNpTETk@swNx0Ipo4EpIfO8GHXIpi651znMkxKKxbGoZTW37PZgIaTK21VWMIXW0zD0DdB0//O90@rkox4MQ9/y/WzX6nS4A8YESz8wN3C4TtvwW51qxikBgBgVY/NijfH2W1Uv "Python 3 – Try It Online")
I know there's a shorter Python answer, and I know that this isn't the most optimal method. But I had come up with a solution which I golfed, and I'm posting it for the sake of completion. *-2 thanks to @Kevin and -2 thanks to OVS*. *A further -22 thanks to @mathjunkie*.
[Answer]
# perl -M5.010 -n -0543, 82 bytes
```
$i--for/\}$|^\{|~(?=[-_~]*$)/gm;s/^[-_~]+$|^.|.$//gm;$c{$_}++for/\S/g;say$i+keys%c
```
[Try it online!](https://tio.run/##K0gtyjH9/18lU1c3Lb9IP6ZWpSYuprqmTsPeNlo3vi5WS0VTPz3Xulg/DszVBkrr1eip6IMEVZKrVeJrtbXBGoP1062LEytVMrWzUyuLVZP//48HA65qBSCo4apR0NMDU0BQCxPU1a2r09X9l19QkpmfV/xf19dUz8DQ4L9u3n9dA1MTYwA "Perl 5 – Try It Online")
First, the penalty is calculated by counting `{`s which start a line, `}`s which end a line, and any `~` in the top and bottom lines. We then strip off the boundaries, and count the number of unique non-space characters; the penalty is added to that, to get the final score.
Reads a single cover from `STDIN`, writes the score to `STDOUT`.
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), ~~42~~ 35 bytes
-6 thanks to Bubbler.
Anonymous tacit prefix function. Requires `⎕IO←0` (0-based indexing).
```
-⍨/(,∘.⍱⍨6⍴5↑1){≢∪⍣⍺⊢⍵~⊃⍺↓⊂'_|-'}⌸∊
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qp/@jtgkG/3Uf9a7Q19B51DFD71HvRiDH7FHvFtNHbRMNNasfdS561LHqUe/iR727HnUtetS7te5RVzOI0zb5UVeTenyNrnrto54djzq6/qcBTXvU2weWXwM04tB6Y6AhQHuCg5yBZIiHZ/D/NAX1eDBQV1CvUQCCGvwMXTBQ50LRF6OvoA9WpQ9kQZQDWRARIAunPgW4PgW4PjQR7PbFqTig2WdiakbYPkUgAKvSVlDQhujT0oIYYKOlZUfYPksLc3T7MjIVceoDhTBEeWYxVF@iHoTh5O/vjVOfPhDU4Gdg1ZeYlJwCVpWalp4BZmRmZeeAGbl5@QU49VXrKdRCTNeDBT@QUYssgk1fNSJ16OkhkkktspSubl0dVF8dGMAka/EzoIpR3QkSAlujBzW9Wg8IapFFsPuvrq6WlHRdV0dIXzWKvjp1AA "APL (Dyalog Unicode) – Try It Online")
`∊` **ϵ**nlist (flatten)
`(`…`){`…`}⌸` apply the below function to each of the two groups identified by 1s and 0s in:
 `5↑1` take five elements from 1; `[1,0,0,0,0]`
 `6⍴` cyclically **r**eshape that to length six; `[1,0,0,0,0,1]`
 `∘.⍱⍨` NOR-table of that;  
  `[[0,0,0,0,0,0],`  
  `[0,1,1,1,1,0],`  
  `[0,1,1,1,1,0],`  
  `[0,1,1,1,1,0],`  
  `[0,1,1,1,1,0],`  
  `[0,0,0,0,0,0]]`
 `,` ravel (flatten)
 The following function will be applied to each multiset (0: edge characters; 1: inner characters):
 `'_|-'` a string; `"_|-"`
 `⊂` enclose it; `["_|-"]`
 `⍺↓` drop 1 element if the set is that of inner characters, otherwise drop 0 elements
 `⊃` get the first element; the above string or `" "` if gone
 `⍵~` remove those characters from the edge/inner set
 `∪⍣⍺⊢` if inner, then get the unique of that, else leave as-is
 `≢` tally that
`-⍨/` subtract the first count from the last count
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~49~~ 41 bytes
```
≔⪫Ｅ⁶Ｓ¶θＰθＢ⁶ ＷΦＫＡ¬№υκ⊞υ⊟ι⎚Ｉ⊖⁻Ｌυ⁻²⁰ΣＥ-_|№θι
```
[Try it online!](https://tio.run/##PY5Ba8MwDIXv@RXCJxkcGDvs0lOXUdhYRqDXgTGZSUxdO43tbdDMf91TmrF3eXoSn6R@VHPvlS1lH4IZHL5447BVEz4IeHZTisc4Gzcg5wLYu2NkF76r2mSjmWgScY2P/nsFGDAKX6OxGvBgbNQzdlqf9tYigW8@YuMTMUnAiZOgS2FcU@cnNJzgxmo1IxXdbXmjQsQn3c/6rF3UH9galwK@ajdEAmnp1ri/E3BM59vnrJYLE7Bduggw/E@7UqTMWcpqueb8s1QLkP7tulm9KkOpP@0v "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
≔⪫Ｅ⁶Ｓ¶θ
```
Input the cover.
```
ＰθＢ⁶ 
```
Print the cover, but immediately erase the border.
```
ＷΦＫＡ¬№υκ⊞υ⊟ι
```
Collect all the unique characters, which always includes a space, as we used that to erase the border. (I feel that I should be able to use `Ｗ⁻ＫＡυ⊞υ⊟ι` but Charcoal crashes when I try.)
```
⎚Ｉ⊖⁻Ｌυ⁻²⁰ΣＥ-_|№θι
```
Clear the canvas and output the popularity, adjusting for the extra space collected and the number of missing border characters in the original string.
I also tried counting the popularity by directly inspecting the string instead of printing it and deleting the border but it turns out that that costs bytes overall.
Previous 49-byte solution does not assume that edge characters only appear on the edge:
```
≔⪫Ｅ⁶Ｓ¶θＰθＢ⁶ ＷΦＫＡ¬№υκ⊞υ⊟ιＰθ↘ＵＯ⁴ ≔ΦＫＡ№{~}ιθ⎚Ｉ⊖⁻ＬυＬθ
```
[Try it online!](https://tio.run/##ZU7LTsMwELznKyyf1lJ6QxzoqaSqBCIQwRUpMmGVWDV26keLlNS/HjY0cOlcZmdXszNNJ11jpZ6mjfeqNfBolYFS9nCbswfTx/AWnDItCJEz/m440UGsszLqoHq6BJjlvf2eDZxxEqdOaWSwUzqggwpxv9EayPhsAxQ2kifmbC8IrIq@m1Vle1Di@nFpjwh3W3syr6rtAm1ePrSlPjd/aUvv67RLEh/SmedMiaV4oVE6oKH6zSikD7DFxuEXmoCfUCoTPTyhaQMVI9MyHua6Yj1NdZ1SXWfjkNJ5zEZG@KfhQqsZiU2ro/4B "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
≔⪫Ｅ⁶Ｓ¶θ
```
Input the cover.
```
ＰθＢ⁶ 
```
Print the cover, but immediately erase the border.
```
ＷΦＫＡ¬№υκ⊞υ⊟ι
```
Collect all the unique characters, which always includes a space, as we used that to erase the border. (I feel that I should be able to use `Ｗ⁻ＫＡυ⊞υ⊟ι` but Charcoal crashes when I try.)
```
Ｐθ↘ＵＯ⁴ 
```
Print the cover again, but this time keep only the border.
```
≔ΦＫＡ№{~}ιθ
```
Collect all the `{`, `~` and `}` characters.
```
⎚Ｉ⊖⁻ＬυＬθ
```
Clear the canvas and output the calculated popularity, adjusting for the extra space collected.
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), 326 320 319 305 bytes
```
int f(List<Character>[]c){int s=0,i=3;c[0].addAll(c[5]);for(;i>1;)S(50*i---55,c[0]);c[5].clear();for(;i<5;c[5].addAll(c[i++]))s+=c[i].remove(0)-c[i].remove(4);S(32,c[5]);for(;c[5].size()>0;i++)S(c[5].get(0),c[5]);return i-5-c[0].size()+s;}void S(int x,List c){c.removeAll(Collections.singleton((char)x));}
```
[Try it online!](https://tio.run/##xVdtb9pIEP4Mv2K@1S6Yd7fXI4lUpYr64e6@oPaqQ@i02AtsYrycd0lCCf3ruZldmxhwecmlPUUjYs/uzOzM88ysr9kt8@SMx9fhzaOYzmSi4Rrf1eZaRLVLGUU80ELGqlve0fa4Lnj7GTfIpEDxm1C4vjybDyMRQBAxpeB3JmJYlsul9K3STOPPrRQhTFHn9HQi4nF/ACwZK9csLQUTlvQH9AeBvOWJgnNYQqlUqtdhKOUNKDadRVwB2m59wJ0JWyjcV1ouX/39qlogq6pRv3rApy@pQCoPG9rs7ZdC7ae9ez@lb@/TVU9aD592ZYXqNOxvB8OGLXnYq12ttcv0zcej9z5pv6Whfvte2IezPUNZoIxQxjuuA5QEJUJhO1qJwlHmKGJHG6JMUDRKfHq2d2U7Y/vz@fLa70S1Qu2qS6EbMg0DZEPM7wy1HNco6nVLyrNLZA4LNE8uDHsucalTqHKNCavqdwb9N4Mu2iEGF9ooUFgLpMj2m0D0PIlBT/iamCBHQIQmtmppVGw2S@QsEUxz0IsZx40jmYCDC@AG3TW6@HMGHfypVFxKzlotrFqg@g3@oBpbBi4oXfZvBn0xSHOzc2ZKVClv6NoauraGrlM/azs1FoYOWVqbcGwrsur@9cC1FlflLPqdHMF7@BUujd3eQmk@rcm5ruG5Yx3FzjCojZz3aAWwq41AKAgdF42tHim80a65wF2SRp03quK83Q36DRPl@yhygr4/cLsYhdMVF82u23P8xmvheZ7vV2md26UVtSDiLHGyhWe@fbu2gdnEU6nKeUAJSPgUD@w0XC//2HG7PafdquY8GiNKfOWOe9HoUkl6JqDamGvcni5NuEGG8HzPRG43VFR3ZWZBzxTlvkqnBjxpkDqkyHJDCrfF44hrGTsOgcq9xwSuHsvlet1mrQDsJ@Tt6kfm7epg3q5Oz9tVmredc5@aQ0Rhu/kOhguNc1XJaE5rKa8fecKrRNsEiYvyFkIxGuET@r3DuQsCC8awL3EIZczhTuhJbglmSaArFsGU64kMFUK8Xo@lVYgNTYnOEhfVECGBN4B6vdNqwJApbuMk6pnSEperpjc0iU4Jn3HsLWG0gITPFV0U6KpArSfm9xqGkQxuUt46tpn4tpkQVxVUzmGzlODBVjHRS8RH6FqEHLWJGE/SB7zPWOMISWJ1LO/QetYkyNuFbWHeuW/85SwfqpTzzvfE62bDtW0DgYKeQ@qwWs6AxSFej7TWcrrl3/PNM/p@W8FjmgfPh5b9pwNt@08bOvafFtCGu4mIOHZLTI/XSkNt5nBvbA1MJIGcDgUWn0URRYOQMM2e8JCgf6eJI0AqjihZ4JUuvuWx4HHA3SpCLSv/Bookas1VkDweSg7OUZuQUKiEj1kSgpqxgKutLLTWVTBmN7i3Pt4hZ2aRpah1esP5DMwuXAMMFFYFc2BBSK@CDMiqRqiHJlAQnAUTmyDjMKTTZmSHCrQM5tYdwjyt6Y96Ra7nsfhnznMOwFETMULoU6JbmM2AIf6pHndMURXRDpvKeWxCVEHCdDBBfhgsS0sRgpKHhtiUm0AJUnJKPh3PNRBf70NY4/wzhMZRmXWNlMh/7CPyZwwWl2KMBF66EwwxCbt8bncNCLZb9rqQ4gzbtq1d42gWrZu8a4f4RpPP2sL3@rxpEYd6fWb0OOTmYOkXwtI/BpZ@DpZ5LHngF6DHVM5ke3pcnUxfbw3ByZf6GQW7SAu2e0f5UZXIXVgOZLro4nJcKpECPA6JC/jRnMtkz0AO7t3lk53iAt7bIdxkdD@dzbVhhcGrIZhJv@2U0GS2cn/tHZVvG0Xj8T9NveOnWK9gYtXr7/wqdE4ZLadNgJdv76f2ZMuqbQiYK9phBGS3MYuDYYYDnCgTmaAlmqmICpySBlMFuBhaXHzdi4u2/7/iYg2Il8EDkdvOYfqahvaJM773IgVPP2Es1atQdBmnyA@CL7uJt5ip7Z@52rZSzn/YW9vGLz@ztjskr9Jes@WEgvaIvVVSH2TwRrWetjy/Yvbj6fkF2/yAag13y5ZSMtxfts7PLVtar2eWy0zTn1it1eO/ "Java (OpenJDK 8) – Try It Online")
THANKS to Muskovets's suggestion of using List (-4), I also omitted the generic type in the second method (List instead of List< Character>)
Takes input as List< Character>[] and outputs an int.
It uses 2 methods (I'm not entirely sure how "allowed" that is)
See inside for comments and ungolfed and alternate solutions (including a single method one).
Interesting part: the ascii values for { | } are 123, 124, 125. That means that this part changes the popularity index by:
for each row: the left char minus the right char
{...} 123 - 125 = -2
{...| 123 - 124 = -1
|...} 124 - 125 = -1
|...| 124 - 124 = 0
It only works with only exactly the given possible inputs, none else (illegal inputs like }...{). Pretty lucky.
This was done with ArrayList, but possibly some other Collection with a shorter name or better methods would be better. Edit: indeed there is: Vector. updated. (Now List)
---
Takes input as String[]. Only one method.
# [Java (OpenJDK 8)](http://openjdk.java.net/), 267 261 bytes
```
int f(String[]c){int s=0,i=4;c[0]=c[0].replace("_","")+c[5].replace("-","");c[5]="";for(;i>0;c[5]+=c[i--].substring(1,5))s+=c[i].charAt(0)-c[i].charAt(5);for(;c[5].trim().length()>0;i++)c[5]=c[5].replace(c[5].trim().substring(0,1),"");return i-c[0].length()+s;}
```
[Try it online!](https://tio.run/##rVZRb9s4DH62fwWXl1pz7KRDPWDn5YZid8C93O2h2DAgMAbFURI1tmRYcntB6v71jpKdOJnTdDscClYQP5EiqY90bukdDWTBxO18/cTzQpYablEXVppn4UeZZSzVXAoVuz30hukT2i9oIMvYdYtqlvEU0owqBX9TLmDruk6rVZpqXO4kn0OOmHejSy6W0wRouVTEHnXSFS2nifmDVN6xUsEEtuA4zmgEMynXoGheZEwB@n7zB1qWdKPQztluL75dDE9IPbTwxQPuvrYCrTwcoTvt15Po57O2n1vtv@2pDg1w15ca4TbsxxfDhh/k4Sxa79Ftq/nrp2079LEN9fG5sF@udoGyQVmgLHtXpyglSoZCe6hEYSgVCu@hc5QVikYRv17tvvxYsfP1/P/RZ6KqEa1jE7ptplmK3SDYvW0tj1hg10TYMKpFW9VVMn2bxHjEtd2D3fIRm4um2nSVlrtjCcILWYLHhYY1uhjHuLyHK1x8n5j49jBvYI7wW1xa2FHTdTLlCYJed7/X9G8DkSbY3VX7zr@G30BZJzcbpVkeykqHBYI6E94sDRfetTV1nfrJBLDYm6ZkaxRqMh7yyVWcTsfJxPwLS1ZkNGXe4NtgOBgQP51GB8rAKmOjnAwGMUbjxfz3sVX46IAHQRKqaqaaHC6HESHKAkloZtO19sYkONxGpPFi70Gr3CNhxsRSrzyCjk2R7G1HcRwe7m4bDy@JDa9kuioF8MBmtPPmq7h@ckzW/3QVTHFwwmiUyjxnQrM51tLWxbzU0D7YZeyORjhZ0RX4EzBXx8aCCtB0zYDe0w3wBQipoVLo1R6xNvaxYv7@MiZ27xxV@OCtPVMM4r2L/Gj82qTc5OE2FicfZgf6k5MvZNHIcAqfCcO9l5iVYGzeDxWoAlVIvWNXQ9AobkCbMobUe1Z0ip@k0rCaaoiAijksJczlvTDtIQUzS8ly5DHoFYMgMl@d5m0@GM6q1vkBNSA4UlwRE3uXHNjkXOxHp0@KFjUWhhrAaLqCUlZi/gFafh0Ta3hAI9Jl/wwTbb@i71cW5@rPvNAbj5jh0MXSmBldeEezin1aNFzdJ2ib9ZcJbfhm@IcBUrFpWdN81q3lsQlesesArGdka3rQB@AD/jZxapwKhuqi1wyVWMps0fVCOyPOsfH0mBiNWhqaWbEv8EvzwlLjpZmx93ZmbvynUh8Urzc@bNHqp@8 "Java (OpenJDK 8) – Try It Online")
[Answer]
# [Perl 5](https://www.perl.org/) + `-p0 -MList::Util+uniq`, 55 bytes
```
s/^.{5}|.
.|.{5}$/$\-=$&=~y!~{}!!;""/ge;$\+=uniq/\S/g}{
```
[Try it online!](https://tio.run/##K0gtyjH9/79YP06v2rS2Ro9LrwbEUNFXidG1VVGzratUrKuuVVS0VlLST0@1VonRti3NyyzUjwnWT6@t/v8/Hgy4amLiVBxquGosLcwVgJSCiakZkNLPyFSs4dIFg3/5BSWZ@XnF/3ULDP7r@vpkFpdYWYWWZOZog8wDAA "Perl 5 – Try It Online")
[Answer]
# [PHP](https://php.net/), ~~104~~ 93 bytes
Original code from yesterday:
```
while($s<35+$c=ord($b[$t=$s++]))$p-=$t>5&$s<31?$t%6?$s%6?0&$i[$c]=1:$c:-$c:$c%5;echo$p+count($i)-$i[32];
```
[Try it online!](https://tio.run/##lZRtb9owEMff91NcKxcBWRIeCusaAu0mtKFVIG2V9oIxFIIh2WhsJUZVFSdfnZ0TBgJaWE/K@aScf/fP@WLu8VWrwz0OpgmuE8CEAnv0haDTMxqGLByHlLNQ@MG82B3f3d9DAdLuuD946H3q5vGPu2/9Xv9zyQLF8CNYRktnsXgG7oQC2AyERwErGH7gn5GPg8HX4ci@GGcmAU0eej2zC8s09TZARYEFjQQqjOgB46cJppQmLrgbF4xx2WPUjjMgZ0DO2MS7jOoJHb/I7UbHVaP5oo7r44xzNCk1AA0Z5TKSWuVye4/R@B8dH67fb3V4/vkuo3p1nGGiyUP/pn44E3cqJZ3NPSn9338WUj4GjO/paB5nxAYkWNvITgR9kse7OupHGfF6rgxjPV1JvJ6xNN0w9Nf6kWYWb/ft@PxtztBrJ@ZUpUppqNqxgZbk8ZtmPU7T5OT/8no/0vQlRrxlpP/6ceJsH770vuNu/NvRO6qzKmHvbPcYMxZSx/WKGQucCMikFJPIrliEK@fbw5FFHAyzm2TBGMe7I2TLuZfdIRtS9A4CJnbuF5dN6erJ8xe0SKJWvakR12bhtEgmQyJsEmnaqFQiXLeJaDcKKqXaIeKy2SERukqB@EPijuzqDXFvdHyIe9mwqOsxwjWXLQNRJH5Jx6x6bWStEqWPBlNVff1VupK7@gs "PHP – Try It Online")
  
  
Improved with a `mod`-expression from @Arnauld, cf. [his solution.](https://codegolf.stackexchange.com/a/205331/95500)
```
for(;$s<36;$s++)$p-=$s*9%56%37%9&1?!$i[$b[$s]]=1:ord($b[$s])%29%8>0;echo$p+count($i)-$i[" "];
```
[Try it online!](https://tio.run/##lZTfj5pAEMff768YzXJBLOCP09Mi3l0b05peNGkv6YO1BmEVWo/dAD40LPzrdgCrUe@0Nw@zQ2A/82V2drjLN7077nLQdbAtH@YU2LMXRdS5okHAgllAOQsiz1/Kg9nD4yNcQzqYjcZPw4@DIv7@8HU0HH2qGJAxvBDW4dparf4At4II2AIilwJm0DzfuyIfxuMvk6lZnuUmAE2cejW3sqHrah@gloEjGkaoMKQnjB866ELouOBuXDDG5YjROM@AggEFYxcfMuoXdPwk9zsdN632izo65xklNCGqAFVkKAqSeorSP2K0/kdHt3O71@F6pUNG/eY8Q0cTp/5N9bDmtiMEXSxdIbxfv1dCPPuMH@lon2fEGiSYW8tPBH1SxIc6mmcZ8bavNG3bXUm87bE03THU1@qR5hbv9x344m3BUBsX@jT7VAgtyx1raEkRv6nX4zRNLt6X1@uRpi8x4j0j/VePC2f79Hn4DXfjbUdvZZXNPjg62yPGggXUsl05Z4EVAplXYhKaNYPwzHnmZGoQC8N8kqwY4zg7ArZeuvkM2ZHCd@Cz6GC@2MyhG0wgGyTsNdvoq9UK4apJQqUrtdpS81bqXtfvSsSbkPmEhNOpWX/PAkcunipSoyt1@jWD2i4jvGqztR/JxKuouKEM5amxSTJR1HeylNtfUTONm78 "PHP – Try It Online")
  
## Explanation
* I was using the fact that char codes of intact top and bottom edges are `%5=0`, and left and right edges have char codes that are in sequence.
* I've now researched the char codes of the six edge chars a little better.  
Try `[45,95,124,123,125,126]%18%15`. There are also other options like `$c%29%8==0` and so on.
  
  
## Please Help Me Get Better
I appreciate any comments or suggestions.
[Answer]
## [Bash](https://www.gnu.org/software/bash/) + standard tools 121 Bytes
```
bc<<<$(sed '1d;$d;s/.//;s/.$//' $1|grep -o '[^ ]'|sort -u|wc -l)-$(sed -E '2,${$!s/(.)..../\1/}' $1|tr -cd '[~{}]'|wc -c)
```
Input is a file of the book.
[Try it online!](https://tio.run/##LY1BC4JAFITv/oonLKxCz8dGWaGHLv0KzchVMggM1@jgs7@@7VrfYeYwzEx9NZ21tc7zXESmbUCqJhNNZigh8iqIpA8V34b2CdiDLCo4Szb9MAK@@K0BHzH@2ngCuV6JSYSGoiROHFQqmv8T4wCo3UfxmWY34as6ttZeFgIuK3HkgA/7HTiDzTZ1Rt095AAXvg "Bash – Try It Online") (+6 bytes because input needs to be a string here)
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 174 bytes
```
//N(c)=p-=*s++!=c
p,v,i,j,k;f(char*s){char u[16]={};for(v=p=0,i=6;i--;N(95));for(j=4;j--;N(124))for(N(124),i=4;i--;)strchr(u,k=*s++-32)||(u[v++]=k);for(i=6;i--;N(45));s=p+v;}
```
[Try it online!](https://tio.run/##fZTfb9owEMff81eYbqhxflKaslVu0DTtYdOk9mF7A1ZlDgEDTaI4ZA9x8qcvO9u0lBTtHs7H3ee@Pl8kqLuitOt8/96kOMzd0OK2PQipkTuVw5yNsyWJSddRYXFcyxPtZ1eTRVg3JMkKswrzcOSwcEKY65J78/YGY1XYhAHZqNTVOMBYpnQIcKBgzMuCrgtz72zVpe71GAth7meVbS/CrZY5KgdSmYe5XZGme8dSutvHS3THy5hl3npqGDRLeYnUiFZesLR8pFm1LMzXeY5RbSDEy6hkVOcUNAvGCwIFTcWhSsoEyCBGDIj0NCNicWLbbDiBUa3YtsPLeXqJMVKxfIbsslw3BlS2FctyX6ToINgYhlR8ilhqVhmL9TjqVj4LRmqtz5eRZLUsucmdYOTIV6aYaBzmn13DJxgR9UO9NTEvhnxeutN5OYzn6YWDXq@AYwcl4LHsaIyme1QmZLt4611lxgGa@8gXwocDynBADEcPQhpCGnqJe0q/3n96UQpuJmeVBmBC2AjZAFkWoHeWNT2rdPvxw1FpzQY96OfXbz@gzLiEIg/854eH7z3IBxNv/SkU/aaxEMtktRaCbbY7IZ7SLO9BtYca6PbU48E3Oj6B6sOWPe@w66Y@bLxtAWqV1cfCidfV5@tkLIQnu2sPrNFxb6a2bf73gdv2HFQfofYvTXbRinfun8790vuP@Ac "C (gcc) – Try It Online")
Pretty standard: I count the number of unique characters in the cover (which is built up in a string), then deduct the amount of damage.
[Answer]
# [Erlang (escript)](http://erlang.org/doc/man/escript.html), 184 bytes
Just a port of Lyxal's Python answer. (Where's the unique function in Erlang?)
```
u([H|T])->[H]++u([I||I<-T,I/=H]);u(X)->X.
f(X)->length(u(lists:flatten([lists:droplast(tl(I))||I<-lists:droplast(tl(string:split(X,"
",all)))])))-21+length([I||I<-X,([I]--"_|-")==[]]).
```
[Try it online!](https://tio.run/##ZY5Bi4MwEIXv@RWS0wwapXt015713oMgQcJudANpKslID01/uw3WPe2DYd7HgzejvVVuFjp8e7PQxrYVhjZeJIrz0Mo8T9jF2H2JS9FVTSvxc4U@hX3Jpt1Y7Wb6hRWsCRTqySoi7WB444@/LVYFArLQIe5N/5NA3ri5Dos1BH3BGS@UtYgo04iPU34cOV7pi@SkEHyMgmPTDFJiuV2VcTBiJs4sSzK3@u4NaZiA8XEXi48ye0YWqzKrjvX8I7GLY2p6AQ "Erlang (escript) – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~101~~ 98 bytes
```
->s{a,*b,c=s.lines;(b.flat_map{x,*y,z,_=_1.chars;a+=x+z;y}|[' ']).size-22+(a+c).tr('{}~','').size}
```
### 100 byte version because TIO doesn't support ruby 2.7
```
->s{a,*b,c=s.lines;(b.flat_map{|i|x,*y,z,_=i.chars;a+=x+z;y}|[' ']).size-22+(a+c).tr('{}~','').size}
```
[Try it online!](https://tio.run/##fZJvb5swEMbf8yku3TQIf5wma7tuGd06ddKmSsuL9V2aIYeY4JUEFBMpCZivnp0JBLRkOwk93N3Pjw/s1Xq63Qfu3rkTGbXNqe27gkR8ycTQmJIgoqm3oEmW83xjm1t7Z3suJ35IV2JILXdj7YZbmY910CddIviOOYOBZVDL75J0ZeiZLHRb1w8tuX@4f7onjPqhp3YgaexR9FovX5Q/77ifnpeSCBYxPzXefAj4SqRdgttjElH1rtbCLAbENQBuQwwuGHx8SQhx@hNTbeWH8SKxgY@xoLbgigwU6cIc8WDMJ1gCSNapgIvR4wVmLBKsVWSbBGdgM3iVxdKGeZzi21yW5HKmqUfzvK8/HjwPVYWWq9X5eXHK0C61I/zcgx62e6iKQlUZ6hEeNDBUMFRwK6vgfsv51@vPLeer65u/nW8buIOBbQvAUrBpqjUfTfPuCF@fOL@/fdd2DnmnGeOqoZ@@ff@pMC5KmhIlX0ajx4ZuTd3DyM/L6SfSqT/DNgvmIQr//RKhLJZx0sA3DZ0RkMqMHH4biqyzin57hLP62AipT0/WRccpCoQd/MaijENDnpcKcQatQ1cVdCWlXYZXlsg6O70hWVHI/1@ncuyi@BectWAcpL//Aw "Ruby – Try It Online")
]