text:
Assign Airliner Seats
Inspired by last week's APL lesson.
Given an uppercase 2D seat map and a 1D list of customers, return the seat map and the customer list but modified as follows (to indicate occupied seats and seated customers):
For each unique letter in the input passenger list, lowercase that many (or all, if there are not enough) of that letter in the seat map, going left-to-right, top-to-bottom.
For each unique letter in the seat map, lowercase that many (or all, if there are not enough) of that letter in the passenger list, going left-to-right.

The input seat map only contains spaces and uppercase letters from the set {F,B,P,E}, and may be:

separated into rows by line breaks
a list of strings
a matrix of uppercase characters
in any other comparable format

The input customer list only contains uppercase letters from the set {F,B,P,E} and may be:

a string
a list of characters
in any other comparable format

The returned seat map must be identical to the input one, except that zero or more letters have been folded to lowercase
The returned customer list must be identical to the input one, except that zero or more letters have been folded to lowercase
Leading and trailing whitespace is allowed

Examples (shortened editions of United's aircraft)
ERJ145
Seat map input:
P
E
E  PP
E  EE
E  EE
E  EE
E  EE

P  PP
E  EE
E  EE
E  EE

Passenger list input:
FFEEEEEEEEEEEEEEEE

Seat map output:
P
e
e  PP
e  ee
e  ee
e  ee
e  ee

P  PP
e  eE
E  EE
E  EE

Passenger list output:
FFeeeeeeeeeeeeeeee

CRJ700
Seat map input:
F   FF
F   FF
PP  PP
PP  PP
PP  PP
EE  EE

PP  PP
EE  EE
EE  EE
EE  EE

Customer list input:
FFFFFFFFPPEEEEEEEEEEEEEEEEEEEEE

Seat map output:
f   ff
f   ff
pp  PP
PP  PP
PP  PP
ee  ee

PP  PP
ee  ee
ee  ee
ee  ee

Customer list output:
ffffffFFppeeeeeeeeeeeeeeeeEEEEE

B757
Seat map input:
F F  F F
F F  F F
F F  F F

PPP
PPP  PPP
PPP  PPP
PPP  PPP
EEE  EEE
EEE  EEE
PPP  PPP
EEE  EEE
EEE  EEE
     EEE

EEE  EEE
EEE  EEE
EEE  EEE
EEE

Passenger list input:
FEEEEEEEEFEEEFEEEEEEEEFEEFFEEFEFFFEE

Seat map output:
f f  f f
f f  f f
f f  F F

PPP
PPP  PPP
PPP  PPP
PPP  PPP
eee  eee
eee  eee
PPP  PPP
eee  eee
eee  eee
     eeE

EEE  EEE
EEE  EEE
EEE  EEE
EEE

Passenger list output:
feeeeeeeefeeefeeeeeeeefeeffeefefffee

B767
Seat map input:
 F   F   F
 F   F   F
BB  B B  BB
BB  B B  BB
BB  B B  BB
PP       BB
PP

PP  PPP  PP
PP  PPP  PP
PP  PPP  PP
PP  PPP  PP
PP  EEE  PP
EE  EEE  EE
EE  EEE  EE
EE  EEE  EE
EE  EEE  EE
EE  EEE  EE

Passenger list input:
PPFEFEEEEEEEBBEEFFPEBPEBBEEFEEEFEEEEEEFPEEEPB

Seat map output:
 f   f   f
 f   f   f
bb  b b  bb
BB  B B  BB
BB  B B  BB
pp       BB
pp

pp  PPP  PP
PP  PPP  PP
PP  PPP  PP
PP  PPP  PP
PP  eee  PP
ee  eee  ee
ee  eee  ee
ee  eee  ee
ee  EEE  EE
EE  EEE  EE

Passenger list output:
ppfefeeeeeeebbeeffpebpebbeefeeefeeeeeeFpeeepb

For those who, like me, wonder what the letters mean, here's a link to relevant part of the chat

05AB1E, 22 16 15 bytes
Saved 6 bytes thanks to Nit noticing that the seat map could be taken as a string.
svDyå·Fyyl.;s]»

Try it online!
Explanation
s                     # setup stack as <passengerlist>,<seatmap>,<passengerlist>
 v                    # for each passenger y
  Dyå                 # does a corresponding seat exist?
     ·F               # multiplied by 2 times do:
       yyl.;          # replace the first y with a lowercase y
            s         # and swap the seatmap and passengerlist on the stack
             ]        # end loops
              »       # join seatmap and passengerlist on newline and output

The seatmap can be input as a single string with line breaks, wouldn't that save you a byte or two?

@Nit: Ah, It should indeed save me some. Thanks :)

C (clang), 75 68 bytes
f(char*s,char*p){char*r;while(*s){if(r=strchr(p,*s))*r=*s+=32;s++;}}

Takes two char * (seats & passengers) whose contents are modified in-place.
Try it online!
I'm less used to golfing in C than in Python, but that's fun as well !
If anyone has an idea for a trick to shorten the *r+=32,*i+=32 part I'd be grateful. -> Thanks to @Dave for helping me golf some more bytes !

since i and r will be the same, you can use *r=*i+=32. You can also shave off a few more chars by getting rid of i, and post-incrementing s in the strchr call.

Thank you, I'll update when l can ! I thought about using s directly but that didn't work for some reason, I'll get back to it.

59 bytes

Python 2, 93 89 84 83 82 78 bytes
l=input()
for c in l[1]:l=[x.replace(c,c.lower(),c in l[0])for x in l]
print l

Try it online!
Takes input as two strings. Prints two strings

Saved

-5 bytes, thanks to Dead Possum
-4 bytes, thanks to Lynn

s,p=[x.replace(c,c.lower(),c in s)for x in[s,p]] for 84 bytes

A full program is a little shorter: l=input() for c in l[1]:l=[x.replace(c,c.lower(),c in l[0])for x in l] print l

C (gcc), 63 bytes
f(x,y,z)char*x,*y,*z;{for(;*y;++y)if(z=strchr(x,*y))*z=*y+=32;}

Try it online!
Lots of credit to etene for the basic concept. Just applied heavy golfing to his answer's strategy.

Suggest index() instead of strchr()

nice improvement. I won't include it here because it is fully deprecated in POSIX and in my experience is less supported by compilers. Plus its only a 1 byte change. (PS: thanks for all the suggestions recently :) <xkcd.com/541>)

Thanks for the credit ! This kind of out-golfing is my favorite way of learning how to golf better.

Same, I'd recommend checking out some of the comments made on my posts by ceilingcat as well as others recently. I love when we all learn from each other.

C (gcc), 64 bytes
Borrowing from @etene's answer, I removed the if with the ?: tertiary operator and reused the passenger pointer as its own index.
f(s,p,j)char*s,*p,*j;{for(;*p;p++)(j=strchr(s,*p))?*j=*p|=32:0;}

Try it online!

Jelly, 19 bytes
,ṚŒlẹÐ€ḣ"ċÐ€`}Ẏʋ¦/€

Try it online!

Scala, 104 bytes
def f(l:Array[Char]*)=(l(0).map(? =>{val i=l(1)indexOf?;if(i>=0){l(1)(i)= ?toLower;l(1)(i)}else?}),l(1))

Try it online!
Takes 2 seq of chars in input and returns 2 seq of chars.
Explanation:
def f(l: Array[Char]*) =          // input are varargs of Array[Char]; in our case 2 arrays. Arrays are chosen since mutable (the seatmap will be updated while the passenger list is mapped)
  (                               // we return a tuple with the 2 arrays of Chars
    l(0).map(                     // l(0) is the passenger list. We map (transform) each element of this list to lowercase or not and this is what's returned as 1st part of the tuple
      ? => {                      // ? is the current element of the passenger list being mapped (it's ? and not let's say m in order to be able to stick it next to functions)
        val i = l(1) indexOf ?   // i is the index (or -1) of the letter ? in the seat map
        if (i >= 0) {             // if index found
          l(1)(i) = ? toLower     // then we update the seatmap with the lower case version of this seat
          l(1)(i)                 // and the passenger list elmt is mapped to its lower case version (same as ?.toLower)
        }                         //
        else ?                    // if not found, the seatmap is not updated and the passenger list elmt stays in upper case
      }                           //
    ),                            //
    l(1)                          // the updated seat map
  )

Welcome to PPCG!

