[Question]
  [
# The 21 Hairstyles of the Apocalypse
Given a a list of numbers between 1 and 21 (or 0 and 20) output a "stitched together" drawing of the following faces (***see rules for stitching information***):
```
     ___           ,,,           ooo           ===           +++           ###          -*~*-     
    (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)     
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-
                                                                                                  
     ***           |||           _/7           )))           (((           xxx           @__      
    (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)     
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-
                                                                                                  
     ((_           >X<           '*`           ^^^           )|(           \|/           &&&      
    (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)     
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-
```
Each, unique face listed on a new-line (the # is the integer ID for the face):
```
     ___      
    (o o)     
ooO--(_)--Ooo #1
              
     ,,,      
    (o o)     
ooO--(_)--Ooo #2
              
     ooo      
    (o o)     
ooO--(_)--Ooo #3
              
     ===      
    (o o)     
ooO--(_)--Ooo #4
              
     +++      
    (o o)     
ooO--(_)--Ooo #5
              
     ###      
    (o o)     
ooO--(_)--Ooo #6
              
    -*~*-     
    (o o)     
ooO--(_)--Ooo #7
              
     ***      
    (o o)     
ooO--(_)--Ooo #8
              
     |||      
    (o o)     
ooO--(_)--Ooo #9
              
     _/7      
    (o o)     
ooO--(_)--Ooo #10
              
     )))      
    (o o)     
