[Question]
  [
Don't ask me how or why but while coding on a project I noticed that the characters of a couple of words had a particular pattern referred to the alphabet, I connected each character of the words with the pencil on the alphabet and I obtained two spirals, then I noticed that the first spiral was clockwise and the other was counterclockwise, and other characteristics... so I named them ***Swirling Words***!
A *Swirling Word* can be:
1. clockwise or counterclockwise
2. centripetal or centrifugal
Here there are some examples of *Swirling Words*:
[![Swirling Words Diagram](https://i.stack.imgur.com/qGedt.png)](https://i.stack.imgur.com/qGedt.png)
### Task 1:
Write a full program or function that will take a word from standard input and will output if is a *Swirling Word* and it's characteristics, in a readable format, extended text, 3 characters, flags, etc.
Test cases and example outputs for different words (but you can decide how to represent the results): 
```
EARTH, GROUP            > NO        // NOT A SWIRLING WORD
OPERA, STAY, IRIS       > SW,CF,CW  // SWIRLING WORD, CENTRIFUGAL, CLOCKWISE
MINER, TAX, PLUG, META  > SW,CF,CC  // SWIRLING WORD, CENTRIFUGAL, COUNTERCLOCKWISE
AXIOM, AXIS, COOK       > SW,CP,CW  // SWIRLING WORD, CENTRIPETAL, CLOCKWISE
WATCH, YETI, PILL       > SW,CP,CC  // SWIRLING WORD, CENTRIPETAL, COUNTERCLOCKWISE
MORE EXAMPLES OF FALSE TEST CASES (NOT SWIRLING WORDS): 
EARTH, GROUP, OUTPUT, WORD, CONNECTION, ODD, MOM, DAD, 
CHARACTER, EXAMPLE, QUESTION, NEWSLETTER, OTHER
```
### Rules:
1. The connection between the first two characters must be *up* (like in the graphics), all the even connection must be *down*, all the odd connections must be *up*.
2. You can ignore upper/lowercase or consider/convert all to upper case or all to lower case.
3. The input words are only characters in the alphabet range of A-Z, no spaces, no punctuation, etc.
4. If a word has double characters, like "GROOVE", you must collapse the doubles to one character: "GROOVE" > "GROVE".
5. The input words will contain at least 3 distinct characters. Words like "MOM", "DAD", "LOL" are not valid words.
6. It's possible to pass multiple times in the same character, like "IRIS".
7. Shortest code wins.
### Task 2:
To obtain more reputation, find the longest *Swirling Words*, and it's characteristics, that you can find in the english dictionary, following the above rules. You can take for example as reference the complete list of the english words [here](https://github.com/dwyl/english-words).
Happy coding!
  
[Answer]
# [MATL](http://github.com/lmendo/MATL), ~~33~~ ~~31~~ 30 bytes
```
lydhg)dt|dZSXz&=wZSdh?4M1)3M1)
```
Input is in uppercase letters (or in lowercase letters, but not mixed).
Output is:
* If the word is non-swirling: no output is produced
* If it is swirling: two numbers are produced in different lines:
	+ First number `1`/ `-1` indicates centrifugal / centripetal.
	+ Second number `1`/ `-1' indicates clockwise / counterclockwise.
[Try it online!](http://matl.tryitonline.net/#code=bHlkaGcpZHR8ZFpTWHomPXdaU2RoPzRNMSkzTTEp&input=J1BJTEwn) Or [verify all test cases](http://matl.tryitonline.net/#code=alliIkBnCmx5ZGhnKWR0fGRaU1h6Jj13WlNkaD80TTEpM00xKWg&input=RUFSVEggR1JPVVAgT1BFUkEgU1RBWSBJUklTIE1JTkVSIFRBWCBQTFVHIE1FVEEgQVhJT00gQVhJUyBDT09LIFdBVENIIFlFVEkgUElMTA) (code modified to take all inputs and to produce the two output numbers on the same line)
### Explanation
Let's take input `'OPERAA'` as an example.
The first part of the code removes double letters:
```
l     % Push 1
      %   STACK: 1
y     % Take input implicitly from below, and duplicate
      %   STACK: 'OPERAA', 1, 'OPERAA'
d     % Convert to code points and compute differences
      %   STACK: 'OPERAA', 1, [1 -11  13 -17 0]
h     % Concatenate horizontally
      %   STACK: 'OPERAA', [1 1 -11  13 -17 0]
g     % Convert to logical
      %   STACK: 'OPERAA', [true true true true true false]
)     % Index
      %   STACK: 'OPERA'
```
We now check if the distances between letters are non-decreasing (necessary condition for the word to be swirling):
```
d     % Convert to code points and compute differences
      %   STACK: [1 -11  13 -17]
t|    % Duplicate and take absolute value
      %   STACK: [1 -11  13 -17], [1 11  13 17]
d     % Differences
      %   STACK: [1 -11  13 -17], [10 2 4]
ZS    % Signum
      %   STACK: [1 -11  13 -17], [1 1 1]
Xz    % Remove zeros (gives a vertical vector). Needed for words like 'IRIS',
      % where some consecutive distances are equal
      %   STACK: [1 -11  13 -17], [1; 1; 1]
&=    % All pairwise equality comparisons. Gives a matrix. If all the signs 
      % were equal the matrix will contain all ones
      %   STACK: [1 -11  13 -17], [1 1 1; 1 1 1; 1 1 1]
```
We then check if the letters go back and forth (this is the other condition for the word to be swirling):
```
w     % Swap
      %   STACK: [1 1 1; 1 1 1; 1 1 1], [1 -11  13 -17]
ZS    % Signum
      %   STACK: [1 1 1; 1 1 1; 1 1 1], [1 -1 1 -1]
d     % Differences
      %   STACK: [1 1 1; 1 1 1; 1 1 1], [-2 2 -2]
```
Lastly, we check if the two conditions hold, and in that case produce the output:
```
h     % Concatenate horizontally
      %   STACK: [1 1 1 1 1 1 1 1 1 -2 2 -2]
?     % If all elements are nonzero
  4M  %   Push first signum array without zeros, from the automatic clipboard
      %     STACK: [1; 1; 1]
  1)  %   Get first element (tells if first difference was positive or negative)
      %     STACK: 1
  3M  %   Push second signum array, from the automatic clipboard
      %     STACK: 1, [1 -1 1 -1]
  1)  %   Get first element (tells if first movement was right or left)
      %     STACK: 1, 1
      %   Implicitly end if
      % Implicitly display