Retina, 36 bytes
+`(([A-Z])(.*¶)+.*?)(\2.*$)
$l$1$l$4

Try it online! Assumes the customer list is the last line of the input. Explanation: Finds pairs of matching uppercase characters and lowercases them using $l thus avoiding the intermediate characters.

APL (Dyalog Classic), 29 27 bytes
(~2∊/3⍴(⍴⍴,\∘,∩¨,)¨)819⌶¨¨⊢

Try it online!

Perl 5 -pF, 48 bytes
$\=join'',<>;say map$\=~s/$_/lc$_/e&&lc||$_,@F}{

Try it online!
First line of input is the passenger list.  All subsequent lines are the seat map.  Output is the same.


text:
The Time Anagram
Originally posted (and deleted) by @Tlink, which was most likely inspired from this StackOverflow question.
Since it was a shame it got deleted, because it seemed like a good challenge in general, I figured I'd repost it with proper formatting and rules. (I've tried contacting @Tlink and get his/her permission to post it, but (s)he doesn't respond any more, which is why I decided to post it myself now.)
Input: Six digits.
Output: Either the first or last valid time in the 24-hour format (00:00:00 through 23:59:59). (You can choose yourself whether you output the first or last valid time.)
Example:
When the inputs are 1,8,3,2,6,4, the following times can be created:
12:36:48    12:38:46    12:46:38    12:48:36
13:26:48    13:28:46    13:46:28    13:48:26
14:26:38    14:28:36    14:36:28    14:38:26
16:23:48    16:24:38    16:28:34    16:28:43
16:32:48    16:34:28    16:38:24    16:38:42
16:42:38    16:43:28    16:48:23    16:48:32
18:23:46    18:24:36    18:26:34    18:26:43
18:32:46    18:34:26    18:36:24    18:36:42
18:42:36    18:43:26    18:46:23    18:46:32
21:36:48    21:38:46    21:46:38    21:48:36
23:16:48    23:48:16

So we'll output either 12:36:48 or 23:48:16 in this case, being the first / last respectively.
Challenge rules:

State whether you output the first or last valid time in your answer.
I/O is flexible. Input can be six separated integers; a string containing the six digits; an integer list/array; a single (possibly octal) number; etc. Output can be a correctly ordered list/array of digits; a String in the format HH:mm:ss/HHmmss/HH mm ss; every digit printed with new-line delimiter; etc. Your call.
You are allowed to take the digits in any order you'd like, so they can already be sorted from lowest to highest or vice-versa.
If no valid time can be created with the given digits (i.e. 2,5,5,5,5,5), make so clear in any way you'd like. Can return null/false; "Not possible"; crash with an error; etc. (You cannot output an invalid time like 55:55:52, or another valid time like 00:00:00.) Please state how it handles inputs for which no valid time can be created.
You are not allowed to output all possible valid times. Only the earliest/latest should be outputted/returned.
24 for hours (i.e. 24:00:00), or 60 for minutes/seconds (i.e. 00:60:60) are not valid. The ranges are [00-23] for hours and [00-59] for minutes and seconds.

General rules:

This is code-golf, so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
Default Loopholes are forbidden.
If possible, please add a link with a test for your code.
Also, please add an explanation if necessary.

Test cases:
Input:          Earliest output:     Latest output:

1,2,3,4,6,8     12:36:48             23:48:16
2,5,5,5,5,5     None possible        None possible
0,0,0,1,1,1     00:01:11             11:10:00
1,1,2,2,3,3     11:22:33             23:32:11
9,9,9,9,9,9     None possible        None possible
2,3,5,5,9,9     23:59:59             23:59:59
1,2,3,4,5,6     12:34:56             23:56:41
0,0,0,0,0,0     00:00:00             00:00:00
1,5,5,8,8,8     18:58:58             18:58:58
1,5,5,5,8,8     15:58:58             18:58:55
1,1,1,8,8,8     18:18:18             18:18:18

Isn't 23:48:16 a valid output for the example?

should I output only one of the earliest / latest time or both?

@tsh Just one. Which one is up to you. The two Python answers thus far output the earliest.

Does a "valid time" not account for any leap seconds? For example, would 06:08:60 be valid, given that there has been a leap second during that minute?

@EriktheOutgolfer No, 60 for minutes and seconds is not valid. Ranges are [00-23], [00-59], and [00-59]. Will clarify this in the challenge.

C (gcc), 186 174 bytes
D[7]={0,1,10,100,1e3,1e4,1e5};G(O,L,F,T,I,M,E){if(!F)O=L<24e4&L%10000<6e3&L%100<60?L:1e9;else{for(T=1e9,I=0;I++<F;M=G(O/10,L*10+E,F-1),T=T>M?M:T,O=(O/10)+E*D[F])E=O%10;O=T;}}

Try it online!
-12 bytes thanks to Kevin Cruijssen
Probably not optimal, but it works. Oddly enough for some reason with 7 arguments the gcc implementation on TIO requires that you actually supply them or it segfaults. On my machine that is unnecessary however.
Format: G(X,0,6) -> Y where X is the 6-digit number whose digits are to be used and Y is the 6 digit number which when taken as a time (by inserting : appropriately) is minimal.

I think you can golf {0,1,10,100,1000,10000,100000} to {0,1,10,100,1e3,1e4,1e5}. Also, you can golf for(I=0;I<F;++I){E=O%10;M=G(O/10,L*10+E,F-1);T=T>M?M:T;O=(O/10)+E*D[F];} to for(I=0;I++<F;M=G(O/10,L*10+E,F-1),T=T>M?M:T,O=(O/10)+E*D[F])E=O%10;, and remove the brackets around the if. Try it online 174 bytes. Also, I like the G(O,L,F,T,I,M,E). :)

Funny, on my machine using ...1e3,1e4,1e5} didn't work. Thanks for the suggestion.

You're everywhere on this guy's answers, @ceilingcat, nice golfing by the way.

I appreciate the insight. It's always nice to see that people actually read the answers and find ways to improve them. :) You're everywhere on them too now.

125 bytes

Haskell, 114 96 86 bytes
import Data.List
f l=minimum[x|x@[a,b,c,d,e,f]<-permutations l,a:[b]<"24",c<'6',e<'6']

Now with less strict output. Takes input as a string of digits and compares permutations against limits with list comparison. With minutes and seconds only the first digit is checked. Crashes and burns if no permutation is a valid time.
Try it online!

Python 2, 131 115 112 109 105 88 bytes
lambda s:min(d for d in permutations(s)if(2,4)>d[:2]>d[4]<6>d[2])
from itertools import*

Try it online!
I/O are lists of integers
Throws an error if no times are possible

Alternative:
Python 2, 88 bytes
lambda s:max(d*((2,4)>d[:2]>d[4]<6>d[2])for d in permutations(s))
from itertools import*

Try it online!
Returns the latest time
Returns an empty tuple for invalid times

Saved

-21 bytes, thanks to ovs

Japt, 17 bytes
Takes input as a string of digits and outputs the first valid time; loops infinitely if there's no valid time.
á
@øXr':}a@ÐX ¤¯8

Try it

Warning: Extremely slow - add *1000 after the second X to speed it up somewhat. And don't forget that an invalid input will create an infinite loop and may crash your browser.

Explanation
                   :Implicit input of string U
á                  :Get all permutations of U
\n                 :Reassign that array to U
      }a           :Loop until true and then return the argument that was passed
        @          :By default that argument is an integer X which increments on each loop so first we'll pass X through a function
         ÐX        :  new Date(X)
            ¤      :  Get the time
             ¯8    :  Slice to the 8th character to get rid of the timezone info
@                  :The function that tests for truthiness
  Xr':             :  Remove all colons in X
 ø                 :  Does U contain the resulting string?

JavaScript (ES6), 93 89 88 bytes
Expects an array of 6 digits, sorted from lowest to highest. Returns either the 6-digit string of the first valid time, or false if no solution exists.
f=(a,t='')=>t<24e4&/..([0-5].){2}/.test(t)?t:a.some((v,i)=>s=f(a.filter(_=>i--),t+v))&&s

Try it online!
Commented
We recursively try all permutations of the input until we find one that passes a hybrid test using both arithmetic and a regular expression.
f = (                       // f = recursive function taking
  a, t = ''                 // a[] = input array and t = current time
) =>                        //
  t < 24e4 &                // if t is less than 240000
  /..([0-5].){2}/.test(t) ? // and it matches "hhMmSs" with M and S in [0-5]:
    t                       //   return t
  :                         // else:
    a.some((v, i) =>        //   for each digit v at position i in a[]:
      s = f(                //     save in s the result of a recursive call with:
        a.filter(_ => i--), //       a copy of a[] with the current digit removed
        t + v               //       the current digit appended to t
      )                     //     end of recursive call
    ) && s                  //   end of some(); if truthy, return s

05AB1E, 20 15 bytes
Input as sorted string.
Output is the smallest time as a string.
In case of no solution, an empty list is the output.
œʒ2ô•3Èñ•2ô‹P}н

Try it online!

Retina, 77 74 69 65 62 bytes
$
:
6+Lv$`(.)(.*):
$%`$2:$1$%'
O`
0L`([01].|2[0-3])([0-5].){2}

Try it online! Outputs the earliest time, or the empty string if no time can be found. Edit: Saved 5 8 bytes thanks to @TwiNight. Explanation:
$
:
6+Lv$`(.)(.*):
$%`$2:$1$%'

Generate all the permutations. The : works its way though the string as the permutations are generated, ending up at the start.
O`

Sort the times into order.
0L`([01].|2[0-3])([0-5].){2}

Output the first valid time.

Since you can output newline-separated digits, you can save 5 bytes

You can even remove the : in the grep stage since it must match 6 characters and the first must be 0, 1, or 2

@TwiNight Oh, if Grep is shorter than I can save 4 more bytes anyway.

Oh yeah you can just L0

@TwiNight 0G actually.

If you use 0L instead of 0G you can save 3 more by not having to remove the : manually. After the second stage, each line will be in the form :\d{6}, and 1) having the : does not affect sorting, and 2) the final regex matches exactly 6 characters, none of which can be newline and the first can't be : so it must match a string of 6 digits forming a valid time.

@TwiNight Bah, I forgot I could do that, even in Retina 0.8.2...

(by which I mean, 1!`([01].|2[0-3])([0-5].){2} would be an approximate Retina 0.8.2 translation)

