[Question]
  [
Given a string of N, S, E and W, output a bearing (angle clockwise from North in degrees), correct to 5 decimal places.
In [traditional compass notation](https://en.wikipedia.org/wiki/Points_of_the_compass#16-wind_compass_rose "Wikipedia article on points of the compass"), a string is made up of only 2 of these characters (like NNW or ESE). **Here you must also accept strings that contain all 4 (like WNNNSE)**. Using only 2 symbols allows humans to intuitively understand the meaning. Allowing 4 symbols makes it horrible to read, but allows shorter ways of describing a bearing to a given accuracy.
*(As pointed out in the [comments](https://codegolf.stackexchange.com/questions/99906/north-by-north-by-north-by-south-east?noredirect=1#comment242720_99906) by [user2357112](https://codegolf.stackexchange.com/users/12647/user2357112), it turns out you can prove that for any given bearing, the 4 symbol string will be exactly the same length as the 2 symbol string, so I've based this challenge on a false assumption. Hopefully this lack of a practical purpose doesn't detract from your enjoyment of the challenge...)*
The exact method is described below, and is equivalent to the traditional notation (it expands on it rather than changing it).
# Input
* The input is a single string containing only the characters `NESW`.
* The input may be a sequence of characters if you prefer, provided this does not include any preprocessing. For example, taking a nested list `[N, [E, [S, [W]]]]` to help with the order of processing is not permitted.
* Taking different characters is not permitted. You may not take a string of `1234` instead of `NESW`.
# Output
* The output must be a decimal number or string representation of one (not a rational/fraction).
* Trailing zeros do not need to be displayed. If the bearing is `9.00000`, then the output `9` also counts as correct to 5 decimal places.
* The output is in the range [0, 360). That is, including 0 but excluding 360.
* Correctness is checked by rounding the output to 5 decimal places. If the bearing is 0.000005, this rounds to 0.00001. Outputs 0.00001 and 0.000005 are both correct.
* Output in scientific notation for some inputs is acceptable. For example, `1e-5` instead of `0.00001`.
# Conversion
* The single character compass points `N`, `E`, `S`, and `W` correspond to 0, 90, 180, and 270 degrees respectively.
* Prepending one of these to a string results in the bearing that bisects the bearing of the single character and the bearing of the original string.
* The closest of the two possible bisecting bearings is chosen, so that NE represents 45 degrees, not 225 degrees.
* This is unambiguous except where the angle to be bisected is 180 degrees. Therefore `NS`, `SN`, `WE`, and `EW` correspond to undefined bearings, and the input will never end in any of these. They may however appear anywhere else in the input string, as this causes no ambiguity.
* If the final two characters are identical, the final character will be redundant as the bisection will return the same bearing. Since this adds nothing to the notation, your code does not need to handle this. Therefore `NN`, `EE`, `SS`, and `WW` correspond to undefined bearings, and the input will never end in any of these. They may however appear anywhere else in the input string.
# Examples
```
N: 0
E: 90
S: 180
SE: halfway between S and E: 135
NSE: halfway between N and SE: 67.5
NNSE: halfway between N and NSE: 33.75
NNNSE: halfway between N and NNSE: 16.875
NNNNSE: halfway between N and NNNSE: 8.4375
```
# Test cases
A submission is only valid if it gives correct output for all of the test cases. Note that the test cases push to the limits of what can be handled with double precision. For languages that default to single precision, you will probably need to spend the bytes to specify double precision in order to get correct outputs.
Test case outputs are shown rounded to 5 decimal places, and also to arbitrary precision. Both are valid outputs.
```
WNE 337.5 337.5
WEN 337.5 337.5
WEWEWEWEWEWEWEWEWEWEWEN 330.00001 330.000007152557373046875
NESWNESWNESWNESWNESWNESWNESW 90 89.99999932944774627685546875
NNNNNNNNNNNNNNNNNNNNNNNE 0.00001 0.0000107288360595703125
NNNNNNNNNNNNNNNNNNNNNNNW 359.99999 359.9999892711639404296875
SNNNNNNNNNNNNNNNNNNNNNNNE 90.00001 90.00000536441802978515625
SNNNNNNNNNNNNNNNNNNNNNNNW 269.99999 269.99999463558197021484375
```
# Scoring
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"). The score is the length of the source code in bytes, and the shortest wins.
---
# Pedantry
> 
>  I made the mistake of thinking that "North by North West" was a valid compass direction. A happy mistake, since it led to a challenge idea, but I then discovered from the [Wikipedia page](https://en.wikipedia.org/wiki/Points_of_the_compass#32-wind_compass_points "Section on the 32-wind compass points"):  
>   
> 
> *"The title of the Alfred Hitchcock 1959 movie, North by Northwest, is actually not a direction point on the 32-wind compass, but the film contains a reference to Northwest Airlines."*  
>   
> 
> It also turns out that the method used for this challenge is only consistent with traditional compass points up to and including the 16 point compass. The 32-wind compass described on that page is subtly different and I have conveniently overlooked its existence for this challenge.  
>   
> 
> Finally, for anyone who thinks I should use "Southeast" instead of "South East", it [seems to be a regional difference](https://english.stackexchange.com/questions/73712/is-there-some-difference-between-north-east-and-northeast "English Language & Usage Stack Exchange").
> 
> 
> 
  
[Answer]
# JavaScript (ES6), ~~84~~ ~~80~~ ~~78~~ ~~74~~ 72 bytes
*Saved a byte thanks to @Titus, 1 thanks to @Neil*
```
f=([c,...s],b="NESW".search(c))=>b*90-(s[0]?(b-=f(s)/90)-4*(b*b>4):0)*45
```
It took a while, but I think I've finally perfected the formula...
### Test snippet
```
f=([c,...s],b="NESW".search(c))=>b*90-(s[0]?(b-=f(s)/90)-4*(b*b>4):0)*45
g=(s,n)=>console.log('f("'+s+'"):',f(s),"expected:",n)
g("N", 0)
g("NE", 45)
g("E", 90)
g("SE", 135)
g("S", 180)
g("SW", 225)
g("W", 270)
g("NW", 315)
g("WNE", 337.5)
g("WEN", 337.5)
g("WEWEWEWEWEWEWEWEWEWEWEN", 330.00001)
g("NESWNESWNESWNESWNESWNESWNESWNESWNESWNESWNESWNESWNESW", 90)
g("NNNNNNNNNNNNNNNNNNNNNNNE", 0.00001)
g("NNNNNNNNNNNNNNNNNNNNNNNW", 359.99999)
g("SNNNNNNNNNNNNNNNNNNNNNNNE", 90.00001)
g("SNNNNNNNNNNNNNNNNNNNNNNNW", 269.99999)
```
### Explanation
Let's start with the simplest case: a single-char string. The result is simply its (0-indexed) position in the string `NESW`, multiplied by 90.
For a two-char string, the result lies halfway between the result of the first char and the result of the second. However, there's a catch: if the absolute difference between the two is greater than 180 (e.g. `NW` or `WN`), we must 180 to the angle so that it's not pointing the opposite direction.
For any longer string, the result lies halfway between the result of the first char and the result of the rest of the string. This can be generalized in the following way:
* If the input is a single char, return its index in the string `NESW` times 90.
* Otherwise, return the index of the first char in the string `NESW` times 45, plus half the result of the rest of the string; add an extra 180 if the absolute difference between the two is greater than 90.
[Answer]
## C#6, ~~226~~ ~~217~~ ~~207~~ 185 bytes
```
using System.Linq;double N(string s){double b=f(s.Last());foreach(var c in s.Reverse()){b=(b+f(c)+(b-f(c)>2?4:f(c)-b>2?-4:0))/2;b=(b+4)%4;}return b*90;}int f(char x)=>"NESW".IndexOf(x);
```
Edit: -10 bytes by "borrowing" idea from ETHproductions's submission  
-22 bytes thanks to @Titus
Ungolfed
```
// Call this method
double N(string s){
    // Initialize bearing with last direction
    double b=f(s.Last());
    // Do backward. Doing last direction once more doesn't impact result
    foreach(var c in s.Reverse()){
        // Average current bearing with new bearing, adjusted with wrapping
        b=(b+f(c)+(b-f(c)>2?4:f(c)-b>2?-4:0))/2;
        // Make bearing back to range [0,4)
        b=(b+4)%4;
    }
    // Change from "full circle = 4" unit to degree
    return b*90;
}
// helper method to convert direction to bearing. This returns bearing with full circle = 4.
int f(char x)=>"NESW".IndexOf(x);
```
[Answer]
# PHP, ~~95~~ ~~88~~ ~~86~~ ~~100~~ ~~127~~ ~~104~~ 101 bytes
* -7 bytes with the null coalescing operator
* -2 bytes by not replacing `N` (and more, because that allows to put the translation to the loop head: `N` is truthy, but evaluates to `0` in the calculation.)
* +41 bytes for fixing the bisection (*cough*)
* -7 bytes directly and -16 indirectly inspired by @ETHproductions´ code
* -3 bytes by replacing `strtr` with one of my bit jugglings
---
```
for($i=strlen($s=$argv[1]);$i--;$p=($q+$p=$p??$q)/2+2*(abs($q-$p)>2))$q=ord($s[$i])/.8+3&3;echo$p*90;
```
This is officially the first time ever that I use the null coalescing operator. Run with `-r`.
## PHP 7.1
Negative string offsets in the upcoming PHP version will save 12 bytes:  
Replace `strlen($s=$argv[1])` with `0` and `$s` with `$argv[1]`.
---
[Answer]
## Python 3, 133 113 bytes
Just improving on @L3viathan's answer because I just made this account and therefore can't make comments yet.
```
d={"N":0,"E":.5,"S":1,"W":1.5}
def B(s):
 b=d[s[-1]]
 for c in s[::-1]:b=(b+d[c])/2+(abs(b-d[c])>1)
 return b*180
```
[Answer]
# [05AB1E](http://github.com/Adriandmen/05AB1E), ~~48~~ ~~42~~ ~~37~~ 32 bytes
Saved 6 bytes thanks to Emigna.
Saved 5 bytes thanks to Titus' idea to work on range [0,4[ and multiply by 90 at the end.
Saved 5 bytes thanks to Adnan's mastery of ancient xor/modulo metamorphosis.
So every angle is reduced from range [0,360[ to range [0,4[ throughout the execution. Result is then multiplied by 90 and displayed.
```
Ç30^5%R¬U¦vXy+;DX-Ä0›2*+4%U}X90*
It can be divided into two sequentially called subprograms.
First program: convert input string into an array of the corresponding angles in range [0,4[
Ç      Take the ascii value of all input characters
 30^5% Dark ascii manipulation that yields [0,1,2,3] for [N,E,S,W]
Now we have an array of integers in range [0,4[.
Second program: actually compute the final angle
R                          Reverse the array
 ¬                         Take the first value (the last of the non-reversed array)
  U                        Pop it from the stack and set X to the same value
   ¦                       Strip the first element
    v                      For each remaining element
     Xy+;                  Compute the average value between the leftmost value and X
         DX-Ä0›            Push 1 if angular distance cast to integer is > 0 (i.e. if it is >= 1), 0 otherwise. It's equivalent to checking >= 90 degrees
               2*+         Multiply by 2 (=2 if angular distance is >= 1 and 0 otherwise) and add it to the formerly computed average value. It's equivalent to multiplying by 180
                  4%       Perform mod 4. It's equivalent to performing mod 360
                    U      Store the result back to X
                     }     End for, mandatory if input has only one character
                      X90* Push X*90 and implicitly display it
```
[Try it online!](http://05ab1e.tryitonline.net/#code=w4czMF41JVLCrFXCpnZYeSs7RFgtw4Qw4oC6MiorNCVVfVg5MCo&input=TkVTV05FU1dORVNXTkVTV05FU1dORVNXTkVTV05FU1dORVNXTkVTV05FU1dORVNXTkVTVw)
Potential axes of golfing:
* Not sure if that mod 4 is required (it would save 2 bytes). All test cases work without it, but maybe there exists a tricky case. A mathematical proof to either validate it or nullify it would be top-notch.
* There is no implicit stuff besides displaying the result (closing quote marks, closing brackets).
[Answer]
# Python 3, ~~146~~ ~~145~~ ~~117~~ ~~107~~ ~~97~~ ~~94~~ ~~93~~ 92 bytes
```
f(s):u='NESW'.find(s[0])*90;return(u+f(s[1:]))/2+180*(abs(u-‌​f(s[1:]))>180)if s[1:]else u
```
Call `f` with the string.
[Answer]
# C, 184 bytes
```
double h(char c){return ((c=='E')+(c=='S')*2+(c=='W')*3);}double d(char*s){double f=h(*s);if(s[1]){double t=f;f=(f+d(s+1)/90)/2;if(((t-f)>1)||((f-t)>1))f+=2;if(f>=4)f-=4;}return f*90;}
```
**Ungolfed**
```
// a helper function
double direction_(char ch)
{
    if (ch=='N')
        return 0.;
    else if (ch=='E')
        return 90.;
    else if (ch=='S')
        return 180.;
    else
        return 270.;
}
// this is the main function to call
double direction(char* str)
{
    double fAngle = direction_(str[0]);
    if (str[1])
    {
        double tmp = fAngle + direction(str+1);
        if (tmp>=360.)
            tmp-=360.;
        tmp/=2;
        if (((tmp-fAngle)>90.) || ((tmp-fAngle)<-90.))
        { //  check if we need to take the "other side"; if the resulting angle is more than 90 degrees away, we took the wrong on
            if (tmp>=180.)
                tmp-=180.;
            else
                tmp+=180.;
        }
        fAngle = tmp;
    }
    return fAngle;
}
```
[Answer]
## R, 172 146 bytes
```
z=rev((0:3*90)[match(scan(,""),c("N","E","S","W"))]);p=z[1];l=length(z);for(i in 2:l)p=(p+z[i])/2+(abs(p-z[i])>180)*180;if(l<2)p=z;sprintf("%f",p)
```
**Ungolfed**
```
z=rev((0:3*90)[match(scan,""),c("N","E","S","W"))]); #1
p=z[1];                                              #2
l=length(z)                                          #3
for(i in 2:l)p=(p+z[i])/2+(abs(p-z[i])>180)*180;     #4
if(l<2)p=z                                           #5
sprintf("%f",p)                                      #6
```
**Explained**
1. Read input from stdin
	* Match input by index to `c("N","E","S","W")`
	* From matched indices: match to the vector of degrees `0:3*90` (instead of `c(0,90,180,270)`)
	* Reverse and store as `z`
2. Initialize `p` to the degree equivalent to last char in input
3. Store length of input as `l`
4. Iteratively, calculate the closest of the two possible bisecting bearings.
5. If only one input is given, set `p` to `z`
6. Format and print
[Try the test cases on R-fiddle](http://www.r-fiddle.org/#/fiddle?id=We13B66f&version=1)
(note that this is a function due to `scan` not working on R-fiddle)
[Answer]
# Haskell, ~~109 105~~ 103 bytes
```
h=180
a#b|abs(a-b)<h=n|n>h=n-h|1>0=n+h where n=(a+b)/2 -- calculates the new "mean" on the cirlce
f 'N'=0                                          -- translates characters to angles
f 'E'=90
f 'S'=h
f _=270
foldr1(#).map f                                  -- traverses the whole string
```
Thanks for -2 byte @xnor!
[Answer]
# [Dyalog APL](http://goo.gl/9KrKoM), ~~55~~ ~~45~~ 38 [bytes](http://meta.codegolf.stackexchange.com/a/9429/43319)
### Solution
Requires `⎕IO←0`, which is default on many systems. Asks for direction.
```
360|÷○÷180×12○(+÷(|+))/¯12○○2÷⍨'NES'⍳⍞
```
### Explanation
Goes around the problem by converting each letter to a complex number 1∠*θ* ⇔ *a* + *b · i*, then doing a sum reduction from right-to-left (APL's forte) while normalizing at each step. The final *θ* is then converted to degrees and normalized to be within [0, 360):
`'NES'⍳⍞` the indices of each input letter in "NES"; N→0, E→1, S→2, anything else→3
`○2÷⍨` convert to angles in radians; *θ* = *π* · ***x***∕2
`¯12○` convert to complex numbers on the unit circle; *ei · θ*
`(`...`)/` reduce the list with... (i.e. insert the function between the elements of...)
 `+÷(|+)` ... the normalized sum; ***x****n* - 1 + ***x***n∕|***x****n* - 1 + ***x***n|
`12○` convert to angle; *θ*
`÷○÷180×` convert to degrees; 1∕*π* · 1∕180 · ***x***
`360|` division remainder when divided by 360
[TryAPL online!](http://tryapl.org/?a=%u2395IO%u21900%20%u22C4%20%7B360%7C%F7%u25CB%F7180%D712%u25CB%28+%F7%28%7C+%29%29/%AF12%u25CB%u25CB2%F7%u2368%27NES%27%u2373%u2375%7D%A8%27WNE%27%20%27WEN%27%20%27WEWEWEWEWEWEWEWEWEWEWEN%27%20%27NESWNESWNESWNESWNESWNESWNESWNESWNESWNESWNESWNESWNESW%27%20%27NNNNNNNNNNNNNNNNNNNNNNNE%27%20%27NNNNNNNNNNNNNNNNNNNNNNNW%27%20%27SNNNNNNNNNNNNNNNNNNNNNNNE%27%20%27SNNNNNNNNNNNNNNNNNNNNNNNW%27&run)
### Anecdote
If input and output was as orthogonal complex units, the entire solution would be just:
```
(+÷(|+))/
```
The rest of the code is parsing input and formatting output.
[Answer]
# Common Lisp, ~~347~~ 327 bytes
*Thanks to @Titus for taking off a few*
This can probably be golfed more, but at least it works (I think):
```
(defun d(c)(if(eql c #\N)0(if(eql c #\E)1(if(eql c #\S)2(if(eql c #\W)3)))))(defun m(a b)(if(> a b)(rotatef a b))(if(<(+(- 4 b)a)(- b a))(+(/(+(- 4 b)a)2)b)(+(/(- b a)2)a)))(defun f(s)(let((c))(setf c(d(char s(1-(length s)))))(do((a)(p(-(length s)2)(1- p)))((< p 0))(setf a(char s p))(setf c(m(d a)c)))(format t"~5$"(* c 90))))
```
Usage:
```
* (f "WNE")
337.50000
NIL
```
Function `d` takes a character `N`, `E`, `W`, or `S` and returns the appropriate degree. Function `m` gets the approprate combined degree of two given directions. Function `f` iterates through the provided string, computes the appropriate degree, and prints it as a floating point. 
[Answer]
# Befunge, ~~183~~ ~~181~~ 175 bytes
```
>~#+:#25#%6*#/`#2_$>5%4*:00p"Z}"4*:***20g#v_+2/00g10g-:8`\0\-8`+!v
v5:+*:*:"d"/+55+5$_^#!:\p01/**:*4"}Z":p020<%**:*"(2Z"+**5*:*"0}"!<
>5>+#<%#56#58#:*#/+\#5:#5_$$$,,,".">:#,_@
```
[Try it online!](http://befunge.tryitonline.net/#code=Pn4jKzojMjUjJTYqIy9gIzJfJD41JTQqOjAwcCJafSI0KjoqKioyMGcjdl8rMi8wMGcxMGctOjhgXDBcLThgKyF2CnY1OisqOio6ImQiLys1NSs1JF9eIyE6XHAwMS8qKjoqNCJ9WiI6cDAyMDwlKio6KiIoMloiKyoqNSo6KiIwfSIhPAo-NT4rIzwlIzU2IzU4IzoqIy8rXCM1OiM1XyQkJCwsLCIuIj46IyxfQA&input=U05OTk5OTk5OTk5OTk5OTk5OTk5OTk5OVw)
**Explanation**
This follows a similar algorithm to many of the other answers, only it's using fixed point calculations emulated with integers since Befunge doesn't support floating point.
Thanks to [@Titus](https://codegolf.stackexchange.com/users/55735/titus) for the ASCII-to-int routine.
```
 ~ : 5 6* ` _$        while ((c = getchar()) > 30)  // ends with any ctrl char or EOF
> + 2 %6 / 2            push(c / 2 % 6 + 2)         // partial conversion to int
                      do {
  5%                    dir = pop() % 5             // completes the conversion to int   
  4*:00p                dir *= 4; lowres_dir = dir  // used by the 180-flip calculation
  "Z}"4*:***            dir *= 22500000             // this is 90000000 / 4 
  20g_                  if (!first_pass) {
    +2/                   dir = (dir+last_dir)/2    // last_dir is second item on stack
    00g10g-               diff = lowres_dir - last_lowres_dir
    :8`\0\-8`+!!          flip = diff>8 || -diff>8
    "}0"*:*5**+           dir += flip * 180000000   // add 180 degrees if we need to flip
    "Z2("*:**%            dir %= 360000000          // keep within the 360 degree range
                        }
  020p                  first_pass = false
  :"Z}"4*:**/10p        last_lowres_dir = dir / 22500000
  \                     last_dir = dir              // saved as second item on stack
  :!_                 } while (!stack.empty())
$                     pop()                         // this leaves the final dir on top
5+55+/                dir = (dir + 5)/10            // round down to 5 decimal places
"d":*:*+              dir += 100000000              // add a terminating digit
                      while (true) {                // convert into chars on stack
:55 + % 6 8 * +\ : _    push(dir%10+'0'); if (!dir) break
   > < 5 5 : /+ 5 5     dir /= 10
                      }
$$$                   pop() x 3                     // drop the chars we don't need
,,,                   putchar(pop()) x 3            // output first three chars
"."                   push('.')                     // add a decimal point
>:#,_@                while(c=pop()) putchar(c)     // output the remaining chars
```
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), ~~30~~ 27 bytes
```
90×(4|2÷⍨+-4×2<∘|-)/'NES'⍳⎕
```
[Try it online!](https://tio.run/##fY89TwJBEIZ7fsV1q9HD/ZqdXWNLS0NBfYGcIV48c1xjgM4ofhyxMdhYaGVvCAmJFf9k/8g552FiAcxmMjuZ99l3J7pKwv51lKTnYS@JhsNBr/Szl0Hqb595w0/v4tLx9fxAj@V66YvPo1Cv5/LMT1/H4eEJa7c6zBdfRJSkLWOifDET/umbTUbsmNGgyoxEC@YfPmiypL6XsZgFvngL8izqx5dBngZUGjnxI5L6@/eMrrEvVqcsvWD@8YbF0SChZ1Y0ziYN1m23WB4ohU2gptX@32w7tYA3eRUoQAKgQsW1sUgQLdLdlURa13S/oaTTGlEbicYC/NHbo/ph7Sg4SmuV4eAAuRJyN1TZKaj9rJMohFFOcy1d7dXZY@Y2@4EyWgvLpUMLAozcw1V@0mz200YBWOGQS6GtVgg/ "APL (Dyalog Classic) – Try It Online")
]