```
[Answer]
# Mathematica, ~~117~~ 111 bytes
*Thanks to JHM for saving 6 bytes, and making it case-insensitive to boot!*
```
 {o=OrderedQ/@{a=Abs[d=Differences[#&@@@Split@LetterNumber@#]],Reverse@a},d[[1]]>0,Or@@o&&Max[Most[d]Rest@d]<0}&
```
Unnamed function that takes a string and returns a nested list of booleans in the form `{{B1,B2},B3,B4}`. B4 records whether the word is swirling (and if it's not, the rest of the output is garbage). If the word is swirling, then B1 records whether the word is centrifugal, B2 records whether the word is centripetal, and B3 records whether the word is clockwise (True) or counterclockwise (False).
Here's a longer version that post-processes (first line) the above function (spaced over the 2nd-5th lines) to make it identical to the OP: `NO` if the word isn't swirling, and the appropriate choice of `{SW,CF,CW}` , `{SW,CF,CC}` , `{SW,CP,CW}`, or `{SW,CP,CC}` if the word is swirling:
```
If[#3, {SW, If[#[[1]], CF, CP], If[#2, CW, CC]}, NO] & @@
  {o = OrderedQ /@
    {a = Abs[d = Differences[# & @@@ Split@LetterNumber@#]], Reverse@a},
  d[[1]] > 0,
  Or @@ o && Max[Most[d] Rest@d] < 0} &
```
The explanation is the same as in Martin Ender's CJam answer, with one additional note: the list of consecutive differences must alternate in sign for the word to be swirling, and that can be detected by making sure all products of pairs of consecutive differences are negative (that's what `Max[Most[d]Rest@d]<0` does).
Running the function on all 40,000+ words of Mathematica's `WordList[]`, we find the following 8-letter swirling words, which are the longest of their respective swirling types:
```
operetta    {SW, CF, CW}
opposite    {SW, CF, CW}
stowaway    {SW, CF, CW}
assassin    {SW, CP, CW}
assessor    {SW, CP, CW}
baccarat    {SW, CF, CC}
keenness    {SW, CF, CC}
positive    {SW, CF, CC}
```
(Brownie points to `positive` for having no double letters, and fewer repeated letters than `stowaway`.)
But the absolute champion is the 9-letter counterclockwise-swirling centripetal word `vassalage`!
[Answer]
# Scala, 110 bytes
```
def/(s:String)={val ? =s.sliding(2).map(t=>(t(0)-t(1)).abs).toSeq
(Seq(?,?reverse)indexOf(?sorted),s(0)<s(1))}
```
Returns a tuple `(a,b)` with
* `a == 1` if s is centripetal
* `a == 0` if s is centrifugal
* `a == -1` if s is not swirling
and
* `b == true` if s is clockwise
* `b == false` if s is counterclockwise
* b can be true or false if s is not swirling
Explanation:
```
def/(s:String)={      //define a method called / with a String argument
  val ? =s            //define ? as...
    .sliding(2)       //an iterator for each two consecutive elements
    .map(t=>          //foreach 2 chars
      (t(0)-t(1)).abs //get the absolute value of their difference
    ) 
    .toSeq            //and convert the iterator to a Seq, because iterator doesn't have reverse and sorted methods
  (                   //return a tuple of
    Seq(?,?reverse)     //a Seq of ? and reversed ?
    .indexOf(?sorted)   //and check which of them is sorted ?
  ,                   //and
   s(0)< s(1)          //the difference bewteen the first two elements of the string.
  )
}
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~30~~ 23 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
OIḟ0µAI©Ṡḟ0ṂṭḢṠ$µ®ḟ0ṠEṭ
```
**[Try it online!](https://tio.run/##y0rNyan8/9/f8@GO@QaHtjp6Hlr5cOcCEOfhzqaHO9c@3LEIyFc5tPXQOojgAleg6P///xMrMvNzAQ "Jelly – Try It Online")** Or see the [test cases](https://tio.run/##y0rNyan8/9/f8@GO@QaHtjp6Hlr5cOcCEOfhzqaHO9c@3LEIyFc5tPXQOojgAleg6P/D7UcnPdw5Q/NR446je9z//49WSk0sKslQ0lFKL8ovLQDS@QWpRYlAurgksRJIZRZlFgOp3My81CIgXZJYASQLckrTQYKpJSCViRWZ@bkQGqQ0OT8/G0iVJ5Ykg8ytTC3JBGnJzMlRiuUCAA "Jelly – Try It Online")
All upper or all lower.  
Returns a flag list `[D, F, S]`:  
`D`: clockwise = `1` / anticlockwise = `-1`  
`F`: centrifugal = `1` / centripetal = `-1`  
`S`: spinning = `1` / not spinning = `0`  
- if `S` is `0` the other flags are still evaluated even though they carry no useful information.
### How?
```
OIḟ0µAI©Ṡḟ0ṂṭṠḢ$µ®ḟ0ṠEṭ - Main link: s
O                       - ordinals
 I                      - deltas (i.e. [a,b,c,...] -> [b-a,c-b,...])
  ḟ0                    - filter out zeros
                        - (call this Z)
    µ                   - start a new monadic chain (i.e. f(Z))
     A                  - absolute values
      I                 - deltas
       ©                - copy to register
        Ṡ               - signs
         ḟ0             - filter out zeros
           Ṃ            - minimum
                        - (i.e. F = {centrifugal: 1; centripetal: -1})
               $        - last two links as a monad:
             Ḣ          -   head (Z)
              Ṡ         -   sign
                        - (i.e. D = {clockwise: 1; anticlockwise: -1})
            ṭ           - tack
                µ       - start a new monadic chain (i.e. f([D,F]))
                 ®      - recall from register
                  ḟ0    - filter out zeros
                    Ṡ   - signs
                     E  - all equal?
                        - (i.e. S = {spinning: 1; not spinning: 0})
                      ṭ - tack
                        - (i.e. [D,F,S])
```
[Answer]
# [CJam](http://sourceforge.net/projects/cjam/), 39 bytes
```
r{2ew::-V}:D~-_:g_0=\D#)!@:zD-:g_0=\(-!
```
[Try it online!](http://cjam.tryitonline.net/#code=cnsyZXc6Oi1WfTpEfi1fOmdfMD1cRCMpIUA6ekQtOmdfMD1cKC0h&input=T1BFUkE)
The input can be uppercase or lowercase, but not mixed.
The program inadvertently points out words which are not necessarily centrifugal or centripetal, but otherwise meet the requirements of being spiral. These are described as "circular" in the chart below.
**To interpret the output use this chart:**
```
SPIRAL (output contains four 1s)
-11-11 : Clockwise Centrifugal
-1111  : Clockwise Centripetal
11-11  : Counter-clockwise Centrifugal
1111   : Counter-clockwise Centripetal
CIRCULAR (output contains two 1s)
-11    : Clockwise Circular
11     : Counter-clockwise Circular
NONSPIRAL (output contains a 0)
```
  
**Explanation:**
The program actually evaluates whether the sequence of non-zero differences between characters starts off positive or negative, if it alternates in sign, if the magnitudes start off increasing or decreasing, and if it continues to do so. If the magnitudes don't increase or decrease then the program breaks by operating on an empty array. The major steps are shown below (this code will also show the progress of the stack):
```
r{2ew::-V}:D~-   e# take difference of overlapping pairs, removing 0s handles duplicates
               ede# store difference function plus 0 as D, it's multipurpose
_:g_0=\          e# compute signs differences, keep first to show starting direction
               ede# -1 = CLOCKWISE, 1 = COUNTERCLOCKWISE
D#)!@            e# difference of signs includes 0 if not alternating, keep in stack
               ede# 1 = ALTERNATING, 0 = NOT ALTERNATING
:zD-:g           e# signs of difference of absolute values, ignoring 0s (fixed magnitude)
_0=\             e# keep first sign in stack to indicate how the sequence starts
               ede# -1 = INCREASING, 1 = DECREASING
(-!              e# remove first item from entire list and see if nothing remains
               ede# 1 = EMPTY(MONOTONE), 0 = NONEMPTY
```
[Answer]
# PHP, 322 Bytes
```
for(;++$i<strlen($z=preg_replace("#(.)\\1#","$1",$argv[1]));){$t[]=$z[$i-1]<=>$z[$i]?:0;$o[]=$z[0]<=>$z[$i];$i<2?:$k[]=$z[$i-2]<=>$z[$i];}$s=preg_match("#^1?(-11)*(-1)?$#",join($t))?($t[0]!=1?1:2):0;$s+=2*preg_match($r="#^(-1|0)?([01](-1|0))*[01]?$#",join($o));$s*=preg_match($r,join($k));count_chars($z,3)[2]?:$s=0;echo$s;
```
for a more pretty Output `echo["n","+P","-P","+F","-F"][$s];`
Expanded version
```
for(;++$i<strlen($z=preg_replace("#(.)\\1#","$1",$argv[1]));){
    $t[]=$z[$i-1]<=>$z[$i]?:0;
    $o[]=$z[0]<=>$z[$i];
    $i<2?:$k[]=$z[$i-2]<=>$z[$i];
    }
$s=preg_match("#^1?(-11)*(-1)?$#",join($t))?($t[0]!=1?1:2):0; #Clockwise direction or not
$s+=2*preg_match($r="#^(-1|0)?([01](-1|0))*[01]?$#",join($o)); # True centrifugal
$s*=preg_match($r,join($k)); #true or false second test for not
count_chars($z,3)[2]?:$s=0; # word must have >2 different characters
echo$s;# short output
echo["n","+P","-P","+F","-F"][$s]; #long output alternative
```
## Task 2 second value without short doubles rule
> 
> 4 -F killingness 11 Bytes positivize 10 Bytes
> 
> 
> 3 +F oppositive 10 Bytes logogogue 9 Bytes
> 
> 
> 2 -P vassalage 9 Bytes sarcocol,sasarara 8 Bytes
> 
> 
> 1 +P assession 9 Bytes apanage, aramaic, argonon, auction, avision, awarded, crenele, exesion, exition, eyewink
>  7 Bytes
> 
> 
> 
## Visualize a word
```
header('Content-Type: image/svg+xml; charset=UTF-8');
$w=$_GET["w"]??"OOPERRA";
$w=strtoupper($w);
echo '<?xml version="1.0" encoding="UTF-8"?>'
.'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
.'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 -100 420 400">'
.'<title>Swirl Word</title><desc>Viualize a Word</desc>';
echo '<text x="210" y="-50" text-anchor="middle" font-family="arial">'.$w.'</text>';
foreach(range("A","Z")as $x=>$c){
    echo '<text x="'.(15+$x*15).'" y="110" text-anchor="middle" font-family="arial">'.$c.'</text>';
    $r[$c]=15+$x*15;
}
for($i=0;++$i<strlen($w);){
    echo '<path d="M '.($r[$w[$i-1]]).',105 A '.($radius=abs($r[$w[$i]]-$r[$w[$i-1]])/2).' '.($radius).' 0 0 0 '.($r[$w[$i]]).',105" style="stroke:gold; stroke-width:1px;fill:none;" />';
}
echo '</svg>';  
```
in the snippet is the result of the SVG I have create
```
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 -100 420 400"><title>Swirl Word</title><desc>Viualize a Word</desc><text x="210" y="-50"  text-anchor="middle" font-family="arial">KILLINGNESS</text><text x="15" y="110" text-anchor="middle" font-family="arial">A</text><text x="30" y="110" text-anchor="middle" font-family="arial">B</text><text x="45" y="110" text-anchor="middle" font-family="arial">C</text><text x="60" y="110" text-anchor="middle" font-family="arial">D</text><text x="75" y="110" text-anchor="middle" font-family="arial">E</text><text x="90" y="110" text-anchor="middle" font-family="arial">F</text><text x="105" y="110" text-anchor="middle" font-family="arial">G</text><text x="120" y="110" text-anchor="middle" font-family="arial">H</text><text x="135" y="110" text-anchor="middle" font-family="arial">I</text><text x="150" y="110" text-anchor="middle" font-family="arial">J</text><text x="165" y="110" text-anchor="middle" font-family="arial">K</text><text x="180" y="110" text-anchor="middle" font-family="arial">L</text><text x="195" y="110" text-anchor="middle" font-family="arial">M</text><text x="210" y="110" text-anchor="middle" font-family="arial">N</text><text x="225" y="110" text-anchor="middle" font-family="arial">O</text><text x="240" y="110" text-anchor="middle" font-family="arial">P</text><text x="255" y="110" text-anchor="middle" font-family="arial">Q</text><text x="270" y="110" text-anchor="middle" font-family="arial">R</text><text x="285" y="110" text-anchor="middle" font-family="arial">S</text><text x="300" y="110" text-anchor="middle" font-family="arial">T</text><text x="315" y="110" text-anchor="middle" font-family="arial">U</text><text x="330" y="110" text-anchor="middle" font-family="arial">V</text><text x="345" y="110" text-anchor="middle" font-family="arial">W</text><text x="360" y="110" text-anchor="middle" font-family="arial">X</text><text x="375" y="110" text-anchor="middle" font-family="arial">Y</text><text x="390" y="110" text-anchor="middle" font-family="arial">Z</text><path d="M 165,105 A 15 15 0 0 0 135,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 135,105 A 22.5 22.5 0 0 0 180,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 180,105 A 0 0 0 0 0 180,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 180,105 A 22.5 22.5 0 0 0 135,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 135,105 A 37.5 37.5 0 0 0 210,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 210,105 A 52.5 52.5 0 0 0 105,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 105,105 A 52.5 52.5 0 0 0 210,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 210,105 A 67.5 67.5 0 0 0 75,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 75,105 A 105 105 0 0 0 285,105" style="stroke:gold; stroke-width:1px;fill:none;" /><path d="M 285,105 A 0 0 0 0 0 285,105" style="stroke:gold; stroke-width:1px;fill:none;" /></svg>
```
[Answer]
# Haskell, 148 bytes
```
z f=tail>>=zipWith f
g c=and.z c.filter(/=0).map abs.z(-).map fromEnum
(a:b:r)%c|a==b=(b:r)%c|1<3=c a b
f s|a<-[g(>=)s,g(<=)s]=or a:a++[s%(<),s%(>)]
```
[Try it on Ideone.](http://ideone.com/ZGhs0P)
Input must be either al lower or all upper-case.  
Output is a list of five booleans: `[SW?, CF?, CP?, CW?, CC?]`.
`f "positive" -> [True,True,False,False,True]`
This turned out longer than expected, especially handing the collapsing of repeated characters takes about 40 bytes.
At first I compared just the first two characters to yield `CW` or `CC` before noticing that testcases like `bba` or `bbc` are valid too and defeat this approach.
[Answer]
# Python, 152 bytes:
```
lambda C:[C[-1]in max(C)+min(C),C[1]>C[0]]*all([[i>g,i<g][[h%2>0,h%2<1][C[1]>C[0]]]for i,g,h in filter(lambda i:i[0]!=i[1],zip(C,C[1:],range(len(C))))])
```
An anonymous lambda function. Call as `print(<Function Name>('<String>'))`.
Takes input as all lowercase or uppercase, but *not* mixed case.
Outputs an array containing nothing (`[]`) if the word is not swirly, or an array in the following format otherwise:
* 1st element is `True/False` for `Centrifugal/Centripetal`.
* 2nd element is `True/False` for `Clockwise/Counterclockwise`.
[Try It Online! (Ideone)](http://ideone.com/viRhhI)
]