Red, 157 124 bytes
Thanks to Kevin Cruijssen for reminding me to read the descritions more carefully!
func[s][a: 0:0:0 loop 86400[b: to-string a a: a + 1 if b/1 =#"0"[insert b"0"]if s = sort replace/all copy b":"""[return b]]]

Try it online!
Takes a sorted string as input. Returns none if it's not possible to make time.
Explanation:
f: func[s][                                    ; the argument is a sorted string of digits
    a: 0:0:0                                   ; time object, set to 00:00:00 h
    loop 86400 [                               ; loop through all seconds in 24 h
        b: to-string a                         ; convert the time to string
        a: a + 1                               ; add 1 second to the current time
        if b/1 = #"0" [                        ; prepend "0" if necessary
            insert b "0"                       ; (Red omits the leading 0)
        ]
        if s = sort replace/all copy b ":" ""[ ; compare the input with the sorted time
            return b                           ; return it if they are equal
        ]
    ]
]

Is the sort at the start necessary? In the challenge I state: "You are allowed to take the digits in any order you'd like, so they can already be sorted from lowest to highest or vice-versa."

@Kevin Cruijssen - No, it's not necessary in this case. I'll update the solution to work with sorted input. Thank you!

Ruby, 68 67 62 56 55 bytes
->*b{b.permutation.find{|a,b,c,d,e|c<6&&e<6&&a*9+b<22}}

Try it online!
Input: Sorted array of digits (as integers).
Output: Array of digits or nil if no solution found

You can drop the space at eval " I think.

Yes, it works, thanks.

I think you can do a*9+b<22 for one byte.

Japt, 39 23 bytes
Pretty sure there's a shorter way to do this, but I wanted to try using Date objects in Japt.
á ®¬ò q':Ãf@T<ÐXiSiKÅ
Ì

á                     // Get all permutations of the input array.
  ®¬ò q':Ã            // [1,2,3,4,5,6] -> "12:34:56"
          f@          // Filter the results, keeping those that
            T<        // are valid dates
              ÐXiSiKÅ // when made into a date object.
Ì                     // Return the last remaining item, if any.

Takes input as a sorted array of numbers, returns the latest valid time or empty output if none exists.
Lost 10 pounds bytes thanks to Shaggy.
Try it here.

25 bytes

@Shaggy Thanks, really neat. Up until right now I didn't know Japt had a separate section in the method docs for dates, which feels quite silly of me, I sorta just tried to work around not having them.

Python 2, 78 bytes
lambda s:min(x for x in range(62**3)if x%100<60>x/100%100<s==sorted('%06d'%x))

Try it online!
Arnauld saved a byte. Thanks!
Expects a list like ['1','2','3','4','6','8'] in sorted order:

You are allowed to take the digits in any order you'd like, so they can already be sorted from lowest to highest or vice-versa.

Outputs an integer like 123648 for 12:36:48. I hope that's acceptable.

Could you use 62**3 instead of 240000?

Jelly, 15 bytes
Œ!s€2Ḍf«¥“ç;;‘Ṃ

Try it online!
Posted after a request. The approach is the same as the one of the other answer, however this answer was developed independently.

Wolfram Language (Mathematica), 63 bytes
FirstCase[Permutations@#,{a:0|1|2,b_,c_,_,d_,_}/;a*b-4<6>d>=c]&

Try it online!
Takes a sorted list of digits as input. Returns Missing[NotFound] for invalid inputs.
Explanation
Permutations@#

Find all of the permutations of the input. Since the input is sorted, it is guaranteed that all valid times are in increasing order.
FirstCase[ ... ]

Find the first list that matches...
{a:0|1|2,b_,c_,_,d_,_}

The first element, labeled a, is 0, 1, or 2, and label the second, third, and fifth elements b, c, and d respectively...
... /;a*b-4<6>d>=c

... such that a*b is less than 10, and d and c are less than 6, with d >= c.
The trick is that for all numbers 00 to 24, the product of the two digits is at most 9, and the possible invalid numbers 25 to 29 (since we force the first digit to be 0, 1, or 2) have the product of least 10.

Jelly, 17 bytes
I'm almost certain this is not the shortest approach... will look at this again later :)
Œ!s2Ḍ<ẠʋÐṀ“ð<<‘ṢḢ

Try it online!

You're correct, this is not the shortest approach. However, public humiliation isn't nice, so I won't comment on the improvements yet. :)

The fact that the input may be assumed to be sorted saves some. It is not humiliating to see better after only spending 2 minutes on a golf!

To be more precise, you can do it in 15 bytes; to save one byte, you must do something trivial; to save the other, it's not so trivial. Mind you, I was going to post that 15-byte version, but it uses your approach. By the way, is your health OK?

Go ahead and post. Health is fine, I'm at work so can't spend time golfing!!

Posted. Now you can see why I was referring to the "humiliation". :P

Perl 5 with -palF, 73 bytes
$"=",";($_)=grep@F~~[sort/./g]&/([01]\d|2[0-3])([0-5]\d){2}/,glob"{@F}"x6

Try it online!
Outputs like HHmmss and outputs a blank line for invalid entries.
Every answer I've made recently has used globing for permutations... Weird!

Bash + GNU sed, 83, 72, 69 bytes

Accepts input as 6 separate arguments;
Returns the earliest time (if found);
Returns nothing (empty output) if no valid combination exist.

seq 0 86399|sed "s/^/date +%T -ud@/e;h;`printf s/%d//\; $@`/\w/d;x;q"
How it works
Pre-generate all the possible time strings, for the timestamps in range 0 to 86399, using GNU-sed e(xecute) command + date.
%seq 0 86399|sed "s/^/date +%T -ud@/e;h;"
00:00:00
00:00:01
...
23:59:59

Generate sed script with 6 sequential substitution commands,
for an each input digit.
%echo sed `printf s/%d//\; $@`
sed s/1//;s/2//;s/3//;s/4//;s/6//;s/8//;

Then, apply substitutions, remove any input lines which have at least one digit left, print the first matching line (original time string is extracted from the hold space with x).
%echo 23:45:12|sed 's/1//;s/2//;s/3//;s/4//;s/6//;s/8//;'
:5:2 //non-matching, delete

%echo 12:36:48|sed 's/1//;s/2//;s/3//;s/4//;s/6//;s/8//;'
:: //matching, print and stop

Test
%./timecomb 1 2 3 4 6 8
12:36:48
%./timecomb 2 5 5 5 5 5
%./timecomb 0 0 0 1 1 1
00:01:11
%./timecomb 1 1 2 2 3 3
11:22:33
%./timecomb 9 9 9 9 9 9
%./timecomb 2 3 5 5 9 9
23:59:59
%./timecomb 1 2 3 4 5 6
12:34:56
%./timecomb 0 0 0 0 0 0
00:00:00
%./timecomb 1 5 5 8 8 8
18:58:58
%./timecomb 1 5 5 5 8 8
15:58:58
%./timecomb 1 1 1 8 8 8
18:18:18

Try It Online !

Pyth, 37 bytes
j\:hf&&<shT24<s@T1 60<seT60mcs`Md2S.p

Test suite
Explanation:
j\:hf&&<shT24<s@T1 60<seT60mcs`Md2S.pQ # Code with implicit variables
   h                                   # The first element of
                                   .pQ # The list of all permutations of the input list
                                  S    # Sorted
                           mcs`Md2     # Mapped to three two digit long strings
    f                                  # Filtered on whether
       <shT24                          #  The first number is less than 24
      &      <s@T1 60                  #  AND the second number is less than 60
     &               <seT60            #  AND the third number is less than 60
j\:                                    # Joined by a colon

Kotlin, 396 391 389 bytes
No clue how to make this smaller. I'm thinking it is double of what's possible. Produces earliest time.
Thanks to Kevin for 7 bytes!
fun p(d:Array<Int>)={val s=Array(6,{0})
val f=Array(6,{1>0})
val t=Array(3,{0})
val o=Array(3,{60})
fun r(i:Int){if(i>5){var l=0>1
var e=!l
for(p in 0..2){t[p]=s[p*2]*10+s[p*2+1]
l=l||(e&&t[p]<o[p])
e=e&&t[p]==o[p]}
if(t[0]<24&&t[1]<60&&t[2]<60&&l)for(p in 0..2)o[p]=t[p]}
else
for(p in 0..5)if(f[p]){f[p]=0>1
s[i]=d[p]
r(i+1)
f[p]=1>0}}
r(0)
if(o[0]>23)0
else "${o[0]}:${o[1]}:${o[2]}"}()

Try it online!

I don't know Kotlin, but do you really need both var l=0>1 and var e=1>0? Also, why are the l=l and e=e necessary? Two things that seem to work to golf are var e=1>0 to var e=!l and removing the space before "None". Also, any falsey-output is fine, so "None" can also be just 0.

@Kevin thank you for the 5 bytes. Shocked I missed one of them. Since I'm not aborting the loop, I can't see anyway to avoid knowing whether the two times have stayed equal so that I can decide the new one is less. I coded a bunch of ways and this ended up shortest. However, the overall code is much bigger than I like.

2 more bytes to golf in your latest version: "0" can be just 0

@Kevin that won't be a String type and I'd have to add :Any to allow both String and Int.

Hmm ok. It does work in TIO though, and still prints the 0 without errors.. And your current function doesn't specify a return-type as far as I could tell, so won't it implicitly return as an object anyway? PS: I don't know Kotlin at all, just tried it without the quotes and the results were the same. ;) Maybe something else isn't working because of it, which I'm not aware of.

@Kevin I'm guessing the {}() pattern is smarter than the = if () 0 else "" as you get an error in the second case of mismatched types, but you're right the first works fine. I guess I must hunt down why...

MATL, 31 30 bytes
Y@3Xy[X1]X*!Y*t[4XX]6*<!AY)1Y)

Try it online!
Input is 6 integers, output is the minimum hour, minutes, and seconds in an array. Crashes for inputs where no such time is possible.
(-1 byte thanks to @Luis Mendo.)

I think you can replace 2&A by !A, because the binary matrix will never be a row vector

Perl 6, 43 bytes
*.permutations.first:{24e4>.join&&6>.[2&4]}

Try it online!
Expects a sorted input array. Returns Nil for invalid input.

Stax, 15 bytes
╝a╣=→aá≈#8(⌂≈58

Run and debug it
It takes a string of sorted digits for input.  It returns the first permutation that satisfies a few criteria.

lexicographically less than "24"
all three pairs of characters are lexicographically less than "6"

Retina, 58 47 bytes
+,V^2`[0-5][6-9]{2}
G`([01].|2[0-3])([0-5].){2}

Try it online!
Input is 6 digits in sorted order. Output is 6 digits representing earliest valid time, or empty string if no valid time exists.
EDIT: I was an idiot, -9 bytes
Explanation
Algorithm
For brevity, let's define a low digit as 0-5, and a high digit as 6-9.
First, rearrange the digits so that "low-ness" or "high-ness" of each position is correct. The correct arrangement, for each number of high digits in the input:
# of highs  arrangment
0           LLLLLL
1           LLLLLH
2           LLLHLH
3           LHLHLH
4+          Not possible

Since the any rearrangement would fail the final check in the input has 4+ high digits, we can ignore that case completely.
Then, sort the lows and the highs individually. Combine with the rearrangement, this gives the lowest value that satisfies the minute and second constraints. So this gives the earliest valid time, if one exists.
Finally, check if that we have valid time. If not, discard the string.

Program
+,V^2`[0-5][6-9]{2}

Matches LHH and swaps the first two digits in that (becomes HLH), and repeat that until no more LHH exists. This gives the correct arrangement.
Actually, I lied. No sorting is needed because 1) swapping only happens between adjacent digits and only between a low and a high; and 2) the input is sorted. So the lows and the highs individually are already in sorted order.
G`([01].|2[0-3])[0-5].[0-5].

Only keeps the string if it is a valid time

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Take CR and LF literally
As a celebration of good old Notepad, we are going to treat carriage returns and line feeds as what they originally meant, rather than what they are (ab-)used for today.
Given a string consisting of printable ASCII plus line feeds (␊; LF; esc \n; hex 0A; dec 10) and carriage returns (␍; CR; esc \r; hex 0D; dec 13), cause Try It Online to show how the printable characters would be positioned if printed on a printer which takes those two control characters literally:

upon a line feed, continue printing one line further down
upon a carriage return continue printing from the left edge
multiple consecutive carriage returns behave like a single carriage return

Due to modern devices having problems with overstriking, a run of one or more of carriage returns will, except for at the beginning of the input, never occur without at least one preceding and/or following line feed. However, two runs of carriage returns may be separated by a single line feed.
Any amount of additional trailing white space is acceptable, both on the right-hand side of any lines and below the entire text, as long as at least the amount of white space given in the input is preserved.
Examples (using \n and \r for line feed and carriage return)
Lorem ipsum dolor sit amet,
Lorem ipsum dolor sit amet,

consectetur adipiscing\nelit, sed
consectetur adipiscing
                      elit, sed

do eiusmod\r\ntempor incididunt\n\n ut labore
do eiusmod
tempor incididunt

                  ut labore

et dolore\n\rmagna          \r\r\naliqua. Ut (notice the trailing spaces)
et dolore
magna
aliqua. Ut

\nenim ad minim veniam,\n\r     quis nostrud

enim ad minim veniam,
     quis nostrud

\rexercitation\r\n\rullamco laboris\n\r\nnisi ut aliquip ex\n\n\rea commodo consequat.\n\n

exercitation
ullamco laboris

nisi ut aliquip ex

ea commodo consequat.

Suggested answer: Notepad, 179712 bytes

@Nit :| notepad isn't TC

Shame that TIO doesn't use a proper terminal, otherwise a nice shell winner would be stty -onlcr;cat.

@TobySpeight Then there would be no challenge.

I'm having trouble entering the carriage-return characters into the "input" field of TIO.  They just seem to get swallowed up (or converted into newlines) when pasting - is that my browser at fault, or is it TIO?

@TobySpeight You'll probably need to input them as JSON or something similar. You don't need to count any wrapper that handles that bit.

In my opinion, just require the output to only contain only printable ASCII and newlines should be OK.

STDERR (i.e. TIO's Debug) is also fine. And if they somehow can be wrapped (e.g. using Bash on TIO) to capture the output, that's fine too (and the wrapper doesn't need to be counted). Otherwise they cannot participate. Sorry.

@Adám Don't prohibit all outputs than TIO. Instead restrict programs to using certain terminal types, or to file output. Or require that output have the necessary spaces preceding text on new lines.

Charcoal, 10 bytes
ＵＴＦθ«ι≡ι⸿↑

Try it online! Link is to verbose version of code. Explanation:
ＵＴ

Disable right padding.
Ｆθ«

Loop over the input.
ι

Print the current character. This automatically handles \n (which Charcoal treats as \v in this context) but Charcoal translates \r into \r\n, so...
≡ι⸿

... check for an \r...
↑

... and if so then move back up a line.

Shouldn't you remove the l flag from your TIO link?

@Adám What's to stop me pasting any gibberish into my answer and then linking to a suboptimal program?

I see. Maybe Charcoal should output the TIO link to stderr (Debug)?

@Adám I'll suggest that to@ASCII-only.

@Neil fixed, I think?

I don't know why you asked me, It was @Adám's suggestion...

yeah but for some reason he appears not to show up in the ping list

@ASCII-only OK, the CMC answer has moved to stderr, but its text is still in stdout.

@Adám yes, but that's only because of the -l option

@ASCII-only The idea was that echoing of code (in short form) would be on stderr only so stdour could contain clean output from the code running.

@Adám ohhhhhh, fair enough. what about AST printing?

@ASCII-only I don't know what that is.

Let us continue this discussion in chat.

Ruby, 24 17 bytes
->s{s.tr $/,"\v"}

Try it online!
It does not work on TIO, but works on the Linux console.

You can drop the space between tr " I think.

Uh, I didn't think of this solution, it may just work for any language to change all \ns into \v when run in a Linux console.

@Adám What about some languages change nothing and works in a DOS console?

I'm sorry for changing the spec mid-challenge, but to make the challenge more interesting and less subject to trivial answers, I now require proper output on TIO.

it won't work if the terminal was set to raw mode

Changing the spec: I don't think it's fair. but I will delete my answer if I have to.

@LưuVĩnhPhúc If the terminal is in raw mode, I think the input will generate the required output, so no code needed. That's exactly why I had to prohibit other output methods than through TIO.

Java 10, 211 207 206 bytes
s->{var a=s.replace("\r\n","\n\r").split("(?<=\n)");int i=0,p=0,j;for(var x:a){for(j=x.charAt(0)<14?0:p;j-->0;x=" "+x);j=(a[i++]=x.replace("\r","")).length()-1;p=x.matches("\\s+")?p:j;}return"".join("",a);}

Try it online.
Explanation:
s->{                      // Method with String as both parameter and return-type
  var a=s.replace("\r\n","\n\r")
                          //  Replace all "\r\n" with "\n\r"
        .split("(?<=\n)");//  Create String-array split by "\n",
                          //  without removing the trailing "\n" delimiter
  int i=0,                //  Index integer
      p=0,                //  Previous line-length, starting at 0
      j;                  //  Temp integer
  for(var x:a){           //  Loop over the String-array
    for(j=x.charAt(0)<14?0//   If the current line starts with either '\r' or '\n':
        0                 //    Prepend no spaces
       :                  //   Else:
        p;j-->0;x=" "+x); //    Prepand `p` amount of spaces for the current item
    j=(a[i++]=x.replace("\r",""))
                          //   Remove all "\r" from the current line
       .length()-1;       //   Set `j` to the current line-length (minus the trailing '\n')
    p=x.matches("\\s+")?  //   If the current line only contains '\r', '\n' and/or spaces:
       p                  //    Leave `p` unchanged
      :                   //   Else:
       j;}                //    Change `p` to this line-length minus 1
  return"".join("",a);}   //  Return the String-array joined together

Old answer before the challenge was changed 151 148 bytes:
s->{String a[]=s.replace("\r\n","\n\r").split("(?<=\n)"),r="";int p=0,i;for(var x:a){for(i=p;i-->0;r+=" ");i=x.length()-1;p=i<1?p:i;r+=x;}return r;}

Explanation:
s->{                            // Method with String as both parameter and return-type
  String a[]=s.replace("\r\n","\n\r")
                                //  Replace all "\r\n" with "\n\r"
              .split("(?<=\n)"),//  Create String-array split by "\n",
                                //  without removing the trailing "\n" delimiter
         r="";                  //  Result-String, starting empty
  int p=0,                      //  Previous line-length, starting at 0
      i;                        //  Index (and temp) integer
  for(var x:a){                 //  Loop over the String-array
    for(i=p;i-->0;r+=" ");      //   Append `p` amount of spaces to the result
    i=x.length()-1;p=i<1?p:j;   //   If the current line is not empty:
                                //    Replace `p` with the length of this current line
    r+=x;}                      //   Append the current item
  return r;}                    //  Return the result-String

Doesn't work on TIO, does work on Windows Command Prompt:

Python 2, 150 128 122 104 103 bytes
def f(s):
 i=n=0;l=''
 for c in s:l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]
 print l

Try it online!

Saved:

-1 byte, thanks to Lynn

It seems l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3] is just barely shorter.

JavaScript (Node.js), 85 bytes
s=>s[R='replace'](/(.*)([\n\r]+)/g,(_,t,b)=>t+b[R](/\r/g,_=>s='',s=t[R](/./g,' '))+s)

Try it online!

C (gcc), 100 94 bytes
b,c,d;f(char*s){for(b=13;b;b=*s++)b==13?c=d=0:b-10?d=!printf("%*c",++d,b),++c:putchar(b,d=c);}

Assumes ASCII coding ('\r'==13, '\n'==10); adjust to suit on other systems.
Try it online! (requires Javascript)
Readable version
int c = 0;
int d = 0;

f(char*s)
{
    for (;*s;++s) {
        switch (*s) {
        case'\r':
            c = d = 0;
            break;
        case'\n':
            d = c;
            putchar(*s);
            break;
        default:
            printf("%*s%c", d, "", *s);
            d = 0;
            ++c;
        }
    }
}

c is the current column position; d is the number of spaces that must be inserted before a printable character.  Both are assumed to be zero on entry to the function.
Test program
int main(int argc, char **argv)
{
    char s[1024];
    if (argc <= 1)
        while (fgets(s, sizeof s, stdin))
               f(s);
    else
        for (int i = 1;  i < argc;  ++i)
            f(argv[i]);
}

chars are just small ints, they should be interchangeable (in theory). Maybe gcc will do an implicit cast

91 bytes.

By the way, I do not think that per our consensus you are allowed to reset your global variables c,d. Your function should -- without other cleanup code -- be able to run multiple times. Thus you most likely need to add a c=d=0.

For your interest, the relevant meta post.

It's now a reusable function.

Python 3, 101 94 bytes
Based on TFeld's answer.
def f(s):
 i=n=0
 for c in s:k='\r\n'.find(c);a=k&1;print(end=-k*' '*i*n+c*a);n=k>0;i=i*a-k//2

Try it online!

Ungolfed
def f(s):
  i=0  # position of the cursor
  n=0  # was the last character LF?
  for c in s:        # iterate over the input
    k='\r\n'.find(c) # k := 0 for CR, 1 for LF and -1 for every other character
    a=k&1            # as (-1)&1 == (1)&1 == 1, this is a := abs(k)
    print(end=-k*' '*i*n+c*a) # If c is a normal character (k == -1) and the last character was LF,
                              # print leading spaces. If c is not CR, print it
    n=k>0            # n := True if c is LF, False otherwise
    i=i*a-k//2       # If c is either a newline or a printable character (a == 1),
                     # keep the cursor's position and increment it for a printable character ((-1)//2 == -1)

Clean, 92 91 bytes
-1 thanks to Laikoni!
Note: \ in \r is omitted from bytecount as Linux CG handles literal \r and \ns.
Note: Windows CG requires \n and \r be escaped, so +3 if it has to run on Windows.
import StdEnv
?n['\r':t]= ?0t
?n['
':t]=['
':spaces n]++ ?n t
?n[h:t]=[h: ?(n+1)t]
?_ e=e

?0

Try it online!
A partial application of ? :: Int [Char] -> [Char] with 0 as the initial first argument. This descends through each character keeping track of how many traversed, the count resets when it encounters a carriage return and when it encounters a newline it adds spaces equal to the number of characters traversed at that point.

I think ?_[]=[] can be ?_ e=e.

@Laikoni You're right. I swear I've missed exactly that same thing a dozen times by now.

Haskell, 93 87 bytes
l=0#0
(n#x)(t:r)|t=='\n'=t:(n#1)r|t=='\r'=l$r|m<-n+1=(' '<$[1..n*x])++t:(m#0)r
(_#_)e=e

Try it online!

Pretty straightforward solution. # is an infix function that recursively creates the output one character at a time while keeping a character position counter (n) and flag for when to add spaces after a newline (x).

You can define an infix function instead of c, use l$r instead of c 0 0r and c _ _ e=e (or rather (_#_)e=e).

All together 87 bytes: Try it online!

@Laikoni Thank you, I didn't realize you could use that infix trick with that many parameters.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
What's the shortest way to define an anonymous recursive function in Octave?
I love functional programming in Octave, but it's rather unwieldy in practice. I'm wondering about the shortest way to define an anonymous recursive function.
I have some ideas, but I'm wondering if there is a way to combine these ideas to make them even shorter (or equally short but more versatile). For the sake of this question, let's recursively count down to zero (just to keep the payload as simple as possible).
If my reasoning is correct, none of the variable names I used in the following examples should overlap. The desired function is q(n), which should always return zero. i is used as a counter variable, f is the recursive function which I have called g in the local scope of f.
44 bytes, "inline definition of f"
q=@(n)(f=@(g,i){@()g(g,i-1),i}{~i+1}())(f,n)

44 bytes, "argument list definition of f"
q=@(n,f=@(g,i){@()g(g,i-1),i}{~i+1}())f(f,n)

44 bytes, "separate definition of f"
f=@(i,g){@()g(i-1,g),i}{~i+1}();q=@(n)f(n,f)

41 bytes, "desired function as a return value"
f=@(g)@(n){@()g(g)(n-1),n}{~n+1}();q=f(f)

The current 'winner' is inspired by this answer by flawr. However, given the large range of different ways to do this, perhaps someone can think of an even shorter combination of methods.
The goal is of course to get it below 39 bytes for a "full" function, Try it online!

Octave, 39 bytes
q=f(f=@(g)@(n){@()g(g)(n-1),n}{~n+1}())

Try it online!

Wow I did not expect that you could define a function in it's own argument list. Well done!


text:
Find arsonist's lullaby
Imagine an arsonist walking around the town and picking its victims according to a very specific pattern (Or, alternatively, Imagine a bee flying around the garden and picking its flowers to pollenize according to a very specific pattern). Let's say the town is an N × N matrix, where N is an integer higher than or equal to 2. The arsonist starts from the upper-left corner and successively sets the house M spots in front of them (where M is the number of the house they're currently in), while changing the direction it's moving in after each fire, in the order East ⟶ South ⟶ West ⟶ North ⟶ East ⟶ South... and so on. The lullaby of the arsonist is the value of M that makes them exit the town (i.e. the last house they visit before stopping the abomination). This is way easier to understand with an example. Take the following matrix for instance:

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

We start in the upper-left corner, so M = 3 (X marks the current and previous positions of the arsonist):

X 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

According to the known order, it first goes east M (3) spots and lands on a 2 so M changes accordingly:

X 2 3 X 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

Then it goes south 2 spots and M is now 1:

X 2 3 X 7
3 1 4 1 6
2 5 3 X 1
4 4 3 2 4
1 1 1 1 1

Now it moves 1 spot to the West and M becomes 3:

X 2 3 X 7
3 1 4 1 6
2 5 X X 1
4 4 3 2 4
1 1 1 1 1

After it moves 3 spots north, it exits the town! Therefore, 3 is this arsonist's lullaby:

    X
X 2 3 X 7
3 1 4 1 6
2 5 X X 1
4 4 3 2 4
1 1 1 1 1

Given an N × N matrix (you can optionally take N as input too), find the lullaby of the arsonist. I've written a program with which you can generate more test cases and visualise the path of the arsonist: Try it online!

You may assume that the arsonist does have a lullaby (that is, it can actually get out of the matrix).
The matrix will only contain positive integers less than or equal to 9 (digits), for simplicity. Solutions that handle any positive integer are completely welcome.
Note that the arsonist can land on a spot they've already burned, in case the sense they're moving in is different from the first time. In such a scenario, just take the value of that element and move again as usual.
You can compete in any programming language and can take input and provide output through any standard method, while taking note that these loopholes are forbidden by default. This is code-golf, so the shortest submission (in bytes) for every language wins.

Test cases

-------------
9 2 3
1 7 2
8 7 6

Lullaby: 9
-------------
2 1 2 1
3 1 1 2
1 2 2 1
1 1 1 3

Lullaby: 2
-------------
3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

Lullaby: 3
-------------
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2
1 2 1 2 1 2

Lullaby: 2
-------------
3 2 1 2 1 1 1
2 3 2 3 2 1 1
2 1 1 1 3 1 2
3 1 1 1 1 1 1
4 5 2 3 1 1 1
1 2 1 2 1 2 2
1 2 2 3 2 1 2

Lullaby: 3
-------------

The matrices in a different format:

[[9, 2, 3], [1, 7, 2], [8, 7, 6]]
[[2, 1, 2, 1], [3, 1, 1, 2], [1, 2, 2, 1], [1, 1, 1, 3]]
[[3, 2, 3, 2, 7], [3, 1, 4, 1, 6], [2, 5, 3, 1, 1], [4, 4, 3, 2, 4], [1, 1, 1, 1, 1]]
[[1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2]]
[[3, 2, 1, 2, 1, 1, 1], [2, 3, 2, 3, 2, 1, 1], [2, 1, 1, 1, 3, 1, 2], [3, 1, 1, 1, 1, 1, 1], [4, 5, 2, 3, 1, 1, 1], [1, 2, 1, 2, 1, 2, 2], [1, 2, 2, 3, 2, 1, 2]]

The fifth test case is very interesting to visualise.

This is like a generalisation of Skip like a Rabbit in two dimensions, with a slightly different goal. The thematic of this challenge and its title were inspired by a song by Hozier

what happens when the arsonist lands on a square that is already burnt?

@LevelRiverSt It just burns it again and takes the value of M as the value of that spot. This scenario is only possible if the arsonist is going in a different direction (sense, actually), because otherwise it would be impossible to exit the matrix (which you are guaranteed to happen). This is covered by the fourth test case, hence the The fourth test case is very interesting to visualise. I've addressed your concerns in the challenge body. Thanks for spotting that.

Can we assume that the arsonist is not actually an arsonist and is instead doing something nice at each location rather than burning it down? +1 for a very nice idea :)

@ElPedro Sure, an alternate version for you: Imagine a bee flying around the garden and picking its flowers to pollenize according to a very specific pattern. :D Happy friendly golfing!

That's a much nicer thought. If I could upvote again I would for that.

MATL, 32 bytes
JQ6*`G5thYay&Zj3$)wyJ2@-^*+8M]b&