ooO--(_)--Ooo #11
              
     (((      
    (o o)     
ooO--(_)--Ooo #12
              
     xxx      
    (o o)     
ooO--(_)--Ooo #13
              
     @__      
    (o o)     
ooO--(_)--Ooo #14
              
     ((_      
    (o o)     
ooO--(_)--Ooo #15
              
     >X<      
    (o o)     
ooO--(_)--Ooo #16
              
     '*`      
    (o o)     
ooO--(_)--Ooo #17
              
     ^^^      
    (o o)     
ooO--(_)--Ooo #18
              
     )|(      
    (o o)     
ooO--(_)--Ooo #19
              
     \|/      
    (o o)     
ooO--(_)--Ooo #20
              
     &&&      
    (o o)     
ooO--(_)--Ooo #21
```
The face is as follows:
```
    hhhhh     
    (o o)     
ooO--(_)--OooS
```
Where `h` is the dynamic apocalyptic hairstyle and `S` is the potential stitching hyphen.
---
# Examples
**Input:** `[1,2,3,4,5]`
**Output:**
```
     ___           ,,,           ooo           ===           +++      
    (o o)         (o o)         (o o)         (o o)         (o o)     
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-
```
---
**Input:** `[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]`
**Output:**
```
     ___           ,,,           ooo           ===           +++           ###          -*~*-          ***           |||           _/7           )))           (((           xxx           @__           ((_           >X<           '*`           ^^^           )|(           \|/           &&&      
    (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)         (o o)     
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-
```
---
**Input:** `["Fraggle Rock"]` / `[22]` / `[-21041024]` / `[22,23,24,25,26]`
**Output:** `Nobody cares.`
---
**Input:** `[1,1,1,1]`
**Output:**
```
     ___           ___           ___           ___      
    (o o)         (o o)         (o o)         (o o)     
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-
```
---
# Rules
* Preceeding and trailing newlines/spaces/hyphen are fine.
* Faces can occur more than once in the input.
* If there is an invalid number in the input you may have undefined behavior.
* The stitching:
	+ The stitched faces will be concatenated by a single hyphen on the bottom (3rd) line.
	+ The faces will all be on a single line (unlike the first drawing).
* Input can be 0 or 1 indexed, with 20 being the max for 0, 21 for 1.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), lowest byte-count wins.
  
[Answer]
# [Japt](https://github.com/ETHproductions/japt) [`-R`](https://codegolf.meta.stackexchange.com/a/14339/), ~~122~~ ~~117~~ ~~113~~ ~~110~~ ~~109~~ ~~107~~ ~~105~~ ~~104~~ ~~103~~ ~~102~~ ~~100~~ 99 bytes
1-indexed, with index wrapping. I've followed the spec here, which requires a hyphen *between* the last line of each face, rather than the test cases, which include a hyphen *after* the last line of each face.
```
[Umg"@__((_>X<'*`^^^)|(\\|/"i"&_,o=+#*|)(x"m³ ò3 i7"-*~"ê)iA"_/7")¡"(o o)"Ã¡"O--(_)--O"ûoDÃq-]ûD m¸
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&flags=LVI&code=W1VtZyJAX18oKF8%2bWDwnKmBeXl4pfChcXHwvImkiJl8sbz0rIyp8KSh4Im2zIPIzIGk3Ii0qfiLqKWlBIl8vNyIpoSIobyBvKSLDoSJPLS0oXyktLU8i%2b29Ew3EtXftEIG24&input=WzEsNyw4LDEwLDIwLDIxXQ)
```
[                                             :Construct an array of 3 elements
Umg"@.../"i"&...x"m³ ò3 i7"-*~"ê)iA"_/7")     :FIRST ELEMENT (F)
U                                             :  Input array
 m                                            :  Map
  g                                           :    Index into
   "@.../"                                    :      Literal string
          i                                   :      Prepend
           "&...x"                            :        Literal string
                  m                           :        Map
                   ³                          :          Repeat 3 times
                     ò3                       :      Split into chunks of 3
                        i7                    :      Insert at 0-based index 7
                          "-*~"ê              :        "-*~" palindromised
                                )             :      End insert
                                 iA"_/7"      :      Insert "_/7" at index 10
                                        )     :  End map
¡"(o o)"Ã                                     :SECOND ELEMENT (S)
¡                                             :  Map input array
 "(o o)"                                      :    Literal string
        Ã                                     :  End map
¡"O...O"ûoDÃq-                                :THIRD ELEMENT (T)
¡                                             :  Map input array
 "O...O"                                      :    Literal string
        ûo                                    :    Centre pad with "o"
          D                                   :      To length 13
           Ã                                  :  End map
            q-                                :  Join with "-"
]                                             :End array
 ûD                                           :Centre pad each to length 13 with spaces (T will always be at least 13 characters long)
    m                                         :Map
     ¸                                        :  Join F & S with spaces. Split T on spaces, creating a singleton array which gets cast back to a string on output
                                              :Implicit output, joined with newlines
```
[Answer]
# [Python 2](https://docs.python.org/2/), 209 bytes
```
def f(a):s=t=u='\n';i=0;exec"s+=(\"_,o=+#-*|_)(x@(>'^)\\&_,o=+#**|/)(x_(X*^||&_,o=+#~*|7)(x__<`^(/&\"[a[i]::21]+'*-'*(a[i]==6)).center(14);t+='    (o o)     ';u+='ooO--(_)--Ooo-';i+=1;"*len(a);print s+t+u[:-1]
```
[Try it online!](https://tio.run/##Lc7RSsMwGAXga32KUGH5/6RxazcUEiO@wW6Fpq1lpjMgyWhTmBB89doyz9U539W5/MSv4Mt5/rQ96aFDOeqoJ02Np8rpnbJXe8pGrsFkbR40fxAstQjXN3ilDRqzuSljabtoC@@sSekff1l6XrF9@WhguzFZ1VWulrIsak6ZoAzWrfUT4uPJ@mgHKA6oIteULIFAAq6FUDUtFsJRCGhRiGMIYrnHdaEy9m398ltdBucjGXnkUyVFUc99GIgjzpOh82cLe5T3dz3chsvLIt8jzn8 "Python 2 – Try It Online")
0-based indexing; nothing especially clever here, just data accessed via slicing and using exec instead of a loop.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~103~~ 102 bytes
```
Ｅ²⪫Ｅθ⎇ι(o o)⪫×²§ -⁼λ⁶§⪪”|″:αuxkτT↷K[ï�↔ς↨?◧BZ@C←↑⊞Ａ⧴M✂↶ºKf÷H#S⦃J&≔⁰∧5À³≕r‹▷”³λ× ⁹Ｍ⁴←⪫ＥθooO--(_)--Ooo¦-
```
[Try it online!](https://tio.run/##TU9NS8NAEL37K5YNxNlkltoq9TOiBw@KpYI9CG2zLnXFhTXTprFECP71dWwFndPMe/PezFu82XpBNsT4UPuqgZFdwgDFHflq269QTFxd2foTPAoJJEjJX37i3936Z/u6ua1eXAtSaOZuVh82rCGgGCql/tjHZfANSGMMIhJRURR5nidJkn1lXF3Xmd4xKwCgbdsrYwDM5dPFfvZclqXqYDbremma8oVDdg1qa777QQpGTxk43xvRxsERirN799rwvIv1P48kGmsNRmk9JpJsIrVkaYzT6QEOsT/A/sl8HvUmfAM "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｅ²⪫Ｅθ
```
Loop over the input twice. Each result is then implicitly printed on its own line.
```
⎇ι(o o)
```
On the second loop, just generate the eyes.
```
⪫×²§ -⁼λ⁶
```
Wrap hairstyle 6 in `-`s, other hairstyles in spaces.
```
§⪪”|″:αuxkτT↷K[ï�↔ς↨?◧BZ@C←↑⊞Ａ⧴M✂↶ºKf÷H#S⦃J&≔⁰∧5À³≕r‹▷”³λ
```
Extract the three hairstyle characters from a compressed string.
```
× ⁹
```
Insert nine spaces between each hair or eyes.
```
Ｍ⁴←
```
Move 4 spaces left.
```
⪫ＥθooO--(_)--Ooo¦-
```
Print the rest of the faces, joined with a `-`.
[Answer]
# [R](https://www.r-project.org/), ~~413~~ 391 bytes
Thanks Giuseppe for 22 less bytes and getting this under 400 bytes.
```
function(s,n=length(s)){I=intToUtf8
U=utf8ToInt
R=rep
K=cat
a=U("_,o=+#^*|&)(x")
b=c("@__","((_",">X<","'*`","",")|(","\\|/","","-*~*-","_/7")
s[s==7]=22;s[s==10]=23;s[s==18]=7;s[s==21]=10
for(i in s)K(I(c(rep(32,4+(i!=22)),"if"(i<14,R(a[i],3),U(b[i-13])),R(32,5+(i!=22)))))
K("
",I(R(c(R(32,3),40,111,32,111,41,R(32,6)),n)),"
")
K(I(40+R(c(x<-c(71,71,39,5,5),0,55,1,rev(x),5),n)[-(14*n)]))}
```
[Try it online!](https://tio.run/##VVBhS8MwEP2eXzEj6KW7YtOmdm6N@LXsW1lB6GrdyqoBSaXtZOD0r9frJoLhePcud@/lSDvUsTvUe1v1prHQodVvO/vSv0InxGeije1XTdbXM5bpPaVVk9iepbrdvbOlrjY92@gMeImNnl4@OccrAQcu2FZXwB/KkiMHGPH@MSa8dp4JKcQRCNfr4825dp1vx6Vc3kSk7vJO66jQvr84UekRD375rNDRmfqyoBarmxbMxNhJJ5aQQAW0GwQ@qimYC/IQArmpOZhYKkxhk5sCA4EZbHPjyqCgfjrOh3/zdNgSOOOYQEqGpzZJlIdSSqRiTEqedbdkYMdHGB9lCShvOqoOsVtBJJEiuMMQQ4EehiFKbHcfcBDjhRW5C1I5VtAaX0MNch6JBX0r8LUluxpmc6n@38hw7ksx/AA "R – Try It Online")
[Answer]
# JavaScript (ES6), ~~200~~ 199 bytes
Expects 1-indexed input.
```
a=>[1,0,2].map(y=>a.map(n=>s=y&2?'ooO--(_)--Ooo':`    ${p='( -'[y*n-7?y:2]}${"o o___,,,ooo===+++###*~****|||_/7)))(((xxx@__((_>X<'*`^^^)|(\\|/&&&".substr(y*n*3,3)}${y?p:')'}    `).join(s[3])).join`
`
```
[Try it online!](https://tio.run/##bZDRboJAEEXf/Qqjhp2FWXRBRUkX@we@NgFdqNVGYxkitpGI/jpdbZ9aZ15ucm/Ozcwu@8rK1WFbHEVOb@tmo5pMRbHEAXoL9yMroFJRdhe5ikpVWd6MEc2FAM2FmBOxMG2b6Z0LxaAtWFzZuQhmVegtLr1zh9qktUZEIlJKOY7T7Xbtq22mrmvdDzjnAHA6nZ61BtDRyxOz0@VyyWtIkrpvWVbHLT9fy@MBDNn20eeGW82KkHF2uVWn3N3RNocy9hf8R6ettFlRXtJ@7e7pHTZgTvLQxyGOTKb1z7vvX4clOXuQ/eXgGIMHrAlOUQ5QGp6H0kc5fFQ4QjlGGaCcoJyiZ759a2@@AQ "JavaScript (Node.js) – Try It Online")
### Commented
```
a =>                              // given the input array a[]
  [1, 0, 2].map(y =>              // for each row y:
    a.map(n =>                    //   for each integer n in a[]:
      s =                         //     let s be the content of this row
        y & 2 ?                   //     if this is the 3rd row:
          'ooO--(_)--Ooo'         //       use a hardcoded string
        :                         //     else:
          `    ${                 //       append 4 spaces
            p = '( -'[            //       append and save in p:
              y * n - 7 ? y : 2   //         '(' if y = 0 (2nd row)
            ]                     //         ' ' if y = 1 and n != 7
          }${                     //         '-' if y = 1 and n = 7
            "o o___,,,ooo(...)"   //       append the middle pattern (NB: truncated string)
            .substr(y * n * 3, 3) //       which is always the eyes if y = 0
          }${                     //
            y ? p : ')'           //       append p for the 1st row or ')' for the 2nd row
          }    `                  //       append 4 spaces
    ).join(s[3])                  //   join with the 4th character of s (space or hyphen)
  ).join`\n`                      // join with line-feeds
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 164 bytes
```
->a{puts a.map{|i|j="_,o=+# *| )(x    ^  &"[i];(j<?!?%w{@__ ((_ >X< '*` -*~*- )|( \|/ _/7}[i%11-2]:j*3).center(14)}*"","    (o o)     "*k=a.size,"ooO--(_)--Ooo-"*k}
```
Zero indexed. [Try it online!](https://tio.run/##FYzbDsFAFADffcWxUnZXz2EREtryB14lVaukTVphBY1Lt369dJ4mmWRuxeFdp36NQVxei8cdYjrH19JmNveZdo3f74C0IPgL/uwAuizMogXPvWV76TzLldbAuYZg40FP7gHlVyIIy2FrB6AHsyrMHKVwFM1zORZ0TC6P5MbVRFSSMZc1V27AiEaAyZMf0z37JC4zZo3ItUBcG4P/UtVpOCSaRq00nBGpcSNqQjQaRvUP "Ruby – Try It Online")
All the difficult stuff happens on the top line.
`"_,o=+# *| )(x ^ &"` contains all the hairstyles with 3 identical characters, from which we select the `i`th character, `j`.
if `j` is not a space, the following expression returns 3 copies of the character. If it is a space, we select the correct hairstyle from between the `%w{}`. The "odd" hairstyles are numbers 6,9,13,14,15,16,18,19 and `i%11-2` gives a perfect hash to `0..7`
```
j<?!?%w{@__ ((_ >X< '*` -*~*- )|( \|/ _/7}[i%11-2]:j*3
```
All that remains is to pad to 14 spaces (centred) and print an appropriate number of middles/bottoms.
[Answer]
# Java 8, ~~273~~ ~~263~~ ~~254~~ 247 bytes
```
a->{String p="",q=p,r=p,s="    ",t="ooO--(_)--Ooo",u="(o o)",z;for(int i:a){z=i==7?"-":" ";p+=s+z+"___,,,ooo===+++###*~****|||_/7)))(((xxx@__((_>X<'*`^^^)|(\\|/&&&".split("(?<=\\G...)")[i]+z+s+" ";q+=s+u+s+" ";r+=t+"-";}return t.join("\n",p,q,r);}
```
-16 bytes thanks to *@ceilingcat*.
[Try it online.](https://tio.run/##lZDLUtswFIb3PMWZk5kgRccGhUsAI2DXVWHRTWcwcVVjGIUgObZM08Tuq6dy8Asg6SzO7f8130J/6Gjx/LbLl7qu4bs2dnsAYKwvqhedF3DfpwA/fGXsK@QsdB6fQPMklLsQ4dVee5PDPVhQsNPRzXaYLhUirVRJVYhaYS@E5BU69xBFLONR9OAcUqOQOXAcaZO8uKr3AHOl@XajjFKzW4zwCgGTUqhabARmWUZEzjmllBBiNBpN/k3Cads2O5pxzhlj6/X6LssYy25@Xh9Ofs3nc96yNG2PxuMxxnW5NJ4hu71WafotjmOO/NE8BfFa9E6r3qkZkkooL8Ifkq4qfFNZ8PHCGcswtUglrajiSbdLPmGUze9lgDEw@XDmGd4DVPaJZI9uIPq39sV77Bofl6Hll5bZOGe2@AN7xttjkjSlEzrt@J72V1bojM5pRhd0STIUJckpyROSpyTPSJ6TnJG8IHlJ0@OvqO/vsNAddLv/)
**Explanation:**
```
a->{                       // Method with integer-array parameter and String return-type
  String p="",q=p,r=p,     //  The three rows, starting all as empty Strings
         s="    ",         //  Temp-String of four spaces for the first and second rows
         t="ooO--(_)--Ooo",//  Temp-String for the third row
         u="(o o)",        //  Temp-String for the second row
         z;                //  Temp-String, uninitialized
  for(int i:a){            //  Loop over the input-array
    z=i==7?                //   If the number is 7 (edge-case):
       "-"                 //    Set temp-String `z` to "-"
      :                    //   Else:
       " ";                //    Set temp-String `z` to a space " "
    p+=                    //   Append to the first row:
          s                //    Four spaces
          +z               //    Append the temp-String `z`
          +"___,,,ooo===+++###*~****|||_/7)))(((xxx@__((_>X<'*`^^^)|(\\|/&&&"
             .split("(?<=\\G...)")[i]
                           //    Append the correct hat based on `i`
          +z               //    Append temp-String `z` again
          +s+" ";          //    And append five spaces
    q+=                    //   Append to the second row:
          s                //    Four spaces
          +u               //    The head
          +s+" ";          //    Five spaces
    r+=                    //   Append to the third row:
          t                //    The hands and bodies
          +"-";}           //    And the stitch "-"
  return t.join("\n",      //  Return a newline-joined String, of
                p,q,r);}   //  the three rows
```
[Answer]
# [Python 2](https://docs.python.org/2/), 204 bytes
```
i=input();l=len(i)
for l in[' '*4+' -'[x==6]+"_,o=+#**|_)(x@(>'^)\\&_,o=+#~*|/)(x_(X*^||&_,o=+#**|7)(x__<`^(/&"[x::21]+' -'[x==6]+' '*5for x in i],['    (o o)     ']*l,['ooO--(_)--Ooo-']*l:print''.join(l)
```
[Try it online!](https://tio.run/##Tc3NasMwDMDx@57CpBDLjrwu6Rdkddkb5DpIHO@yUhdjhZJCBqGvntoMxnQSP4T@w894oVAti9MuDPcRxLvX/juAEy9nujHPXGg543JbcKZ4O2m9N0VmkXSxknK2AqYPOPFedF3@qw85r6Na@JT9POd/p4eE9vjVwzrP2qmuq9L8f5oqu9ScYpM5g7EbB4iRSAvjRvqIRI1SYIVSDZFKWA83F0bOX6/kAnixLO0blljhBre4wz0ezBM "Python 2 – Try It Online")
[Answer]
# [R](https://www.r-project.org/), ~~247~~ 242 bytes
```
function(a,n=length(a)){for(i in a)cat(format(h[i],,,,"c",14+!20-i))
cat("
","   (o o)     "*n,"
")
cat("ooO--(_)--Ooo"*n,sep="-")}
"*"=rep
h=readLines(,21)
___
,,,
ooo
===
+++
###
-*~*-
***
|||
_/7
)))
(((
xxx
@__
((_
>X<
'*`
^^^
)|(
\|/
&&&
```
[Try it online!](https://tio.run/##VY5RS8MwFIXfz6@IKdSbNGF2bEyKEX@AsFfBrbHUdg1oMroKBat/vaawF8/Dvdxz7uV@/dyauf3y9eCCp0p589H409BRJcR3G3pyzHlWiboaKI6fsXWv7qiieM1Vvslu1nfaCYFlg4MrzhijwIJgi7j0KrrXOIS91mSF1vsQlujSnA3XXPyAS2765owu1ur92fnmQmqdC1hrEb8hhABjDLIsQ5Ik0PJXakgpMU0T7GoHESmICOM44ileEVk8vjzgVr6hLEuIiXCYVkjTdG4pL3ZXqoOPfC3dF/nmv5Nvi0gw/wE "R – Try It Online")
Now, trying to bring R to a more manageable byte count...
Since doing character manipulations in R is so hopelessly verbose, I settled on listing all face and hairstyle patterns completely as is.
For pretty-printing the hairstyles I use `format` function with `justify="centre"`. Unfortunately, we need to use an extra padding character for `i==20` because `format` calculates padding as if the backslash was escaped, like `\\|/`.
The current version does *not* use trailing hyphen.
Edit: Credit to JayCe for -2 and Giuseppe for -3 bytes.
[Answer]
# [Red](http://www.red-lang.org), 333 319 bytes
```
func[x][h: copy[]i: 0
foreach[k l m]{___,,,ooo===+++###   ***|||_/7)))(((xxx@__((_>X<'*`^^^^^^)|(\|/&&&}[alter h
pad pad/left either 7 = i: i + 1["-*~*-"][rejoin[" "k l m" "]]9
14]foreach y x[prin h/(y)]print append/dup copy"^/"{    (o o)     }l: length? x
print take/part append/dup copy""{ooO--(_)--Ooo-}l 14 * l - 1]
```
[Try it online!](https://tio.run/##ZU/RaoNAEHz3K4YLpKfmuJimhEht@weBPhUul6vEs9pY7xADhpj@ur3YvJTusuww7OzONjobXnUmpJfHQ36s96KTooixN/YkZBlj7uWm0em@EAdU@JJnpdRsNjPGJEkShuFkMgEQBEHf94qvfN@nlHZd96IUperp7fEueN@N4fd02/PpdHoRadXqBoVn0wyueKXzFrpsC8eukMDdLREiEoQF3wEjUjT605S1ICCjDdelXHvRUt7c4YRO2KasUXB68uUVtkit1XXGs6MdHyI7Ts7OLaiB8a8AlypGpeuPtnhG5/2q2vSguU2b/3pyNmbDGFU@Yxtj2KVCtETgHDFEcsghIowpb6sI8UZygXss8fCXXiNyowtEayzmWMnhBw "Red – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), 163 bytes
```
->a{puts a.map{|i|(i==6?"-*~*-":i<9?"_,o=+#~*|"[i]*3:"_/7)))(((xxx@__((_>X<'*`^^^)|(\\|/&&&"[3*i-27,3]).center 14}*"","    (o o)     "*k=a.size,"ooO--(_)--Ooo-"*k}
```
[Try it online!](https://tio.run/##PY7NDsFAFEb3nmJyJXVn9F6qoiEGb2ArqXaUtMlEGPGTFMOrFxvf6pyczXe@be9NpRuaFc/T7XoRBR@K09Nbj1br0RxIvRXBxE7HczCh0932W3lIbabiCZheIqVExLquF8Ygmtlq2lGbPM@lx/Xa94IggDRWlgZJGGeSd@XxWp5FNHwpgBDEd@iEkz8QoPa64It9lCE4tyRCI4mWztG3vJoq7TOPstbvZ6tKE@Yo/ls0ZB70s@YD "Ruby – Try It Online")
0-indexed. I fiddled with Level River St's [answer](https://codegolf.stackexchange.com/a/164572/78274) and found another approach to encode the hairstyles, apparently of similar golfiness. Here, we treat the "longest" 5-char haircut as a special case, trivial patterns in the first part of the list are encoded by 1 char each, and in the second part all 3-char patterns are listed literally, no matter - are those chars distinct or not. Finally comes the monkey-face boilerplate.
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~210~~ 212 bytes
-4 bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat). (It grew again when I fixed a bug that the original code had.)
Pretty straight-forward.
```
#define r(s)for(i=!puts("");i<n;printf(s,c,"___,,,ooo===+++###*~****|||_/7)))(((xxx@__((_>X<'*`^^^)|(\\|/&&&"+x*3,c=x^6?32:45,x=l[i++]));
x,c,i;f(l,n)int*l;{r("%5c%.3s%-6c")r("    (o o)     ")r("ooO--(_)--Ooo-")}
```
[Try it online!](https://tio.run/##bZDdboJAEIWv5Sm2EO0sHKoLAlqk7Rt420Rl21BpSCxrgCYkYl@drib971zNmS9z5idzn7Os762nbV6UW1ZRzXNVUZFc7F@bmkyTx8WijPdVUTY51chgSikBKKWSJHEcx7Is@83W0XWdHEeccyJq2/ZOSiJ5c7@4tB/SNOUdrdfdeDQamU5r@8iSNg1vfe96GqBNdqvCcTacx0arRxRxTjuUXM@0d/GhInMYZMMrvx66YWZyrZkOUkzxU8LOJaWWrkuSu@5SKdfkx163s5fHoiRuHIzBSTXbuhGrDUvYYQIBDz6mx/iLeb8YAoSIMMMcQhcFhAfhQ0whAogQIoKYQczhTb7b@H9tghM3BjmdVwAL9KmDzxd/AA/ME/8SHyz6CY79Ow "C (gcc) – Try It Online")
[Answer]
# [Runic Enchantments](https://github.com/Draco18s/RunicEnchantments/tree/Console), 313 bytes
```
B6?>8b2*B0il2)?\B" "9a2*
{" ___ "D
{" ,,, "D
{" ooo "D
{" === "D
{" +++ "D
{" ### "D
{"-*~*-"D
{" *** "D
{" ||| "D
{" _/7 "D
{" ))) "D
{" ((( "D
{" xxx "D
{" @__ "D
{" ((_ "D
{" >X< "D
{" '*` "D
{" ^^^ "D
{" )|( "D
{" \|/ "D\
{" &&& "D{
{"    " LLRB͍!{
"-(_)--Ooo-"{*@\~4-:l͍e,:{$ak$"    (o o)     "{*$ak$"ooO-"
```
[Try it online!](https://tio.run/##Pc7NasJAEAfwu08xbiTuTrJoYmtVjErwKAiePIRsbelBlA4IQmAX38BH85liEifO6cd8/JnL9f/4W5bpeLmY/MSYDo/nWC2zVICYHmLsWAHGGBDrWmEYsoiIlSQJKwgClud5L2m8oX71EJGnzjmWGXyxlFIsKSWrKArW6v2BlK0W@zmrj9@sPM/bPNemZG5QKavp@35FW7MqAZvNLn3cu7YjtDRK6y2RFhZX2e1Dz86P@184s73DqdesSwJS0BxabLpEWy3KMoogimEE0ecT "Runic Enchantments – Try It Online")
Reasonably compact in terms of compressing the strings and re-using segments where possible as well as using the input values as direct jump offsets when `B`ranching.
If excess trailing space is allowed, this can be shortened by 2 bytes by omitting the `4-` on the last line. +2 bytes for a `1-` if the final `-` is intended to not be there (matching spec, violating examples).
The chunk, `" (o o) "` is annoying impossible to compress, as constructing it using things like `" "4*` ends up being exactly the same number of bytes.
Passing inputs >21 do fun things. E.g. [a single 22 gives a close shave](https://tio.run/##Pc5LCsIwEAbgvaeIqdRk2qAE8VGsSnEpCK5clMYHLsTigCAUEryBR/NMta1TZ/Uxj595PO/Xc1km4@VietKQDK@5lss04YzPjho6ljNjDOPrWmEYkhCRFMcxKQgCkud5Pyl4gfr1AICmzjmSGUxIUkqSEIJUFAVp9f9AiFaL/ZzUhwMpy7I2z7UpqRtUSmv6vl/R1qyKs81ml3zeXdvhShip1BZRcQur9DVSUf55X8LI9o63XrMukKFkzaGFpou4Vbwstf4C).
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~187~~ 171 bytes
-16 bytes thanks to mazzy
```
''+($args|%{($x=' '*4)+($y=' -'[$_-eq6])+("___,,,ooo===+++###*~****|||_/7)))(((xxx@__((_>X<'*``^^^)|(\|/&&&"|% s*g($_*3)3)+$y+$x;$z++})
"$x(o o)$x "*$z
"ooO--(_)--Ooo-"*$z
```
[Try it online!](https://tio.run/##PclBTsMwEIXhfU4xcqbx2I7VTpImrSCIG3SLBMRlkZZFJUOzwG1drh4CCOZtRt//5j/64/DaHw4j7trLKKUhfDnuhzi7EIZWgtSVmuw0vVY@orP9e/08iXDO5XnuvW/b1hiTpqn@1NPFGN28UUoRUQjh3jkid/dwK/V223WdivQU51mWiTiDQe8JnS5VqQyeDIYbPBtzVYnAQB68wgBC4zkR3m@sJaes3Xhvv228JhnuYAEMBZRQwRLqRIgfbGAFa@CpMXABXP4FroCXwDVwA7wCXkOx@G@/G78A "PowerShell – Try It Online")
0-indexed, has a trailing hyphen.
Unrolled:
```
''+($args|%{
    ($x=' '*4) + ($y=' -'[$_-eq6]) + 
    ("___,,,ooo===+++###*~****|||_/7)))(((xxx@__((_>X<'*``^^^)|(\|/&&&"|% substring ($_*3) 3) +
    "$y$x ";
    $z++
    })
"$x(o o) $x"*$z
"ooO--(_)--Ooo-"*$z
```
Nothing too fancy. Only the first line has some decent logic in it. It indexes into the hair string by using the `$current_entry_value*3` and scoops out that chunk by using `s`ubstrin`g`, before joining all the chunks into one big line. Ran into the issue of ` escaping the next caret, leaving me wondering why I was getting an IndexOutOfBounds error but that's fixed. Now using a much better way to combine the first line.
[195 Bytes to follow the spec of no leading/trailing hyphens](https://tio.run/##TY7dTsJAFITv@xTNcmjP2Z4Vti0tJNb4BtySqF2IKf4EuwgaF1h89drghc7cTOZLJrO1X81u/9xsNh2sq1O3Xe1WbwgtqVf70vbBD08IrorDWOaUIBz6qOI7MKp5Lx76RhhjmNlaW1VVkiSDwUB@y17eezMqiQgRnXO3xiCam8V1LJfLuq7J470fRVEk/DDcyycEIzPKKBFwABeKMwUCHNrQUghOSIRjBe3Vo/1sPyhgYe1cKTSk1NxaIeF4eRyruDsHEaxDHLPmlDPOecJFPyZ@65KnPGPdU806ZZ39IZ2znrAuWJesp6xnnI7/Ub6Yuh8 "PowerShell – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 240 bytes
```
h=[x*3for x in"_,o=+#*|)(x^&"]
for i,*l in(6,"-*~*-"),(9,"_/7"),(13,"@__","((_",">X<","'*`"),(18,")|(","\|/"):h[:i]+=l
*x,=map(int,input().split())
l=len(x)
p=print
p(*(h[i].center(13)for i in x))
p("    (o o)     "*l)
p("ooO--(_)--Ooo-"*l)
```
[Try it online!](https://tio.run/##HY7dSsQwEIXv8xTDCDrJJrvWrvuHEd9gb4VujbJUGohJqBUiFF@9Jp2LmcN3ZpgTf8c@@Hqee90kUX@GARJYj0YGvboRE6f0dostK4aVwmWPdhKV@BMKuaSjRLPZF1XVEl@MQYlEpT@/PuV@J94X8yCRT5TBZdogP/XNybYr7ZhIUn99RLJ@lNbHn5H4@js6mydnTrvOU@Is6jjkDRZJUN/Ydn3t/NgN@SdfguVUkPJBJIRcFCDwIgCFW2gIZ6XIcKXOIahC5/keKniAGrbwCDvYwwGOUGVYwT8 "Python 3 – Try It Online")
]