Try it online! Or verify all test cases.
How it works
The input matrix is padded with a frame of five zeros, so for example
3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

becomes
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 3 2 3 2 7 0 0 0 0 0
0 0 0 0 0 3 1 4 1 6 0 0 0 0 0
0 0 0 0 0 2 5 3 1 1 0 0 0 0 0
0 0 0 0 0 4 4 3 2 4 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

The frame of zeros is used to detect when the arsonist bee has exited the matrix. The extension with five zeros ensures that a modular displacement of length up to 9 in any direction from any of the nonzero entries will correctly land in a zero without wrapping around to some non-zero entry.
In matrix coordinates, the bee starts at entry (6,6) of the extended matrix. It reads that entry, and updates the coordinates as required, applying a (modular) displacement of the read length in the corresponding direction. This is repeated in a loop until the read value is 0. The entry that was read before that one (i.e. the last non-zero entry) is the output.
The coordinates are actually stored as a complex number, so for example (6,6) becomes 6+6j. This way the four cyclic directions can be realized as powers of the imaginary unit. The corresponding power (j, 1, -j or -1) is multiplied by the read entry to obtain the complex displacement which is used for updating the coordinates.
The successively read values are kept on the stack. When the loop is exited, the stack contains all non-zero read values in order, then the last read value which is 0, then the latest complex coordinates. So the third-top element is the required output.

+1 for a very innovative approach.

JavaScript (ES6), 70 68 bytes
m=>(g=d=>(n=(m[y]||0)[x])?g(--d&3,x-=d%2*(y+=--d%2*n,L=n)):L)(x=y=0)

Try it online!
Commented
m => (                        // given m = input matrix
  g = d =>                    // g = recursive function taking the direction d
    (n = (m[y] || 0)[x]) ?    // let n be the content of the current cell; if it's defined:
      g(                      //   do a recursive call:
        --d & 3,              //     with the next direction (0 = E, 3 = S, 2 = W, 1 = N)
        x -=                  //     update x by subtracting ...
          d % 2 * (           //       ... ((d - 1) % 2) * n
            y += --d % 2 * n, //       and update y by adding ((d - 2) % 2) * n
            L = n             //       save n into L
          )                   //     end of x update
      )                       //   end of recursive call
    :                         // else:
      L                       //   stop recursion and return L
)(x = y = 0)                  // initial call to g() with x = y = d = 0

Given that the sign of the modulo in JS is that of the dividend, the direction is updated this way:
 d | d' = --d&3 | dx = -(d%2)  | dy = --d%2 | direction
---+------------+--------------+------------+------------------
 0 |     3      | -(-1%2) = +1 | -2%2 =  0  | (+1,  0) = East
 3 |     2      | -( 2%2) =  0 |  1%2 = +1  | ( 0, +1) = South
 2 |     1      | -( 1%2) = -1 |  0%2 =  0  | (-1,  0) = West
 1 |     0      | -( 0%2) =  0 | -1%2 = -1  | ( 0, -1) = North

Charcoal, 25 18 bytes
ＰＳ↶ＷＫＫ«≔ιθ×Ｉι¶↷»⎚θ

Try it online! Link is to verbose version of code. Explanation:
ＰＳ

Print the input string, but don't move the print position.
↶

Rotate the pivot left, so that the print direction is now up.
ＷＫＫ«

Repeat while there is a character under the print position.
≔ιθ

Save the character in a variable.
×Ｉι¶

Cast the character to a number and print that many newlines. As the print direction is now up, this ends up printing horizontally. The upshot is that we've moved the print position in the desired direction by the amount given by the number under the print position.
↷»

Rotate the pivot so that the next newlines move the print position in the next direction clockwise for the next pass of the loop.
Ｆ⟦ωθ⟧¿ιι⎚

Unfortunately we still have the input cluttering our canvas, and even more unfortunately, if we clear the canvas we also clear our variable. So, this is a bit of a trick: a list of the empty string and the variable is looped over. On the first pass of the loop, the loop variable is empty, so the canvas and the loop variable and the result variable are all cleared. But the loop is not finished! On the second pass of the loop, we still get to access our variable carefully preserved in our loop list. It simply remains to print it.
⎚θ

Clear the canvas and print the saved variable. (Thanks to @ASCII-only for the fix to Charcoal.)

Python 2, 85 84 bytes
a=input();x=y=e=0;d=1
while-1<y<len(a)>x>=0:v=a[y][x];x+=v*d;y+=e*v;d,e=-e,d
print v

Try it online!
Tip o' the hat to Mr. Xcoder for 1 byte.

Charcoal, 50 49 46 34 33 26 bytes
ＮθＥθＳＭθ↑ＷＫＫ«ＭＩι✳⊗Ｌυ⊞υι»⎚⊟υ

Try it online
Link is to the verbose version of the code
Input must be N on its own line, then the lines of the array on separate lines after that.
Any ways to knock off bytes are welcome and wanted, as I am not a good golfer in Charcoal!
-12 bytes thanks to @Neil!
-1 byte thanks to @ASCII-only!
-7 bytes thanks to @ASCII-only (changed a bug that made Clear reset variables)

Red, 145 bytes
func[b][h:[0 1 0 -1 0]x: y: 1 i: 0
until[y: h/(i: i % 4 + 1) *(t: b/(y)/(x)) + y x: h/(i + 1) * t + x none = b/(y) or(x < 1 or(x > length? b))]t]

Try it online!
More readable:
f: func[b][
    h: [0 1 0 -1 0]                                ; step lengths (combined for x and y)
    x: y: 1                                        ; starting coords (1,1)
    i: 0                                           ; step counter
    until[
        y: h/(i: i % 4 + 1) * (t: b/(y)/(x)) + y   ; next y; t stores the lullaby
        x: h/(i + 1) * t + x                       ; next x
        none = b/(y) or (x < 1 or (x > length? b)) ; until x or y are not valid indices
    ]
    t                                              ; return the lullaby
]

Perl 6, 62 bytes
{$^w;$^m[0,{$_+$m[$_]*(1,$w,-1,-$w)[$++%4]}...{!$m[$_]}][*-2]}

Try it online!
Takes the matrix as flat list and width.

Clean, 141 bytes
import StdEnv
d=[0,1,1,0,0,-1,-1,0:d]
$m[x,y]n[a,b:l]#r=size m
#u=x+a*n
#v=y+b*n
|0>u||0>v||u>=r||v>=r=n= $m[u,v]m.[u,v]l
?m= $m[0,0]m.[0,0]d

Try it online!
Defines the function ? :: {#{#Int}} -> Int, taking an unboxed array of unboxed arrays of integers and returning the result.

Java 8, 121 bytes
m->{int l=m.length,x=0,y=0,f=0,r=0;for(;x*y>=0&x<l&y<l;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];return r;}

Try it online.
Alternative with same 121 bytes byte-count:
m->{int l=m.length,x=0,y=0,f=0,r=0;try{for(;;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];}finally{return r;}}

Uses try-finally instead of checking if the x,y-coordinate is still within bounds.
Try it online.
Explanation:
m->{                   // Method with integer-matrix parameter and integer return-type
  int l=m.length,      //  Dimensions of the matrix
      x=0,y=0,         //  x,y coordinate, starting at [0,0]
      f=0,             //  Direction-flag, starting at 0 (east)
      r=0;             //  Result-integer
  for(;x*y>=0&x<l&y<l  //  Loop as long as the x,y coordinates are still within bounds
      ;                //    After every iteration:
       x+=f<1?         //     If the direction is east:
           r           //      Increase the `x` coordinate by `r`
          :f==2?       //     Else-if the direction is west:
           -r          //      Decrease the `x` coordinate by `r`
          :            //     Else (it's north/south):
           0,          //      Leave the `x` coordinate the same
       y+=f==1?        //     If the direction is south:
           r           //      Increase the `y` coordinate by `r`
          :f>2?        //     Else-if the direction is north:
           -r          //      Decrease the `y` coordinate by `r`
          :            //     Else:
           0,          //      Leave the `y` coordinate the same
       f=++f%4)        //     Go to the next direction (0→1→2→3→0)
    r=m[y][x];         //   Set `r` to the value of the current cell
  return r;}           //  Return the last `r` before we went out of bounds

Perl 5, 92 bytes
sub b{1while eval join'&&',map{/./;map"(\$$_$&=".'$n=$_[$y][$x])'.$',x,'y'}'+<@_','->=0';$n}

Try it online!
How?
The set of nested maps and the join produce this:
($x+=$n=$_[$y][$x])<@_&&($y+=$n=$_[$y][$x])<@_&&($x-=$n=$_[$y][$x])>=0&&($y-=$n=$_[$y][$x])>=0

which is then evaluated to determine if the loop ends.  Because the Boolean is evaluated left to right, the value of $n actually changes (up to) four times during the evaluation.  Because Boolean logic short-circuits in Perl, the value of $n is the lullaby when the loop is exited.

Python 3, 85 84 bytes
xcoder: -1 (I never remember the +~ trick)
def f(x):
 r=c=0
 while-1<r:d=x[r][c];r,c=len(x)-c+~d,r;x=[*zip(*x)][::-1]
 return d

Try it online!
Instead of moving in different directions (E,S,W,N), this solution always moves east and rotates the grid counter clockwise after every move.  After rotating, what was the last column is now the first row, so if the row index is less than zero it means we ran off the board.

84 bytes:  -d-1 => +~d

Retina, 161 bytes
.
 $.%`*_#$&*
(?<=(.+¶)+|^)
A ¶A$#1*
~(K`{`^X\1YZ¶1S$4¶1XYZ¶2$4$2$4$3¶2XYZ¶3S¶3XY\1Z¶S
X
(_$*)(A_$*)
Y
( _$*)
Z
(?=\n\D$*\2\b.$*\3#(_+))
)`S
$$4$$2$$3
L$0`_+
$.0

Try it online!


text:
The 21 Hairstyles of the Apocalypse
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, lowest byte-count wins.

Pretty similar: https://codegolf.stackexchange.com/q/34773/29750

@NinjaBearMonkey in terms of algorithm, sure, in terms of content, not really. Agreed but with 3 valid challenges written today I felt like... we needed another. 21 views and 0 upvotes seems to disagree though. I can delete if you think it should've been sandboxed.

Number 7 seems to violate the "face is as follows" part

@boboquack I think that part is only for helping you understand the basic structure, although using hhhhh instead of hhh would help.

All your test cases include a trailing "stitching" hyphen, which seems to contradict the spec.

Kilroy was here.

@boboquack crap... too late to remove that now.

@MagicOctupusUrn, can you please address the issue of the trailing hyphens I raised above?

@Shaggy Didn't notice the hyphen comment, my bad. Trailing/preceding hyphens are up to implementation, that is fine.

Japt -R, 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
[                                             :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

Nice job getting it to 100. That char-mirror method that we've wanted would really come in handy here.

Also, that wrapping of the & to take advantage of m³ was genius. Especially since that made it 1-based.

It was the other way 'round; I realised I could move the & there if I made it 1-based ;) Still feel there's more to golf here but it's late so it'll have to wait 'til tomorrow.

Charcoal, 103 102 bytes
Ｅ²⪫Ｅθ⎇ι(o o)⪫×²§ -⁼λ⁶§⪪”|″:αuxkτT↷K[ï�↔ς↨?◧BZ@C←↑⊞Ａ⧴M✂↶ºKf÷H#S⦃J&≔⁰∧5À³≕r‹▷”³λ× ⁹Ｍ⁴←⪫ＥθooO--(_)--Ooo¦-

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 -.

R, 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!

you should probably alias utf8ToInt and intToUtf8

391 bytes

@Giuseppe good point! I am ashamed of my index swaps it is so costly. I will work on it.

@JayCe You missed one more rep to shorten: for(i in s)K(I(c(rep<--

Thanks @KirillL. ! I'll make sure to include this when I finally have time to review this code.

Python 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!
0-based indexing; nothing especially clever here, just data accessed via slicing and using exec instead of a loop.

186 bytes

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!
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

Ruby, 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!
All the difficult stuff happens on the top line.
"_,o=+# *| )(x    ^  &" contains all the hairstyles with 3 identical characters, from which we select the ith 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.

You can drop parentheses in center(14)

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.
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

Python 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!

R, 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!
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.

Love your direct approach! I wasn't aware of justify="centre" I can probably reuse it. Minus two chars : "/"=rep

another two bytes down: format(h[i],,,,"c",14+!20-i)

@Giuseppe it's actually -3, so even better.
@JayCe very nice, in fact we don't use multiplication either, so overriding * looks even better - now it resembles string * number operation common to many other languages!

Red, 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!

Ruby, 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!
0-indexed. I fiddled with Level River St's answer 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.

C (gcc), 210 212 bytes
-4 bytes thanks to 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!

206 bytes

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!
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 substring, 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

nice 7. you could save some bytes Try it online!

and some more Try it online!

Runic Enchantments, 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!
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 Branching.
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.

Python 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!


text:
Sign-Swapping Sums
Given a nonempty list of positive integers \$(x, y, z, \dots)\$, your job is to determine the number of unique values of \$\pm x \pm y \pm z \pm \dots\$
For example, consider the list \$(1, 2, 2)\$. There are eight possible ways to create sums:

\$+ 1 + 2 + 2 \to +5\$
\$+ 1 + 2 − 2 \to +1\$
\$+ 1 − 2 + 2 \to +1\$
\$+ 1 − 2 − 2 \to −3\$
\$− 1 + 2 + 2 \to +3\$
\$− 1 + 2 − 2 \to −1\$
\$− 1 − 2 + 2 \to −1\$
\$− 1 − 2 − 2 \to −5\$

There are six unique sums \$\{5, -5, 1, -1, 3, -3\}\$, so the answer is \$6\$.
Test Cases
[1, 2] => 4
[1, 2, 2] => 6
[s]*n => n+1
[1, 2, 27] => 8
[1, 2, 3, 4, 5, 6, 7] => 29
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] => 45
[1, 7, 2, 8, 3, 1, 6, 8, 10, 9] => 56
[93, 28, 92, 100, 43, 66, 2, 98, 2, 52, 57, 75, 39, 77, 45, 15, 13, 82, 81, 20, 68, 14, 5, 3, 72, 56, 57, 1, 23, 25, 76, 59, 60, 71, 71, 24, 1, 3, 72, 84, 72, 28, 83, 62, 66, 45, 21, 28, 49, 57, 70, 3, 44, 47, 1, 54, 53, 56, 36, 20, 99, 9, 89, 74, 1, 14, 68, 47, 99, 61, 46, 26, 69, 21, 20, 82, 23, 39, 50, 58, 24, 22, 48, 32, 30, 11, 11, 48, 90, 44, 47, 90, 61, 86, 72, 20, 56, 6, 55, 59] => 4728

Reference solution (optimizes for speed and not size).
If you can't handle the last case because you use a brute-force method or similar, that's fine.
Scoring
This is code-golf, so the shortest valid solution (measured in bytes) wins.

Do we have to handle the case where the input is the empty array?

@ChasBrown the input is non-empty, according to the post.

Hm, I can't understand how the third test case works, care to explain please?

@EriktheOutgolfer It's effectively saying if your array is all identical numbers (e.g. [2,2,2,2,...] ) the answer should be the length of the array + 1. This is because in this case the position of the signs is irrelevant and only the number of each matter

@reffu It's more of a joke, it does look kinda like it has been included there by error.

@EriktheOutgolfer It's wasn't intended as a joke; it's an infinite number of test cases!

With the exception of the [s]*n family, all test cases can be computed as sum of elements plus one. I suggest adding test cases that fail for this formula (e.g., [2, 4, 8] and [1, 2, 27]).

You can use MathJax now!

Wolfram Language (Mathematica), 27 bytes
Tr[1^Fold[#⋃+##&,{0},#]]&

Try it online!
Finding the number of unique sign-swapping sums is equivalent to finding the number of unique subset sums.
A proof would involve adding the sum of the input to each of the sign-swapping sums and dividing by two. Then, there's an obvious bijection.
Explanation
Fold[#⋃+##&,{0},#]

Iterate through the input, with the initial value being {0}: take the union between <current value> and <current value> + input element (maps onto lists).
Tr[1^ ... ]

Golfy version of the Length function.

Jelly, 6 bytes
ŒPS€QL

Try it online!
Background
Let L be the input list and {P, N} a partition into algebraic summands with positive and negative signs. The challenge spec requires calculating s{P,N} = sum(P) - sum(N).
However, since sum(P) + sum(N) = sum(L) and sum(L) does not depend on the partition, we have s{P,N} = sum(P) - sum(N) = sum(P) - (sum(L) - sum(P)) = 2sum(P) - sum(L).
Thus, each unique value of sum(P) corresponds to one unique value of s{P,N}.
How it works
ŒPS€QL  Main link. Argument: A (array)

ŒP      Powerset; generate all subarrays of A.
  S€    Take the sum of each.
    Q   Unique; deduplicate the sums.
     L  Take the length.

MATL, 11 10 bytes
nW:qBGY*un

Try it online!
This is a port of Luis Mendo's Octave/MATLAB answer. I'm still trying to learn MATL, and I figured I'd post it, along with an explanation, since MATL is the language of the month.
Explanation:
Here's a read-through for anyone unfamiliar with stack based programming in general, and MATL in particular.
The input vector is implicitly placed on the stack. Note that when an operation is performed on an element in the stack, then that element is removed from the stack.
                % Stack:
                % [1, 2, 2]
n               % Counts the number of elements of the vector on the top of the stack.
                % Stack:
                % [3]
 W              % Raise 2^x, where x is the number above it in the stack
                % Stack:
                % [8]
  :             % Range from 1...x, where x is the number above it in the stack.                    % Stack:
                % [1, 2, 3, 4, 5, 6, 7, 8]
   q            % Decrement. Stack:
                % [0, 1, 2, 3, 4, 5, 6, 7]
    B           % Convert to binary. Stack:
                % [0,0,0; 0,0,1; 0,1,0; 0,1,1; 1,0,0; 1,0,1; 1,1,0; 1,1,1]
     G          % Push input again. Stack:
                % [0,0,0; 0,0,1; 0,1,0; 0,1,1; 1,0,0; 1,0,1; 1,1,0; 1,1,1], [1; 2; 2]
      Y*        % Matrix multiplication of the two elements on the stack.
                % Stack:
                % [0; 2; 2; 4; 1; 3; 3; 5]
        u       % Keep only unique elements. Stack:
                % [0; 2; 4; 1; 3; 5]
         n      % Number of elements in the vector. Stack:
                % [6]

And then it outputs the final element on the stack implicitly.

Nice explanation!

Python 2, 55 bytes
s={0}
for n in input():s|={t+n for t in s}
print len(s)

Try it online!

Python 2, 52 bytes
k=1
for n in input():k|=k<<n
print bin(k).count('1')

Try it online!
Uses the binary representation of a number to store the reachable subset sums.

Could you explain how this works? Did you come up with it yourself, or is it some known result?

@sundar It's not that complicated. This answer calculates the unique sums (not sign-swapping) like many other answers. Each bit in k corresponds to a sum. k<<n adds n to each sum. Oring with k stores these new sums in k whilst keeping all the previous ones, and duplicated Sims are not recorded

Ah, the trail of breacrumbs leads back to JungHwan Min's bijection idea, that was the main insight I was missing. Here each subset sum is represented by a 1 in that position in the bitstring (with the initial 1 in the LSB representing the sum 0 for the empty subset). Still not something I'd call "not that complicated", but that may just be my inexperience speaking. :)

05AB1E, 4 bytes
æOÙg

Utilizes the same approach used in Dennis’ Jelly answer.
Try it online!

R, 83 75  bytes
-8 bytes thanks to JayCe and Giuseppe
Creates a matrix of all possible combinations of (1,-1) for the size of the input vector, multiples this by the original vector to get the sums. Then unique and find the length of the result.
function(v)nrow(unique(t(t(expand.grid(rep(list(c(1,-1)),sum(v|1)))))%*%v))

previous version:
f=function(v)nrow(unique(as.matrix(expand.grid(rep(list(c(1,-1)),length(v))))%*%v))
Ungolfed with comments:
f=function(vector){

  List=rep(list(c(1,-1)),length(vector))   ## Create a list with length(vector) elements, all (1,-1)

  Combinations=expand.grid(Length)    ## get all combinations of the elements of the list, e.g, 1,-1,1,1,-1,1

  Matrix=as.matrix(Combinations)   ## convert to matrix

  Results=Matrix%*%vector   ## multiply the matrix original vector to get a Nx1 matrix

  Unique_results=unique(Results)   ## unique the results

  nrow(Unique_results)   ## length = number of rows of unique values
  }

Save some bytes with t: TIO

and sum(v|1) is a byte shorter than length(v)

Haskell, 46 bytes
import Data.List
length.nub.map sum.mapM(:[0])

Try it online!
Instead of summing the subsets of the input list, we make all combinations of either keeping a number or replacing it by 0, e.g.
mapM(:[0])[1,2,3] -> [[1,2,3],[1,2,0],[1,0,3],[1,0,0],[0,2,3],[0,2,0],[0,0,3],[0,0,0]]

This is two bytes shorter than subsequences.

Nice answer! I hoped something like f x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x] would be shorter than the import, but apparently, it isn't.

Nice, even shorter than the translation of the Mathematica one, although I think it’s prettier: import Data.List;length.foldr((<*>)union.map.(+))[0]

Pari/GP, 39 bytes
a->#[1|n<-Vec(prod(i=1,#a,1+x^a[i])),n]

Counts the number of nonzero coefficients of the polynomial \$ \prod_{i \in a}(1+x^i) \$, where \$a\$ is the input.
Try it online!

That's a cool way to do it!

Octave / MATLAB, 45 41 40 bytes
@(x)nnz(unique(dec2bin(0:2^nnz(x)-1)*x))

Input is a column vector (using ; as separator).
The code errors for the last test case due to memory restrictions.
This uses an idea from JungHwan Min's answer (subsets instead of alternating signs) to save a few bytes.
Try it online!

Python 3, 61 bytes
f=lambda a,s={0}:a and f(a[1:],s|{u+a[0]for u in s})or len(s)

Try it online!
Recursive approach, keeping track of unique subset sums.
The real fun is that this beats itertools by a big margin:
76 bytes
lambda a:len({*map(sum,product(*([0,x]for x in a)))})
from itertools import*

Try it online!

Pyth, 5 bytes
l{sMy

Utilizes the same approach used in Dennis’ Jelly answer.
Try it here.

APL (Dyalog Classic), 12 11 bytes
-1 thanks to H.PWiz
≢⊃(+∪⊢)/⎕,0

Try it online!

As has been noted in other answers, -⍨ can be ⊢

@H.PWiz thanks, very nice!

Attache, 29 bytes
{#Unique[Flat!±_]}@Fold[`±]

Try it online!
This works by folding the ± operator over the input list, then taking ± of that list, then counting the unique atoms of the array.
Here's some examples of how the folding works:
Fold[`±][ [1,2] ] == 1 ± 2
                  == [1 + 2, 1 - 2]
                  == [3, -1]
Fold[`±][ [1,2,2] ] == (1 ± 2) ± 2
                    == [3, -1] ± 2
                    == [[3 + 2, 3 - 2], [-1 + 2, -1 - 2]]
                    == [[5, 1], [1, -3]]
                    == [5, 1, 1, -3]
Fold[`±][ [4,4,4,4] ] == (4 ± 4) ± 4 ± 4
                      == [8, 0] ± 4 ± 4
                      == [[12, 4], [4, -4]] ± 4
                      == [[[16, 8], [8, 0]], [[8, 0], [0, -8]]]
                      == [16, 8, 8, 0, 8, 0, 0, -8]
                      == [16, 8, 0, -8]

Then we generate all permutations of the final sign by applying PlusMinus once more.
A more efficient version, 31 bytes
`#@(q:=Unique@Flat@`±)@Fold[q]

Try it online! This doesn't time out on the final test case, since it doesn't generate unnecessary combinations.

R, 62 bytes
function(V)sum(unique(c(V%*%combn(rep(0:1,L),L<-sum(V|1))))|1)

Try it online!
Ports Dennis' algorithm. It's closest to the Octave/MATL answers as it uses a similar bitmap and matrix product for inclusion/exclusion of terms.

Perl 5 -p, 39 bytes
s/^| /{+,-}/g;$_=grep!$s{eval$_}++,glob

Try it online!

JavaScript (ES6), 63 bytes
f=([c,...a],s=n=!(o={}))=>c?f(a,s-c)|f(a,s+c)&&n:o[s]=o[s]||++n

Try it online!

Husk, 5 bytes
LumΣṖ

Try it online!
Port of Dennis' Jelly answer.
Explanation
LumΣṖ                     [1,2,2]
    Ṗ  Powerset           [[],[1],[2],[1,2],[2],[1,2],[2,2],[1,2,2]]
  mΣ   Sum each           [0,1,2,3,2,3,4,5]
 u     Remove duplicates  [0,1,2,3,4,5]
L      Length             6

Equivalent to the Pyth answer, essentially character for character.

Perl 6, 33 bytes
{+set ([X](^2 xx$_)XZ*$_,)>>.sum}

Try it online!

Bash + GNU utilities, 49 bytes
eval echo "{,-}${@//,/{+,-\}}\;"|bc|sort -u|wc -l

Try it online!
Input given as a comma-separated list at the command-line.
Explanation
               ${@//,/{+,-\}}                      # Replace commas with {+,-}
          "{,-}${@//,/{+,-\}}\;"                   # Build a brace expansion with {+,-} before every number and ; at the end
eval echo "{,-}${@//,/{+,-\}}\;"                   # Expand to give every combination expression, separated by ;
                                |bc                # Arithmetically evaluate each line
                                   |sort -u        # Remove duplicates
                                            wc -l  # Count

C (gcc), 74 69 bytes
f(a,b)int*a;{long k=1;for(;b--;k|=k<<a[b]);a=__builtin_popcountl(k);}

Try it online!
C port of @xnor's answer

x86_64 machine language for Linux, 31 29 bytes
 0:   31 d2                   xor    %edx,%edx
 2:   6a 01                   pushq  $0x1
 4:   58                      pop    %rax
 5:   8b 0c 97                mov    (%rdi,%rdx,4),%ecx
 8:   48 89 c3                mov    %rax,%rbx
 b:   ff c2                   inc    %edx
 d:   48 d3 e3                shl    %cl,%rbx
10:   48 09 d8                or     %rbx,%rax
13:   39 d6                   cmp    %ese,%edx
15:   7c ee                   jle    5 <+0x5>
17:   f3 48 0f b8 c0          popcnt %rax,%rax
1c:   c3                      retq

Try it online!
Inspired by @xnor's answer. Requires a machine with the POPCNT instruction.

APL (Dyalog Classic), 34 33 32 bytes
{≢∪⍵+.×⍨↑{,⍵∘.,U}⍣(≢1↓⍵)⊢U←¯1 1}

Try it online!
Thanks to @ngn for -1 byte!

1-⍨≢⍵ -> ≢1↓⍵

+.×⍨ -> +.×

The latter one doesn't work, I'm afraid.

oops, I don't know why I thought you're applying +.× on vectors... sorry

Clean, 82 bytes
import StdEnv
f[]=length
f[h:t]=f t o foldr(\e l=removeDup[e+h,e-h:l])[]
?l=f l[0]

Try it online!
Defines the function ? :: [Int] -> Int using f :: [Int] -> ([Int] -> Int) as a helper to reduce over each possible sum after an addition or subtraction.

Here's a golfed version of the reference solution in Haskell; not sure how much it can carry over to Clean but you might be able to get something out of it.

@EsolangingFruit Thanks, but it's already using the same approach and I can't find a way to shorten it even with the reference solution golfed.

Java 8, 207 83 44 bytes
s->Long.bitCount(s.reduce(1L,(r,c)->r|r<<c))

Port of @xnor's Python 2 answer.
-39 bytes thanks to @Jakob.
Try it online.
s->               // Method with Long-Stream parameter and long return-type
  Long.bitCount(  //  Return the amount of 1s in the binary representation of:
    s.reduce(1L,  //   Result-Long, starting at 1
     (r,c)->      //   Loop pair-wise (result,current):
      r|          //    Bitwise-OR the result `r` with:
        r<<c))    //    result `r` bitwise left-shifted by the current `c`

44 bytes is all we need! Taking a stream of Long: s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e)).

@Jakob Thanks! I always forget about .reduce (and .bitCount as well I might add.. >.>) -39 bytes right there! :)

Also I just made an arbitrary-precision version. Looks like the cheapest way to do it is still with a bitmap rather than sets.

APL (Dyalog Classic), 21 bytes
⍴∘∪⊢+.×1-2×2(⍴⍨⊤∘⍳*)⍴

Try it online!
Explanation
2(⍴⍨⊤∘⍳*)⍴

A function train equivalent to {((⍴⍵)⍴2)⊤⍳(⍴⍵)}, which generates a matrix that has the binary representations of 0 to the length of the input as columns
1-2×

Maps 1s to -1s and 0s to 1s
⊢+.×

Matrix multiplication with the input, which gives an array of all possible sums
⍴∘∪

Remove duplicates, then count

Java 8, 85 bytes
Another Java port of xnor's answer. Like the original answer, this uses an arbitrary-precision bitmap so that there's no upper limit on the size of a subset sum.
It's a lambda from a sequential java.util.stream.Stream<Integer> to int.
s->s.reduce(java.math.BigInteger.ONE,(a,e)->a.or(a.shiftLeft(e)),(u,v)->u).bitCount()

Try It Online
Note that the combiner (the third argument to reduce) is unused since the stream is sequential. The function I chose is arbitrary.

Julia 0.6, 54 52 bytes
V->(~W=W==[]?0:∪([n=W[] -n].+~W[2:end]))(V)|>endof

Try it online!
(-2 bytes by replacing ¬ with ~, thanks to Jo King)
Works for all test cases. Makes use of broadcast to collect all possible sums, then counts them.
Explanation:
function g_(V)
  function inner(W)  #named ~ in golf version to save bytes
    W == [] ? 0 :    #return 0 when input empty (base case)
    ∪(               #unique elements of
      [n=W[] -n]     #take the first element and its negation
      .+             #broadcast-add that to each element of
      inner([2:end]) #sign-swapping sums of the rest of the array
     )
  end                #returns the list of unique elements out of those sums
  return endof(inner(V)) #return the length of that list
end

Older solution:
Julia 0.6, 64 bytes
N->endof(∪([2(i&2^~-j>0)-1 for i=0:~-2^(l=endof(N)),j=1:l]*N))

Try it online!
Works for input arrays with length upto 63 (so doesn't work for the last test case, which is fine according to OP).
Explanation:
function f_(N)
  endof(                            #length of
        ∪(                          #unique elements of
          [
           (i & 2^(j-1) > 0)        #check j'th bit (from right) of i
           * 2 - 1                  #convert bit value from (0,1)=>(-1,1)
           for i = 0:2^endof(N)-1,  #where i is numbers 0 to 2^length(N)-1
           j = 1:endof(N)           #and j is 1 to length(N) (i.e. the bits in i)
          ]                         #so we have a matrix [-1 -1 -1;1 -1 -1;1 -1 1;...]
          *                         #matrix multiply that with the input array,
          N                         #thus calculating different combinations of
         ))                         #sign-swapping sums
end

Desmos, 90 74 bytes
-16 bytes thanks to Aiden Chow!
f(A)=unique(∑_{j=1}^a(-1)^{floor([0...2^a]2/2^j)}A[j]).length
a=A.length

Try it on Desmos!
Brute-forces all possible sums; then counts the number of distinct sums.
The exact choice of + or - is encoded in the binary digits of i, ignoring the zeroth bit because Desmos arrays are 1-indexed.

74 bytes

JavaScript (Babel Node), 64 bytes
F=([f,...r],s=[0])=>f?F(r,s.flatMap(x=>[x+f,x])):new Set(s).size

Try it online!
This won't work for last testcase.

More effective solution (works on last testcase):
JavaScript (Babel Node), 71 bytes
F=([f,...r],s=[0])=>f?F(r,[...new Set(s.flatMap(x=>[x+f,x]))]):s.length

Try it online!

This won't work in a real browser due to Array#smoosh.
Thanks to Bubbler, [x+f,x-f] -> [x+f,x] saves 2 bytes.

You can use [x+f,x] in place of [x+f,x-f] (proof by JungHwan Min).

+2 bytes for ES6 version: F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size

@Neil, and... [...s,...s.map(x=>x+f)], s.concat(s.map(x=>x+f)), and, s,s.map(x=>s.push(x+f)) share same length...

Red, 73 bytes
func[b][s:[0]foreach n b[foreach m s[s: union s reduce[m + n]]]length? s]

Port of Dennis' Python 2 answer.
Does not handle the last test case.
Try it online!

Japt, 9 bytes
Saved 1 byte thanks to @Shaggy
à mx â ÊÄ

Try it online! This is a slightly modified port of Dennis' Jelly answer, credits to him for the idea. Explanation:
à             Take all non-empty subsets of the input array
  mx           and sum them
     â Ê      Return the amount of unique sums
        Ä      plus one (to account for the non-empty subset)

Save a byte with à mx â ÊÄ

Stax, 12 bytes
Çσ▓╥7Cφ1╝╥ò1

Run and debug it
Doesn't handle the last test case in acceptable time.
Explanation (unpacked):
0]s{cN\{+K$uF% Full program, implicit input
0]s            Put [0] under input (array of sums)
   {        F  Foreach:
    cN\          x -> [x, -x]
       { K       Cartesian join:
        +          Add
          $u     Flatten and unique
             % Length
               Implicit output

8 bytes Following a similar solution to what Dennis came up with using Jelly

@Multi Post it yourself, you were probably not even inspired by this one.

C (gcc), 236 208 204 bytes

Saved twenty-eight thirty-two bytes thanks to ceilingcat.

*s,i,g,n;S(w,a,p,_)int*p,*w;{if(_-a)for(_[p]=2;_[p]--;)S(w,a,p,-~_);else{for(*s=0,i=a;i--;)*s+=~(p[i]*2)*w[i];s++;}}f(w,a)int*w;{int p[a+1],r[g=1<<a];s=r;for(S(w,a,p,n=0);g--;wmemchr(r,r[g],g)||++n);w=n;}

Try it online!

@ceilingcat Thanks; did not know you could drop the int in global pointer declarations in gcc.

It is a (mis)feature of K&R, which technically shouldn't be allowed if we're using wmemchr() but gcc is very permissive.

@ceilingcat Would a strict C99 compiler not accept such K&R remnants?

Retina, 27 bytes
+`\d+ ?
*@$%"$&*
%O`.
D`
.+

Try it online!
Explanation
+`\d+ ?
*@$%"$&*

For each number, remove the space after it if there is one,. Then split the line into two, one with the number replaced with that many @s, and another with the number replaced with that many _s. Loop until no more numbers exist. That generates all combination, albeit with some duplicates.
%O`.

For each line, sort the characters. With this, there is a 1-1 correspondence between a sum and this "@_" representation.
D`

Deduplicate the lines.
.+

Count the non-empty lines.

Thunno 2 L, 3 bytes
ʠʂU

Try it online!
Explanation
ʠʂU  # Implicit input
ʠ    # Powerset
 ʂ   # Sum each
  U  # Uniquify
     # Length
     # Implicit output

Nekomata + -n, 3 bytes
ŋ∑ũ

Attempt This Online!
ŋ∑ũ
ŋ       Non-deterministically negate some elements of the input
 ∑      Sum
  ũ     Unique values

-n counts the number of possible outputs.