text:
Multi-level free parking space finder
Kids-related intro
Whenever I take my kids to an amusement park, the kids get more nervous the closer we are to the park, with the nerve peak when we are in the parking lot and find no place to park. So I've decided I need a method to find the closest free parking space to minimise the time spent parking.
Technical intro
Imagine a representation of a parking lot like this one:
*****************
*               *
* ··CC··C··CC·· *
* ************* *
* ··CCCCCCCCC·· *
*               *
**********E******

In this representation a * means a wall, a · a free parking space, a E the entry point and a C a car already parked. Every whitespace is a position the car to be parked can use to move around the parking lot. Now let's extend this concept to 3D to create a multi-level parking lot:
    1st floor            2nd floor            3rd floor            4th floor
*****************    *****************    *****************    *****************
*               1    *               2    *               3    *               *
* CCCCCCCCCCCCC *    * CCCCCCCCCCCCC *    * ····C··CCCCCC *    * ······C······ *
* ************* *    * ************* *    * ************* *    * ************* *
* CCCCCCCCCCCCC *    * CCCCCCCCCCCCC *    * ···CCCCCCCCCC *    * ··C·······C·· *
*               *    *               1    *               2    *               3
**********E******    *****************    *****************    *****************

The numbers 1, 2 and 3 represent the connections between levels. The 1 from the first floor connects with the 1 in the second floor so a car stepping into the 1 position in the first floor appears in the 1 position in the second floor.
Challenge
Giving a scheme of a parking lot like the previously shown, write the shortest program that calculates the distance to the nearest free parking space, according to the following
Rules

The input will be a 3D char array or a 2D string array or equivalent, and the output will be a single integer representing the number of steps the car must take to get to the nearest free parking space. If you receive a 3D char array the first index may represent the floor number and the second and third indices the (x,y) position for each floor, but this is up to you.
There won't be more than 9 ramps, represented by [1-9].
The car starts from the E position (there will be only one entry point per map) and moves around using the whitespaces in one of four directions each time: up, down, left, right. The car can also step into · positions and [1-9] positions.
Every change of position (step) counts as 1, and every time the car goes from one floor to another counts as 3 as the car must take a ramp. In this case, the movement from a whitespace beside a 1 to the 1 itself is what counts as 3 steps, because as a result of this movement the car appears in the 1 position on the other floor.
The car can't go beyond the matrix limits.
The count will end when the car to be parked is in the same position as a ·. If there are no reachable free parking spaces you can return zero, a negative integer, a null value or an error.

Examples
In the example above the result would be 32, as it is cheaper to go to the fourth floor and park in the closest parking space near the 3. The nearest free parking spaces in the third floor are at a distance of 33 and 34.
Other examples:
    1st floor            2nd floor            3rd floor            4th floor
*****************    *****************    *****************    *****************
*               1    *               2    *               3    *               *
* CCCCCCCCCCCCC *    * CCCCCCCCCCCCC *    * ····C··CCCCCC *    * ······C······ *
* ************* *    * ************* *    * ************* *    * ************* *
* CCCCCCCCCCCCC *    * ·CCCCCCCCCCCC *    * ···CCCCCCCCCC *    * ··C·······C·· *
*               *    *               1    *               2    *               3
**********E******    *****************    *****************    *****************

Answer: 28 (now the parking space in the 2nd floor is closer)

    1st floor            2nd floor            3rd floor            4th floor
*****************    *****************    *****************    *****************
*               1    4               2    5               3    6               *
* CCCCCCCCCCCCC *    * CCCCCCCCCCCCC *    * ····C··CCCCCC *    * ······C······ *
* ************* *    * ************* *    * ************* *    * ************* *
* CCCCCCCCCCCCC *    * CCCCCCCCCCCCC *    * ···CCCCCCCCCC *    * ··C·······C·· *
4               *    5               1    6               2    *               3
**********E******    *****************    *****************    *****************

Answer: 24 (now it's better to go to ramp 4 and then to ramp 5 to the third floor)

    1st floor            2nd floor            3rd floor            4th floor
*****************    *****************    *****************    *****************
*               1    *               *    *               3    *               2
* CCCCCCCCCCCCC *    * CCCCCCCCCCCCC *    * ····C··CCCCCC *    * ······C······ *
* ************* *    * ************* *    * ************* *    * ************* *
* CCCCCCCCCCCCC *    * ·CCCCCCCCCCCC *    * ···CCCCCCCCCC *    * ··C·······C·· *
*               *    *               3    *               2    *               1
**********E******    *****************    *****************    *****************

Answer: 16 (now the parking space in the 4th floor is closer)

 1st floor     2nd floor     3rd floor     4th floor     5th floor
************  ************  ************  ************  ************
*CCCCCCCCC 1  *CCCCCCCCC 2  *CCCCCCCCC 3  *·CCCCCCCC 4  *········C *
*          *  *          *  *          *  *          *  *          *
*CCCCCCCCC E  *CCCCCCCCC 1  *CCCCCCCCC 2  *··CCCCCCC 3  *·······CC 4
************  ************  ************  ************  ************

Answer: 29 (both the nearest parking spaces at the 4th and 5th floors are at the same distance)

 1st floor     2nd floor     3rd floor
************  ************  ************
*CCCCCCCCC 1  *CCCCCCCCC 2  *CCCCCCCCC *
*          *  *          *  *          *
*CCCCCCCCC E  *CCCCCCCCC 1  *CCCCCCCCC 2
************  ************  ************

Answer: -1 (no free parking space)

 1st floor
************
*          *
*          *
*         E*
************

Answer: -1 (no parking space at all)

 1st floor
************
* ·····    *
*·      ****
* ····· * E
*********

Answer: -1 (the parking lot designer was a genius)

Alternatives

You can use whatever characters you want to represent the parking lot map, just specify in your answer which are your chosen characters and what they mean.

This is code-golf, so may the shortest program/method/lambda/whatever for each language win!
If you need help with the algorithm, please check my (ungolfed) implementation in C#.

Related.

Since we're apparently dealing with crazy parking lot designers, may a ramp go directly from, say, 1st floor to 3rd floor? I think you should either add such a test case (which could be pretty fun) or explain that it's not going to happen.

@Arnauld yes, it may happen. I'll add a test case as soon as possible.

@Arnauld added. A difficult task from the mobile app...

@Arnauld characters [1-9] are just markers to tell the ramps apart. They do not tell which floor the ramp goes to. You could have chosen characters [a-z] and have up to 26 floors, but only 9 are required.

-1 no colorful blocks or kid's stories this time

@LuisMendo better now? :-)

@Charlie Heh. Now it does sound like you :-P

Can the entrance and ramps be anywhere or are they always part of a wall?

@Veskah they can be anywhere, see the last two examples.

@Charlie "A difficult task from the mobile app". Not difficult and not mobile app. Same pathfinding tasks was actual with old tile games like Mario a long time ago in a galaxy far, far away )))

@mazzy I meant that adding a new test case to the text of the question was a difficult task using the limited UI of the Stack Exchange mobile app...

Got It. I'm sorry.

Are you allowing or excluding ramp-loops (e.g. ramps 1 and 2 both go between first floor and second floor, such that a 3-space-up-ramp, short move, 3-space-down-ramp might be a faster way to navigate)

@Chronocidal I'm not really excluding ramp loops. The only limitation is that a ramp cannot bifurcate. I mean, there will be only two 1 characters in the map, two 2 characters and so on. But you can create maps with loops. I'll try to add such an example in the question.

JavaScript (ES6), 199 bytes
Takes input as an array of arrays of arrays of characters, using the characters described in the challenge. Returns \$0\$ if there's no free parking space.
a=>(m=g=(c,t,f,x,y,F=f||a.find(r=>r.some((a,i)=>~(y=i,x=a.indexOf(c)))),r=F[y])=>r&&(c=r[x])&&(r[x]=g,c>'z'?m=m<t?m:t:!f|c<1?[0,-1,0,1].map((d,i)=>g(0,-~t,F,x+d,y+~-i%2)):+c&&g(c,t+2),r[x]=c))('E')|m

Try it online!
How?
The recursive function g() takes as input:

c : the character of the entry point we're looking for if we've just left a floor or we are at the very beginning of the process; 0 otherwise
t : the total number of moves so far (initially undefined)
f, x, y : a pointer to the current floor and the current coordinates in this floor; they are all undefined if we're looking for a new floor

If f is defined, we simply copy it to the current floor F. Otherwise, we need to look for the new floor and the new coordinates by iterating over each floor and over each row until we find the entry point c:
F = f || a.find(r => r.some((a, i) => ~(y = i, x = a.indexOf(c))))

We define r as the current row in the current floor:
r = F[Y]

The next step is to make sure that the current cell c at (x, y) is defined:
r && (c = r[x]) && ...

If it is, we mark it as visited by setting it to g, a value that does not trigger any of the forthcoming tests:
r[x] = g

If c is a free parking space, we stop the recursion. And if the total number of moves is lower than our previous best score, we update m accordingly:
c > 'z' ? m = m < t ? m : t : ...

If we've just reached a new floor (f is undefined) or c is a space, we process a recursive call for each surrounding cell:
!f | c < 1 ?
  [0, -1, 0, 1].map((d, i) =>
    g(0, -~t, F, x + d, y + ~-i % 2)
  )
:
  ...

Otherwise, if c is a ramp marker (i.e. a non-zero digit), we process a single recursive call to reach the new floor:
+c && g(c, t + 2)

Finally, we restore the current cell to its initial value so that it can be visited again in other recursion paths:
r[x] = c

Powershell, 299 292 bytes
It is assumed that the map is rectangle.
It uses x instead ·. To get ·, you need to save script as ASCII (not UTF-8) and replace x on ·.
filter f{$l=($_-split"
")[0].length
$p,$d,$e='x','\d',' '|%{"$_(?=E)|(?<=E)$_|$_(?=[\s\S]{$l}E)|(?<=E[\s\S]{$l})$_"}
for($r=1;$_-notmatch$p;$r++){$m=$_-replace'F','E'-replace'G','F'-replace'H','G'
if($m-match$d){$m=$m-replace$Matches[0],'H'}$m=$m-replace$e,'E'
if($m-eq$_){return -1}$_=$m}$r}

Ungolfed and test script:
filter f{
    #Write-Host "`nStep:`n$_" # uncomment this to display each step

    $l = ($_ -split "`n")[0].length
    $p,$d,$e = 'x', '\d', ' '| % {"$_(?=E)|(?<=E)$_|$_(?=[\s\S]{$l}E)|(?<=E[\s\S]{$l})$_"}

    for($r = 1;$_ -notmatch $p;$r++) {
        $m = $_ -replace 'F', 'E' -replace 'G', 'F' -replace 'H', 'G'
        if ($m -match $d) {
            $m = $m -replace $Matches[0], 'H'
        }
        $m = $m -replace $e, 'E'

        if ($m -eq $_) {
            return -1
        }

        $_=$m
    }
    $r
}

@(
    , (2, @"
****
*x E
****
"@)
    , (1, @"
****
* xE
****
"@)
    , (1, @"
****
* x*
* E*
****
"@)
    , (1, @"
****
* E*
* x*
****
"@)
    , (-1, @"
****
2 E1
*  *
****
"@)
    , (28, @"
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*               *
**********E******
*****************
*               2
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               1
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               *
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               3
*****************
"@)
    , (16, @"
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*               *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************
"@)
    , (29, @"
************
*CCCCCCCCC 1
*          *
*CCCCCCCCC E
************
************
*CCCCCCCCC 2
*          *
*CCCCCCCCC 1
************
************
*CCCCCCCCC 3
*          *
*CCCCCCCCC 2
************
************
*xCCCCCCCC 4
*          *
*xxCCCCCCC 3
************
************
*xxxxxxxxC *
*          *
*xxxxxxxCC 4
************
"@
    )
    , (-1, @"
************
*          *
*          *
*         E*
************
"@)
    , (-1, @"
************
* xxxxx    *
*x      ****
* xxxxx * E
*********
"@)
) | % {
    $e, $m = $_
    $r = $m|f
    "$($e-eq$r): $r $e"
}

Output:
True: 2 2
True: 1 1
True: 1 1
True: 1 1
True: -1 -1
True: 28 28
True: 16 16
True: 29 29
True: -1 -1
True: -1 -1

Extended output for parking with 16 steps:
Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*               *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*         E     *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*        EEE    *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*       EEEEE   *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*      EEEEEEE  *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*     EEEEEEEEE *
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCC *
*    EEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* ************* *
* CCCCCCCCCCCCCE*
*   EEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCC *
* *************E*
* CCCCCCCCCCCCCE*
*  EEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*               1
* CCCCCCCCCCCCCE*
* *************E*
* CCCCCCCCCCCCCE*
* EEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*              E1
* CCCCCCCCCCCCCE*
* *************E*
* CCCCCCCCCCCCCE*
*EEEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               1
*****************

Step:
*****************
*             EEH
* CCCCCCCCCCCCCE*
* *************E*
*ECCCCCCCCCCCCCE*
*EEEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               H
*****************

Step:
*****************
*            EEEG
* CCCCCCCCCCCCCE*
*E*************E*
*ECCCCCCCCCCCCCE*
*EEEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               G
*****************

Step:
*****************
*           EEEEF
*ECCCCCCCCCCCCCE*
*E*************E*
*ECCCCCCCCCCCCCE*
*EEEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*               F
*****************

Step:
*****************
*E         EEEEEE
*ECCCCCCCCCCCCCE*
*E*************E*
*ECCCCCCCCCCCCCE*
*EEEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxx *
*              EE
*****************

Step:
*****************
*EE       EEEEEEE
*ECCCCCCCCCCCCCE*
*E*************E*
*ECCCCCCCCCCCCCE*
*EEEEEEEEEEEEEEE*
**********E******
*****************
*               *
* CCCCCCCCCCCCC *
* ************* *
* xCCCCCCCCCCCC *
*               3
*****************
*****************
*               3
* xxxxCxxCCCCCC *
* ************* *
* xxxCCCCCCCCCC *
*               2
*****************
*****************
*               2
* xxxxxxCxxxxxx *
* ************* *
* xxCxxxxxxxCxxE*
*             EEE
*****************
True: 16 16

Explanation
It's kind of Lee pathfinding algorithm. Only one smart thing: 3 steps on ramp are realized as a dummy states H->G->F->E

Powershell for a genius parking lot designer, 377 369 bytes
Parking design is an 2D string array. No assumtions about map: any length strings, floors without walls, parking without an entry point, multi-floor-and-multi-exit-ramps. Genus cost is +26%.
filter f{for($r=1;$_-notmatch$p;$r++){$m=$_-replace'F','E'-replace'G','F'-replace'H','G'
if($m-match$d){$m=$m-replace$Matches[0],'H'}$m=$m-replace$e,'E'
if($m-eq$_){return-1}$_=$m}$r}$g={$l=($args|%{$_|%{$_.length}}|sort)[-1]
$p,$d,$e='x','\d',' '|%{"$_(?=E)|(?<=E)$_|$_(?=[\s\S]{$l}E)|(?<=E[\s\S]{$l})$_"}
(($args|%{$_.PadRight($l,'*')-join"
"})-join"
"+'-'*$l+"
")|f}

Ungolfed and test script:
filter f{
    #Write-Host "`nStep:`n$_" # uncomment this to display each step

    for($r = 1;$_ -notmatch $p;$r++) {
        $m = $_ -replace 'F', 'E' -replace 'G', 'F' -replace 'H', 'G'
        if ($m -match $d) {
            $m = $m -replace $Matches[0], 'H'
        }
        $m = $m -replace $e, 'E'

        if ($m -eq $_) {
            return -1
        }

        $_=$m
    }
    $r
}

$g = {

    $l = ($args| % {$_| % {$_.length}}|sort)[-1]
    $p,$d,$e = 'x', '\d', ' '| % {"$_(?=E)|(?<=E)$_|$_(?=[\s\S]{$l}E)|(?<=E[\s\S]{$l})$_"}
    (($args| % {$_.PadRight($l, '*') -join "`n"}) -join "`n"+'-' * $l+"`n")|f

}

@(
    , (2, @(, (
                "****",
                "*x E",
                "****"
            )))
    , (1, @(, (
                "****",
                "* xE",
                "****"
            )))
    , (1, @(, (
                "****",
                "* x*",
                "* E*",
                "****"
            )))
    , (1, @(, (
                "****",
                "* E*",
                "* x*",
                "****"
            )))
    , (-1, @(, (
                "****",
                "2 E1",
                "*  *",
                "****"
            )))
    , (28, @(, (
                "*****************",
                "*               1",
                "* CCCCCCCCCCCCC *",
                "* ************* *",
                "* CCCCCCCCCCCCC *",
                "*               *",
                "**********E******"
            ), (
                "*****************",
                "*               2",
                "* CCCCCCCCCCCCC *",
                "* ************* *",
                "* xCCCCCCCCCCCC *",
                "*               1",
                "*****************"
            ), @(
                "*****************",
                "*               3",
                "* xxxxCxxCCCCCC *",
                "* ************* *",
                "* xxxCCCCCCCCCC *",
                "*               2",
                "*****************"
            ), @(
                "*****************",
                "*               *",
                "* xxxxxxCxxxxxx *",
                "* ************* *",
                "* xxCxxxxxxxCxx *",
                "*               3",
                "*****************"
            )))
    , (16, @(, (
                "*****************",
                "*               1",
                "* CCCCCCCCCCCCC *",
                "* ************* *",
                "* CCCCCCCCCCCCC *",
                "*               *",
                "**********E******"
            ), @(
                "*****************",
                "*               *",
                "* CCCCCCCCCCCCC *",
                "* ************* *",
                "* xCCCCCCCCCCCC *",
                "*               3",
                "*****************"
            ), @(
                "*****************",
                "*               3",
                "* xxxxCxxCCCCCC *",
                "* ************* *",
                "* xxxCCCCCCCCCC *",
                "*               2",
                "*****************"
            ), @(
                "*****************",
                "*               2",
                "* xxxxxxCxxxxxx *",
                "* ************* *",
                "* xxCxxxxxxxCxx *",
                "*               1",
                "*****************"
            )))
    , (29, @(, (
                "************",
                "*CCCCCCCCC 1",
                "*          *",
                "*CCCCCCCCC E",
                "************"
            ), @(
                "************",
                "*CCCCCCCCC 2",
                "*          *",
                "*CCCCCCCCC 1",
                "************"
            ), @(
                "************",
                "*CCCCCCCCC 3",
                "*          *",
                "*CCCCCCCCC 2",
                "************"
            ), @(
                "************",
                "*xCCCCCCCC 4",
                "*          *",
                "*xxCCCCCCC 3",
                "************"
            ), @(
                "************",
                "*xxxxxxxxC *",
                "*          *",
                "*xxxxxxxCC 4",
                "************"
            )))
    , (-1, @(, (
                "************",
                "*          *",
                "*          *",
                "*         E*",
                "************"
            )))
    , (-1, @(, (
                "************",
                "* xxxxx    *",
                "*x      ****",
                "* xxxxx * E",
                "*********"
            )))
) | % {
    $e, $m = $_
    $r = &$g @m
    "$($e-eq$r): $r $e"
}

Kotlin, 768 bytes
used period . instead of ·. Wish I understood Arnauld's answer because losing 500 bytes would be nice.
fun s(l:List<List<CharArray>>)={val b=listOf(l.size-1,l[0].size-1,l[0][0].size-1)
val e=Int.MAX_VALUE
var r=e
var t=listOf(e,e,e)
val d=Array(b[0]+1){Array(b[1]+1){Array(b[2]+1){e}}}
val f={c:Char,n:List<Int>->var a=t
(0..b[0]).map{f->(0..b[1]).map{r->(0..b[2]).map{var s=listOf(f,r,it)
if(l[f][r][it]==c&&!s.equals(n))a=s}}}
a}
fun m(p:List<Int>,c:Int){if(p[0]in 0..b[0]&&p[1]in 0..b[1]&&p[2]in 0..b[2]&&d[p[0]][p[1]][p[2]]>c){d[p[0]][p[1]][p[2]]=c
val h=l[p[0]][p[1]][p[2]]
when(h){' ','E'->(-1..1 step 2).map{m(listOf(p[0],p[1]+it,p[2]),c+1)
m(listOf(p[0],p[1],p[2]+it),c+1)}
'.'->if(r>c)r=c
in '1'..'9'->{val n=f(h,p)
d[n[0]][n[1]][n[2]]=c+2
(-1..1 step 2).map{m(listOf(n[0],n[1]+it,n[2]),c+3)
m(listOf(n[0],n[1],n[2]+it),c+3)}}}}}
m(f('E',t),0)
if(r<e)r
else-1}()

Try it online!


text:
Tell me the Lunar Phase!
Challenge
Given an image of the Moon as input, output the phase of the Moon.
Phases of the Moon
Your program will be supplied one of these images in png format and you must output the phase exactly as given:
new moon

hexdump

waxing crescent

hexdump

first quarter

hexdump

waxing gibbous

hexdump

full moon

hexdump

waning gibbous

hexdump

third quarter

hexdump

waning crescent

hexdump

Input
The input will be the path to a 240 px by 240 px png file and will be the one of the images above.
The image bytes are guaranteed to be the same.
Winning
Shortest code wins

As a bonus, check out this cool gif: https://upload.wikimedia.org/wikipedia/commons/b/ba/Lunar_libration_with_phase_Oct_2007_450px.gif

Node.js, 145 bytes
p=>'third/waning/first/full/waxing/new'.split`/`[(s=require('fs').statSync(p).size)%418%6]+' '+'quarter/crescent/gibbous/moon'.split`/`[s%12%9%4]

Try it online! (generates dummy files with the same sizes)
How?
We just look at the size of the file and convert it to indices in two lookup tables.
First part:
 phase | file size | mod 418 | mod 6 | mapped to
-------+-----------+---------+-------+-----------
   0   |    3451   |    107  |    5  | new
   1   |    6430   |    160  |    4  | waxing
   2   |    5144   |    128  |    2  | first
   3   |    7070   |    382  |    4  | waxing
   4   |    5283   |    267  |    3  | full
   5   |    7067   |    379  |    1  | waning
   6   |    4976   |    378  |    0  | third
   7   |    6337   |     67  |    1  | waning

Second part:
 phase | file size | mod 12 |  mod 9 |  mod 4 | mapped to
-------+-----------+--------+--------+--------+-----------
   0   |    3451   |     7  |     7  |    3   | moon
   1   |    6430   |    10  |     1  |    1   | crescent
   2   |    5144   |     8  |     8  |    0   | quarter
   3   |    7070   |     2  |     2  |    2   | gibbous
   4   |    5283   |     3  |     3  |    3   | moon
   5   |    7067   |    11  |     2  |    2   | gibbous
   6   |    4976   |     8  |     8  |    0   | quarter
   7   |    6337   |     1  |     1  |    1   | crescent

Python 2, 223 222 bytes
-1 byte thanks to OMᗺ

lambda p:'new moonzzfull moonzzfirst quarterzzwaxing crescentzzwaning gibbouszzwaxing gibbouszthird quarterzwaning crescent'.split('z')[sum(n*Image.open(p).getpixel((n*48,99))[2]for n in[1,2,3,4])%13]
from PIL import Image

getpixel((x,y)) - will return the RGBA pixel at x,y
getpixel((n*48,99))[2]for n in[1,2,3,4] - will return the blue channel of the middle line, where n*48 ... for n in 1,2,3,4 will be 4 points where the sunlight may cover
n*getpixel(...) - will generate a different value for each column
sum(...)%13 - these values are added together and %13 is used to get an unique value to each phase, that will be used as index for the phase list
The pixels are approximately inside the red circles:

Ruby, 131 bytes
->f{f=open(f,'rb').read;%w[first third waxing new full waning][f[699].ord%7]+' '+%w[x moon gibbous quarter crescent][f[998].ord%5]}

Byte offsets found by brute force -- taking the 699th byte of the file modulo 7, for instance, gives an index into the first lookup table.

Python 2, 196 165 bytes
lambda f:'first quarter|new moon|waning crescent|waxing gibbous|third quarter|full moon|waxing crescent|waning gibbous'.split('|')[sum(map(ord,open(f).read()))%41%9]

Try it online!

PHP (>=5.4), 199 197 bytes
(-2 bytes by more golfing)
<?$s=strlen(file_get_contents($argv[1])).'';echo strtr([waning_crescent,waning_gibbous,new_moon,0,waxing_crescent,waxing_gibbous,full_moon,first_quarter,third_quarter][($s[0]+$s[3])%11-2],'_',' ');

To run it:
php -d error_reporting=0 -d short_open_tag=1 <filename> <image_path>

Example:
php -d error_reporting=0 -d short_open_tag=1 lunar_phase.php https://upload.wikimedia.org/wikipedia/commons/thumb/c/c9/Moon_phase_6.svg/240px-Moon_phase_6.svg.png

Notes:

The -d error_reporting=0 option is used to not output notices/warnings.
The -d short_open_tag=1 is required to allow short tags.
If you are using a https URL like the example above, OpenSSL should also be enabled.

How?
Gets file size (bytes) and creates a unique number for it by this formula:
((<first_bytes_digit> + <fourth_bytes_digit>) % 11) - 2
This formula generates numbers from 0 to 8 with only a 3 missing.
┌─────────────────┬───────┬─────────┬─────┬────────────────────────┐
│      Phase      │ Bytes │ 1st+4th │ %11 │ -2 (position in array) │
├─────────────────┼───────┼─────────┼─────┼────────────────────────┤
│ new moon        │  3451 │ 3+1=4   │   4 │                      2 │
│ waxing crescent │  6430 │ 6+0=6   │   6 │                      4 │
│ first quarter   │  5144 │ 5+4=9   │   9 │                      7 │
│ waxing gibbous  │  7070 │ 7+0=7   │   7 │                      5 │
│ full moon       │  5283 │ 5+3=8   │   8 │                      6 │
│ waning gibbous  │  7067 │ 7+7=14  │   3 │                      1 │
│ third quarter   │  4976 │ 4+6=10  │  10 │                      8 │
│ waning crescent │  6337 │ 6+7=13  │   2 │                      0 │
└─────────────────┴───────┴─────────┴─────┴────────────────────────┘

Previous approaches:
PHP (>=5.4), 251 bytes
<?foreach([4,8,16,20]as$w){$a+=imagecolorat(imagecreatefrompng($argv[1]),$w*10,120)>1e7;$a&&$w<5?$b=-2:0;}$x=explode('_','full moon_waning gibbous_third quarter_waning crescent_new moon_waxing crescent_first quarter_waxing gibbous');echo$x[$a*++$b+4];

To run it:
php -d error_reporting=0 -d short_open_tag=1 <filename> <image_path>

Example:
php -d error_reporting=0 -d short_open_tag=1 lunar_phase.php https://upload.wikimedia.org/wikipedia/commons/thumb/c/c9/Moon_phase_6.svg/240px-Moon_phase_6.svg.png

Notes:

The -d error_reporting=0 option is used to not output notices/warnings.
The -d short_open_tag=1 is required to allow short tags.
PHP must have GD and it should be enabled.
If you are using a https URL like the example above, OpenSSL should also be enabled.

How?
Checks for the color of 4 pixels in the image at 40,120, 80,120, 160,120 and 200,120 and decides on the moon phase from those colors.

source: Stack Exchange

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

sort: votes


text:
Spiral neighbourhoods
If we take the natural numbers and roll them up counter clock-wise into a spiral we end up with the following infinite spiral:
                  ....--57--56
                             |
36--35--34--33--32--31--30  55
 |                       |   |
37  16--15--14--13--12  29  54
 |   |               |   |   |
38  17   4---3---2  11  28  53
 |   |   |       |   |   |   |
39  18   5   0---1  10  27  52
 |   |   |           |   |   |
40  19   6---7---8---9  26  51
 |   |                   |   |
41  20--21--22--23--24--25  50
 |                           |
42--43--44--45--46--47--48--49

Given some number in that spiral your task is to determine its neighbours - meaning the element above, left, right and below it.
Example
If we have a look at 27 we can see that it has the following neighbours:

above: 28
left: 10
right: 52
below: 26

So the output would be: [28,10,52,26]
Rules

Input will be a number \$n \geq 0\$ in any default I/O format
Output will be a list/matrix/.. of that numbers' 4 neighbours in any (consistent!) order
You may work with a spiral that starts with 1 instead of 0, however you should specify that in your answer

Examples
The output is in the format [above,left,right,below] and uses a 0-based spiral:
0  ->  [3,5,1,7]
1  ->  [2,0,10,8]
2  ->  [13,3,11,1]
3  ->  [14,4,2,0]
6  ->  [5,19,7,21]
16  ->  [35,37,15,17]
25  ->  [26,24,50,48]
27  ->  [28,10,52,26]
73  ->  [42,72,74,112]
101  ->  [100,146,64,102]
2000  ->  [1825,1999,2001,2183]
1000000  ->  [1004003,1004005,999999,1000001]

related

R, 156 bytes
function(n){g=function(h)c(0,cumsum(h((4*(0:(n+2)^2)+1)^.5%%4%/%1/2)))
x=g(sinpi)
y=g(cospi)
a=x[n]
b=y[n]
which(x==a&(y==b+1|y==b-1)|y==b&(x==a+1|x==a-1))}

Try it online!

posted another R answer since it's a slightly different approach than @ngn
1-indexed
neighbours are always sorted by ascending value
saved 6 bytes removing round and using cospi(x)/sinpi(x) which are more precise than cos(x*pi)/sin(x*pi) in case of half numbers (0.5, 1.5 etc...)
saved another byte removing the minus on y coordinates since the result is the same (just up/down neighbours are reversed)

Explanation :
If we look at the matrix coordinates of the values, considering the first value 0 placed at x=0, y=0, they are :
x = [0,  1,  1,  0, -1, -1, -1,  0,  1,  2,  2,  2,  2,  1,  0, ...]
y = [0,  0,  1,  1,  1,  0, -1, -1, -1, -1,  0,  1,  2,  2,  2, ...]

The x coordinates follow the A174344 OEIS sequence with the recursive formula :
a(1) = 0, a(n) = a(n-1) + sin(mod(floor(sqrt(4*(n-2)+1)),4)*pi/2)

The same formula holds for y matrix coordinates, but with cos instead of sin and negated :
a(1) = 0, a(n) = a(n-1) - cos(mod(floor(sqrt(4*(n-2)+1)),4)*pi/2)

So, in R we can translate the formula to this function, taking sinpi/cospi as parameter :
g=function(h)c(0,cumsum(h((4*(0:(n+2)^2)+1)^.5%%4%/%1/2)))

and we generate the two coordinates vectors (we don't negate the y coords since we'll get the same result, just with up/down neighbours reversed) :
x=g(sinpi)
y=g(cospi)

Note that we have generated (n+2)^2 coordinates, which are more than the minimum necessary coordinates containing both n and their neighbours (a tighter bound would be (floor(sqrt(n))+2)^2 but unfortunately is less "golfy").
Therefore, now that we have all the coordinates, we first search the coordinates a,b corresponding to our n :
a=x[n]
b=y[n]

finally we select the positions of their neighbours, i.e. :

the up/down neighbours where x == a and y == b+1 or b-1
the right/left neighbours where y == b and x == a+1 or a-1

using :
which(x==a&(y==b+1|y==b-1)|y==b&(x==a+1|x==a-1))

"slightly different" :)

@ngm: eheh... since the rosetta code you used is pretty "obscure" to me, I assumed is somehow generating the position indexes of the matrix in a different but similar fashion than my OEIS sequences :D

Brain-Flak, 238 bytes
((){[()]<((({}[((()))]<>)<<>{((([{}]({}))([{}]{})())[()]){({}[()])<>}{}}>)<<>({}<(((({}{})()){}<>({}))()())<>>)<>>()())<>{{}((()()()[({})]){}<>({}<{}>))(<>)}>}{}){<>((((())()())()())()())(<>)}{}{({}[()]<<>({}<>)<>({}<({}<({}<>)>)>)<>>)}<>

Try it online!
Output is in the order left, up, right, down.
Explanation
# If n is nonzero:
((){[()]<

  ((

    # Push 1 twice, and push n-1 onto other stack.
    ({}[((()))]<>)

    # Determine how many times spiral turns up to n, and whether we are on a corner.
    # This is like the standard modulus algorithm, but the "modulus" used
    # increases as 1, 1, 2, 2, 3, 3, ...
    <<>{((([{}]({}))([{}]{})())[()]){({}[()])<>}{}}>

  # Push n-1: this is the number behind n in the spiral.
  )<

    # While maintaining the "modulus" part of the result:
    <>({}<

      # Push n+2k+1 and n+2k+3 on top of n-1, where k is 3 more than the number of turns.
      # n+2k+1 is always the number to the right in the direction travelled.
      # If we are on a corner, n+2k+3 is the number straight ahead.
      (((({}{})()){}<>({}))()())<>

    >)<>

  # Push n+1.  If we are on a corner, we now have left, front, right, and back
  # on the stack (from top to bottom)
  >()())

  # If not on a corner:
  <>{{}

    # Remove n+2k+3 from the stack entirely, and push 6-2k+(n+1) on top of the stack.
    ((()()()[({})]){}<>({}<{}>))

  (<>)}

>}{})

# If n was zero instead:
{

  # Push 1, 3, 5, 7 on right stack, and implicitly use 1 (from if/else code) as k.
  <>((((())()())()())()())

(<>)}{}

# Roll stack k times to move to an absolute reference frame
# (switching which stack we're on each time for convenience)
{({}[()]<<>({}<>)<>({}<({}<({}<>)>)>)<>>)}<>

Very impressive! I guess you're not generating the whole spiral as others do, are you?

Perl 6Raku, 94 83 78 bytes
{my \s=0,|[+] flat((1,i...)Zxx flat(1..Inf Z 1..Inf));map {first :k,s[$_]+$^d,s},i,-1,1,-i}
{my \s=0,|[+] flat((1,i...)Zxx(1,1.5...*));map {first :k,s[$_]+$^d,s},i,-1,1,-i}
{my \s=0,|[\+] flat (1,*i...*)Zxx(1,3/2...*);(grep :k,1==(s[$_]-*).abs,s)[^4]}

Try it online!
s is a lazy, infinite list of spiral coordinates, represented as complex numbers.  It's constructed from two other infinite lists: 1, *i ... * makes the list 1, i, -1, -i ....  1, 1.5 ... * makes the list 1, 1.5, 2, 2.5, 3, 3.5 ....  Zipping these two lists together with list replication produces the list of steps from each spiral coordinate to the next: 1, i, -1, -1, -i, -i, 1, 1, 1, i, i, i ....  (The fractional parts of the right-hand arguments to the list replication operator are discarded.)  Doing a triangular addition reduction ([\+]) on this list (and pasting 0 onto the front) produces the list of spiral coordinates.
Finally, starting from the complex number s[$_] ($_ being the sole argument to the function), we look up the indexes (first :k) in the spiral of the complex numbers which are offset from that number by i, -1, 1, and -i.
I shaved a few bytes off by searching for the matching elements in index order, and by testing that the absolute value of the complex difference between the coordinates is 1, rather than testing for 1, -1, i, and -1 explicitly.

MATL, 15 bytes
2+1YLtG=1Y6Z+g)

Input and output are 1-based.
The output gives the left, down, up and right neighbours in that order.
Try it online! Or verify all test cases except the last two, which time out on TIO.
2+      % Implicit input: n. Add 2. This is needed so that
        % the spiral is big enough
1YL     % Spiral with side n+2. Gives a square matrix
t       % Duplicate
G=      % Compare with n, element-wise. Gives 1 for entry containing n
1Y6     % Push 3×3 mask with 4-neighbourhood
Z+      % 2D convolution, keeping size. Gives 1 for neighbours of the
        % entry that contained n
g       % Convert to logical, to be used as an index
)       % Index into copy of the spiral. Implicit display

1YL- MATLAB has aspiral function? When did MATLAB turn into Mathematica?!

Yeah, I duckduckgo-ed it after seeing what 1YL meant, and this Rosetta code entry was the only place I could find to confirm that it's a MATLAB thing and not just a MATL convenience function. I was starting to think it might be something you added to MATL for golfing, until I saw that entry.

@sundar Weird that it's not documented anymore

Python 2, 177 164 146 144 bytes
def f(n):N=int(n**.5);S=N*N;K=S+N;F=4*N;return[n+[F+3,[-1,1-F][n>K]][n>S],n+[F+5,-1][n>K],n+[[1,3-F][n<K],-1][0<n==S],n+[F+7,1][n<K]][::1-N%2*2]

Try it online!
Calculates u,l,r,d directly from n.

Save a couple of bytes with [-1,1-F][n>K] -> 1-[2,F][n>K] and n+[[1,3-F][n<K],-1][0<n==S] -> n-[[2,F][n<K]-3,1][0<n==S] - TIO

JavaScript (V8),  165 162  151 bytes
Prints the indices.
f=(n,x=w=y=n+2)=>y+w&&[-1,0,1,2].map(d=>(g=(x,y)=>(k=2*Math.max(x,-x,y,-y))*k+(k+x+y)*(y>=x||-1))(x+d%2,y+~-d%2)-n||print(g(x,y)))|f(n,x+w?x-1:(y--,w))

Try it online!
How?
For \$x, y \in \mathbb{Z}\$, we compute the 0-based index \$I_{x,y}\$ of the spiral with:
$$A_{x,y}=2\cdot\max(|x|,|y|)$$
$$S_{x,y}=\begin{cases}1,&\text{if }y\ge x\\-1,&\text{if }y<x\end{cases}$$
$$I_{x,y}=A_{x,y}^2+(A_{x,y}+x+y)\times S_{x,y}$$
Adapted from this answer from math.stackexchange.
Also used in Can you make your way through the Ulam spiral?
Saved 1 byte thanks to @att.

This seems to work fine with smaller numbers, but I get an error when testing this with a large number like 2000. Error on tio.run: RangeError: Maximum call stack size exceeded and error in browser console: InternalError: too much recursion. Am I doing something wrong?

@Night2 The number of iterations grows in $4n^2$, so the call stack quickly overflows. The same kind of restriction applies to most JS recursive answers, although the exact limit depends on the platform it's running on.

R, 172 bytes
function(x,n=2*x+3,i=cumsum(rep(rep(c(1,n,-1,-n),l=2*n-1),n-seq(2*n-1)%/%2))){F[i]=n^2-1:n^2
m=matrix(F,n,n,T)
j=which(m==x,T)
c(m[j[1],j[2]+c(-1,1)],m[j[1]+c(-1,1),j[2]])}

Try it online!
This is R, so obviously the answer is 0-indexed.
Most of the work is creating the matrix. Code inspired by: https://rosettacode.org/wiki/Spiral_matrix#R

APL (Dyalog Unicode), 66 60 bytes
{(⊃⍸⍵=s)⌷{⊢/4 2⍴⍵}⌺3 3⊢s←{⌽⍉⍵⍪⍨⌽(⍳(⌈/⍴⍵)+⌈/,⍵)~,⍵}⍣(⍵+4)⊢⍪1}

Try it online!
1-indexed.
I'd been wanting to solve spiral challenges in APL for a while, so I figured I'd make a spiral creating function for this. I've used simple array magic to make it(and ngn will probably find an insane math relation to calculate it, most likely).
-6 bytes from Adám.
Explanation
{(⊃⍸⍵=s)⌷{⊢/4 2⍴⍵}⌺3 3⊢s←{⌽⍉⍵⍪⍨⌽(⍳(⌈/⍴⍵)+⌈/,⍵)~,⍵}⍣(⍵+4)⊢⍪1} input → n
                                                         ⍪1  to [[1]],
                                                  ⍣(⍵+4)⊢    apply the following n+4 times:
                                (⍳(⌈/⍴⍵)+⌈/,⍵)               range 1..max(i)+max(shape(i))
                                              ~,⍵            without i
                            ⍵⍪⍨                              add that as a row

                          ⌽⍉                                 rotate 90 degrees clockwise

                       s←                                    assign the spiral to s
         {       }⌺3 3⊢                                      to the 3x3 paritions of the spiral:
          ⊢/4 2⍴⍵                                            get every 2nd element

 ⊃⍸⍵=s                                                       find indices of n in the spiral
(     )⌷                                                     and index into the matrix of neighbours

PHP (>=5.4), 208 bytes
<?$n=$argv[1];for(;$i++<($c=ceil(sqrt($n))+($c%2?2:3))**2;$i!=$n?:$x=-$v,$i!=$n?:$y=+$h,${hv[$m&1]}+=$m&2?-1:1,$k++<$p?:$p+=$m++%2+$k=0)$r[-$v][+$h]=$i;foreach([0,1,0,-1]as$k=>$i)echo$r[$x+$i][$y+~-$k%2].' ';

To run it:
php -n -d error_reporting=0 <filename> <n>

Example:
php -n -d error_reporting=0 spiral_neighbourhoods.php 2001

Or Try it online!
Notes:

The -d error_reporting=0 option is used to not output notices/warnings.
This spiral starts with 1.

How?
I'm generating the spiral with a modified version of this answer in a 2 dimensional array.
I decide on the size of the spiral based on the input n with a formula to always get an extra round of numbers in the spiral (guarantee for existence of above/below/left/right). An extra round of numbers means +2 in height and +2 in width of the 2 dimensional array.
So if n will be located in a spiral with maximum size of 3*3, then generated spiral will be 5*5.
Spiral size is c*c where c = ceil(sqrt(n)) + k, if ceil(sqrt(n)) is odd, then k is 2 and if ceil(sqrt(n)) is even, then k is 3.
For example, the above formula will result in this:

If n = 1 then c = 3 and spiral size will be 3*3
If n <= 9 then c = 5 and spiral size will be 5*5
If n <= 25 then c = 7 and spiral size will be 7*7
If n <= 49 then c = 9 and spiral size will be 9*9
And so on ...

While generating the spiral, I store the x and y of n and after generation, I output the elements above/below/left/right of it.

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


text:
Given N, output n-th element of ['A', 'B', 'AB', 'C', 'D', 'CD', 'ABCD', 'E', ...]?
Consider the following list:
expected = [
'A',
'B',
'AB',
'C',
'D',
'CD',
'ABCD',
'E',
'F',
'EF',
'G',
'H',
'GH',
'EFGH',
'ABCDEFGH',
'I',
'J',
'IJ',
'K',
'L',
'KL',
'IJKL',
'M',
'N',
'MN',
'O',
'P',
'OP',
'MNOP',
'IJKLMNOP',
'ABCDEFGHIJKLMNOP',
...
]

Here's one way to look at it - you're learning how to write Chinese characters and want to learn increasingly big chunks of them, rehearsing them as you go. You start with A, then go with B, then there's already a sequence that is a pair of two so you combine it. Then you go with C and D, make another pair, practice it. Then you rehearse: ABCD. Then the same goes with E up to H, then rehearse: ABCDEFGH. The list is infinite.
The goal is to generate and print out an n-th element of this list, indexes going up from zero. Assume that after 'Z', you get 'A' again.
The winning criteria is source code length.

@Picard is it not clear they way it's shown in the example?

I guess, same equal length string are concatenated?

@LuisfelipeDejesusMunoz I just added an explanation, hopefully it's clear now.

Not sure I get it, when is BC or CDEF? What decides what we concatenate and what we don't? How is it infinite if it starts at A again after Z (you mean at some point after ABCDEFGHIJKLMNOPQRSTUVWXZ we have ABCDEFGHIJKLMNOPQRSTUVWXZAB or something?)

Test case for letters that wrap around is appreciated (x,y,z,a,b...).

I strongly recommend that you use the Sandbox in the future to improve your challenge. There, you would receive feedback from fellow users to make sure your challenge is suitable for the main PPCG site! Personally, I'd leave a post in the Sandbox for at least 2 days so that everybody has a chance to see the post.

I/O suggestion: is it okay if we write a program that infinitely prints the list, instead of returning the n-th element? Also, what about returning a list of integers instead of an alphabetic string that wraps?

@JungHwanMin: not OK to infinitely print the list. I'd pass returning a list of integers.

This sequence is related to skew binary, which was featured in this challenge.

See the meta post Explaining a challenge only with test cases and examples - Programming Puzzles & Code Golf Meta Stack Exchange.

What does "I'd pass returning a list of integers" mean? Is output of a list of integers acceptable or not? If so what about "Assume that after 'Z', you get 'A' again" - should this be the case with this output format (after i+25 we get i again)? (Also update the post with the relevant information - don't leave specification to be found in comments.)

Unfortunately I don't have time anymore to improve this puzzle, sorry about that. Could someone take it over?

Python 2, 53 bytes
x,y=0,1
exec"x^=y-x;y+=x/y;"*input()
print range(x,y)

Try it online!
Similar to this construction with the transformation x = u-v, y = u

What a nice simplification! The first statement can be x^=y-x for -1 byte.

@xnor oh right, silly me

JavaScript (ES6), 59 bytes
We can save 2 bytes by making the sequence 1-indexed and using a simplification similar to the one used by KSab:
n=>(x=g=y=>n?g(y+=y==(x^=y-x),n--):x<y?[x++,...g(y)]:[])(1)

Try it online!

JavaScript (ES6), 61 bytes
Returns a list of non-wrapping integers.
n=>(g=v=>n?g(u&-u^v?v*2:!!u++,n--):v?[u-v,...g(v-1)]:[])(u=1)

Try it online!
Based upon a construction by Donald Knuth. Related OEIS entry: A182105.
How?
This is a two-stage recursive function.
We first build the sequence \$(u_n,v_n)\$ defined as \$(u_1,v_1)=(1,1)\$ and:
$$(u_{n+1},v_{n+1})=\begin{cases}(u_{n}+1,1),&\text{if }(u_{n}\operatorname{AND}-u_{n})=v_{n}\\(u_{n},2v_{n}),&\text{otherwise}\end{cases}$$
During the second pass, we build the list \$[u_n-v_n,u_n-v_n+1,\dots,u_n]\$ and eventually return it.

JavaScript (ES6), 97 bytes
Returns wrapping uppercase letters.
n=>(s=i='',g=v=>(s+=String.fromCharCode(65+i++%26),n--)?g(u&-u^v?v*2:!!u++):s.substr(u-v,v))(u=1)

Try it online!
Or 91 bytes in lowercase.

Python 2, 60 bytes
u=v=1
exec"v=u/v%2or 2*v;u+=1/v;"*input()
print range(u-v,u)

Try it online!
Based on Arnauld's use of Knuth's construction. The condition u&-u==v can be replaced with a simpler condition u/v%2>0, or alternatively u&v>0, since v is always a power of 2 that u is divisible by.

Python 2, 93 89 82 bytes
def f(n):r=[];C=1;exec"p=C%2or 2*p;r+=[p];C=r.count(p);"*n;return range(C*p-p,C*p)

Try it online!
Returns a list of integers. Similar to Arnauld's Javascript approach.

Wolfram Language (Mathematica), 80 71 bytes
Range@#2+#-#2&@@Nest[If[#~BitAnd~-#==#2,{#+1,1},{#,2#2}]&@@#&,{1,1},#]&

Try it online!
Returns a list of integers instead of a wrapping string of alphabet. 0-indexed.
Uses OEIS A182105, thanks to @Arnauld.
Printing the list indefinitely, 54 bytes
Do[j=Range@i;#∣i&&Print@j[[-#;;]]&/@(2^j/2),{i,∞}]

Try it online!
1-indexed. The TIO version has lim instead of ∞ to prevent crashes.

Jelly, 16 bytes
1;ẎṀ+ƊẎQṭƊƊ¡ị@‘Ṿ

Try it online! TIO link works well up to and including \$13\$.
Full program. Prints ,-separated list of integers.

Charcoal, 45 42 35 bytes
ＦＮ⊞υ⎇∧›Ｌυ¹⁼Ｌ§υ±¹Ｌ§υ±²⁺⊟υ⊟υ§αＬ⭆υκ⮌⊟υ

Try it online! Link is to verbose version of code. 1-indexed. I couldn't find a simple formula to generate the result so I simply followed the procedure given in the question. Explanation:
ＦＮ

Repeat the given number n times.
⊞υ

Push the next element to the predefined empty array u, calculated as...
⎇∧›Ｌυ¹⁼Ｌ§υ±¹Ｌ§υ±²

... if there is more than one element in u and the last two elements have the same length...
⁺⊟υ⊟υ

... then append the penultimate element to the last element (which builds up the result in reverse order)...
§αＬ⭆υκ

... otherwise the next letter can be found by counting how many letters we've added so far and cyclically indexing into the predefined uppercase alphabet. (Taking either the sum of length or length of sum fails when the list is empty, and mapping the list into a string saves two bytes over special-casing an empty list.)
⮌⊟υ

Take the last element of u, which is the reversed nth element of the desired list, and implicitly print the reverse.


text:
Date Occurrences
Given three non-negative integers y, m, and d (of which at least one must be positive) and a valid date with a positive year (in any reasonable format that includes the year, month, and day, and no additional information), output the date that is y years, m months, and d days after the original date.
The Gregorian calendar is to be used for all dates (even dates prior to the adoption of the Gregorian calendar).
The method for computing the next date is as follows:

Add y to the year
Add m to the month
Normalize the date by applying rollovers (e.g. 2018-13-01 -> 2019-01-01)
If the day is past the last day of the month, change it to the last day in the month (e.g. 2018-02-30 -> 2018-02-28)
Add d to the day
Normalize the date by applying rollovers (e.g. 2019-01-32 -> 2019-02-01)

Leap years (years divisible by 4, but not divisible by 100 unless also divisible by 400) must be handled appropriately. All inputs and outputs will be within the representable integer range of your language.
Test Cases
Test cases are provided in the format input => output, where input is a JSON object.
{"date":"2018-01-01","add":{"d":1}} => 2018-01-02
{"date":"2018-01-01","add":{"M":1}} => 2018-02-01
{"date":"2018-01-01","add":{"Y":1}} => 2019-01-01
{"date":"2018-01-30","add":{"M":1}} => 2018-02-28
{"date":"2018-01-30","add":{"M":2}} => 2018-03-30
{"date":"2000-02-29","add":{"Y":1}} => 2001-02-28
{"date":"2000-02-29","add":{"Y":4}} => 2004-02-29
{"date":"2000-01-30","add":{"d":2}} => 2000-02-01
{"date":"2018-01-01","add":{"Y":2,"M":3,"d":4}} => 2020-04-05
{"date":"2018-01-01","add":{"Y":5,"M":15,"d":40}} => 2024-05-11

You may use this JSFiddle for testing.
This is code-golf, so the shortest solution (in each language) wins.

Sandbox post (deleted)

@LuisfelipeDejesusMunoz The input format is not important, as is the norm here on PPCG.

Is there any restriction to the upper bounds of y, m and d (e.g. could d be 2147483000?)

@ErikF All inputs and outputs will be within the representable integer range of your language.

What about output formats? Can we output a date object? Can we take a date object?

Uh, excuse me, but I think step 3 makes step 4 obsolete. Do the "rollovers" in step 3 start from the month and not the day? Or are they only applied once, so that, for example, 2007-01-28 with d=33 becomes 2007-01-61 → 2007-02-30?

Is it OK if I output e.g. Sat Mar  3 00:00:00 UTC 2018?

@wastl Yeah that's fine, since that's the default representation of a date as a datetime stream.

@EriktheOutgolfer The rollovers in step 3 are for the month, since you can't properly determine what the last day of the month is until you've normalized the month. You don't rollover the day of the month in step 4 - you just set it to the maximum of the calculated day and the last day of the month.

C (gcc), 291 bytes
This one was pretty fun to get returning the same values as the JS builtin.
z,m=0xEEFBB3;int*y;g(){z=28+(m>>y[1]*2&3)+!(y[1]-1)*(!(*y%4)&&(*y%100)||!(*y%400));}h(a){z=(a>g())?g():a;}j(){*y+=y[1]/12;y[1]%=12;y[2]=h(y[2]);}f(int*a){y=a+6;for(z=0;z<3;z++)y[z]=a[z];y[1]--;j();*y+=a[3];y[1]+=a[4];j();y[2]+=a[5];for(;y[2]>h(y[2]);(y[1]=++y[1]%12)||++*y)y[2]-=g();y[1]++;}

Try it online!
Un-golfed:
// De No Oc Se Au Jl Jn Ma Ap Mr Fe Ja
// 31 30 31 30 31 31 30 31 30 31 28 31 = Month length
// 11 10 11 10 11 11 10 11 10 11 00 11 = Offset (2-bit representation)
//   E     E     F     B     B     3   = Hex representation

int m=0xEEFBB3; // Month lengths-28 in reverse order, stored as 2 bits/month
int *y; // Pointer to the output date, shared as a global between calls

// Regenerate month length and add leap day
int days_month(void) {
  return 28+(m>>y[1]*2&3)+!(y[1]-1)*(!(*y%4)&&(*y%100)||!(*y%400));
}

int calendar_day(int day) { return day>days_month()?days_month():day; }

void truncate_date(void) {
  *y+=y[1]/12; y[1]%=12;
  y[2]=calendar_day(y[2]);
}

void f(int *a) {
  int z;
  y=a+6;
  for(z=0;z<3;z++)y[z]=a[z];y[1]--; // Convert month to 0-based
  truncate_date();
  *y+=a[3]; y[1]+=a[4]; truncate_date();
  y[2]+=a[5];
  for(;y[2]>calendar_day(y[2]);(y[1]=++y[1]%12)||++*y)
    y[2]-=days_month();
  y[1]++; // Return month to 1-based
}

Try it online!

249 bytes

perl -MDate::Calc=:all -E, 28 bytes
$,=$";say Add_Delta_YMD@ARGV

This takes 6 arguments: the input year, month and date (as separate arguments), and the number of years, months and days to add.

This doesn't deal with the quirky "rule 4" of the task, so fails some of the test cases - for eg., perl -MDate::Calc=:all -E '$,=$";say Add_Delta_YMD@ARGV' -- 2000 2 29 1 0 0 returns 2001 3 1 instead of 2001 2 28 as the OP expects (test case 6).

R, 88 bytes
function(Y,M,D,y,m,d,o=M+m){while(is.na(x<-ISOdate(Y+y+o%/%12,o%%12,D)))D=D-1;x+864e2*d}

Try it online!
A function that takes 3 arguments (Y,M,D) for the date, and other 3 arguments (y,m,d) for the values to be added.
The output comes with prepended 12:00:00 GMT which is the default format for ISOdate's

Perl 6,  60 50 45  44 bytes
{Date.new($^a).later(:$:year).later(:$:month).later(:$:day)}

Test it (60)
Input is ( "2000-02-29", year => 1, month => 0, day => 0 )

{$^a.later(:$:year).later(:$:month).later(:$:day)}

Test it (50)
Input is ( Date.new("2000-02-29"), year => 1, month => 0, day => 0 )

{$/=$^a;$/.=later(|$_) for |[R,] $^b.sort;$/}

Test it (45)
Input is ( Date.new("2000-02-29"), %( year => 1 ) )
(No need to include keys with a value of 0)

{$/=$^a;$/.=later(|$_) for |[R,] %_.sort;$/}

Test it (44)
Input is ( Date.new("2000-02-29"), year => 1 )
Expanded:
{  # bare block lambda

  $/ = $^a; # store only positional param into a modifiable scalar
            # (params are readonly by default)

  # do a loop over the data to add

  $/ .= later(    # add using Date.later()
    |$_           # turn current iterated Pair into a named parameter
  )

    for

      |           # flatten so that `for` will iterate

        [R,]      # shorter than `reverse` (year=>1, month=>0, day=>0)

          %_.sort # sort the named arguments (day=>0, month=>0, year=>1)
  ;

  # return new Date
  $/
}

You can remove the space before the for

C# (.NET Core), 48 bytes
(a,y,m,d)=>a.AddYears(y).AddMonths(m).AddDays(d)

Try it online!

Java 8, 51 bytes
(s,y,m,d)->s.plusYears(y).plusMonths(m).plusDays(d)

Input (s) and output are both java.time.LocalDate.
Try it online.
Explanation:
(s,y,m,d)->        // Method with LocalDate and 3 int parameters and LocalDate return-type
  s.plusYears(y)   //  Add the years to the input start-Date
   .plusMonths(m)  //  Add the months as well
   .plusDays(d)    //  And add the days as well

R, 65 bytes
function(x,y){require(lubridate)
x%m+%period(y,c("ye","mo","d"))}

Uses the lubridate package. The %m+% infix operator is sugar for the add_with_rollback function which essentially implements what the question asks for.
TIO doesn't have lubridate so you can Try It Here Instead with f <- prepended to the function above along with test cases:
f(as.Date("2018-01-01"),c(0,0,1))
f(as.Date("2018-01-01"),c(0,1,0))
f(as.Date("2018-01-01"),c(1,0,0))
f(as.Date("2018-01-30"),c(0,1,0))
f(as.Date("2018-01-30"),c(0,2,0))
f(as.Date("2000-02-29"),c(1,0,0))
f(as.Date("2000-02-29"),c(4,0,0))
f(as.Date("2000-01-30"),c(0,0,2))
f(as.Date("2018-01-01"),c(2,3,4))
f(as.Date("2018-01-01"),c(5,15,40))

You can save save two bytes with:function(x,y)x%m+%period(y,c("ye","mo","d")) require(lubridate) (require outisde of function)

Bash, 150 149 bytes
a=$2+$5-1+b
y=$1+$4+a/12
m=1+a%12
d=date
$d -d@$[$($d +%s+$6*86400 -d$[y]-$[m]-$($d +$3%n%d -d@$[`b=1;$d +%s-86400 -d$[y]-$[m]-1`]|sort -n|head -1))]

Try it online!
Takes input via command line arguments in order: old year, old month, old day. year change, month change, day change. Outputs a string like Wed Feb 28 00:00:00 UTC 2018 to stdout.

PHP, 203 bytes
<?list(,$a,$y,$m,$d)=$argv;$b=new DateTime($a);$j=$b->format('j');$b->modify("+$y year +$m month");$j==$b->format('j')?:$b->modify('last day of last month');$b->modify("+$d day");echo$b->format('Y-m-d');

To run it:
php -n <filename> <date> <y> <m> <d>

Example:
php -n date_occurrences.php 2018-01-01 5 15 40

Or Try it online!
Tests: Try it online!

T-SQL, 53 Bytes
SELECT DATEADD(D,d,DATEADD(M,m,DATEADD(Y,y,a)))FROM t

I'm not sure that it matters, but I'm applying the Year adjustment, followed by the Month adjustment, followed by the Day. All test values check out.
Per our IO standards, input is taken from a pre-existing table t with date field a and integer fields y, m, and d.
Note interestingly that it isn't the capitalization that matters between the date type codes (D, M, and Y) and my input values (d, m, and y) its simply the order of parameters in the SQL DATEADD function.

Does this pass test case 6? Since it doesn't implement Rule 4, I think it'd give 2001 3 1 instead of 2001 2 28 for input 6.

@sundar Looks like you are correct; I thought I had passed all the test cases. I'll see if it can be fixed...


text:
Ex-Increasing Set Sequence
Background
An ex-increasing set sequence of order \$N\$ is defined as a sequence of integer sets \$S_1,S_2,\cdots,S_n\$ which satisfies the following:

Each \$S_i\$ is a non-empty subset of \$\{1,2,\cdots,N\}\$.
For \$1\le i<n\$, \$S_i \cap S_{i+1} = \varnothing\$, i.e. any two consecutive sets have no elements in common.
For \$1\le i<n\$, the mean (average value) of \$S_i\$ is strictly less than that of \$S_{i+1}\$.

Challenge
Given a positive integer N, output the length of the longest ex-increasing set sequence of order N.
Test cases
These are based on the results by Project Euler user thundre.
1 => 1 // {1}
2 => 2 // {1} {2}
3 => 3 // {1} {2} {3}
4 => 5 // {1} {2} {1,4} {3} {4}
5 => 7 // {1} {2} {1,4} {3} {2,5} {4} {5}
6 => 10 // {1} {2} {1,4} {3} {1,4,5} {2,3,6} {4} {3,6} {5} {6}
7 => 15 // {1} {2} {1,4} {3} {1,2,7} {3,4} {1,2,5,7} {4} {1,3,6,7} {4,5} {1,6,7} {5} {4,7} {6} {7}
8 => 21
9 => 29
10 => 39
11 => 49
12 => 63
13 => 79
14 => 99
15 => 121
16 => 145
17 => 171
18 => 203
19 => 237
20 => 277
21 => 321
22 => 369
23 => 419
24 => 477
25 => 537

Rules
Standard code-golf rules apply. The shortest valid submission in bytes wins.
Bounty
This problem has been discussed here on Project Euler forum about 4 years ago, but we failed to come up with a provable polynomial-time algorithm (in terms of N). Therefore, I will award +200 bounty to the first submission that achieves this, or prove its impossibility.

I've spent over a week trying to come up with a polynomial-time algorithm or an NP-hardness proof using a reduction. Has anyone here made any progress on this?

Brachylog, 28 bytes
⟦₁⊇ᶠk⊇pSs₂ᶠ{c≠&⟨+/l⟩ᵐ<ᵈ}ᵐ∧Sl

Try it online!
This is really damn slow. Takes about 30 seconds for N = 3, and it didn't complete after 12 minutes for N = 4.
Explanation
⟦₁                             Take the range [1, …, Input]
  ⊇ᶠk                          Find all ordered subsets of that range, minus the empty set
     ⊇                         Take an ordered subset of these subsets
      pS                       Take a permutation of that subset and call it S
       Ss₂ᶠ                    Find all substrings of 2 consecutive elements in S
           {           }ᵐ      Map for each of these substrings:
            c≠                   All elements from both sets must be different
              &⟨+/l⟩ᵐ            And the average of both sets (⟨xyz⟩ is a fork like in APL)
                     <ᵈ          Must be in strictly increasing order
                         ∧Sl   If all of this succeeds, the output is the length of L.

Faster version, 39 bytes
⟦₁⊇ᶠk⊇{⟨+/l⟩/₁/₁}ᵒSs₂ᶠ{c≠&⟨+/l⟩ᵐ<₁}ᵐ∧Sl

This takes about 50 seconds on my computer for N = 4.
This is the same program except we sort the subset of subsets by average instead of taking a random permutation. So we use {⟨+/l⟩/₁/₁}ᵒ instead of p.
{         }ᵒ     Order by:
 ⟨+/l⟩             Average (fork of sum-divide-length)
      /₁/₁         Invert the average twice; this is used to get a float average

We need to get a float average because I just discovered a ridiculous bug in which floats and integers don't compare by value but by type with ordering predicates (this is also why I use <ᵈ and not <₁ to compare both averages; the latter would require that double inversion trick to work).

I was planning to slowly work my way up to tackling this one (since @JonathanAllan mentioned it in the other comment), but I'm probably weeks behind coming up with anything like this! I like how (like most Brachylog answers) in the end it just looks like a neat restatement of the question itself.

@sundar you can always come back to it later and try to rediscover a solution!

CJam (81 bytes)
{YY@#(#{{2bW%ee{)*~}%}:Z~{)Z__1b\,d/\a+}%$}%{_,1>{2ew{z~~&!\~=>}%0&!}{,}?},:,:e>}

Online demo. It should execute for input 4 in a reasonable time, but I wouldn't try it with higher inputs.
Dissection
{                 e# Declare a block (anonymous function)
  YY@#(#          e# There are 2^N subsets of [0, N), but the empty subset is problematic
                  e# so we calculate 2^(2^N - 1) subsets of the non-empty subsets
  {               e# Map integer to subset of non-empty subsets:
    {             e#   Define a block to map an bitset to its set indices; e.g. 9 => [0 3]
      2bW%ee      e#     Convert to base 2, reverse, and index
      {)*~}%      e#     If the bit was set, keep the index
    }:Z           e#   Assign the block to variable Z
    ~             e#   Evaluate it
    {             e#   Map those indices to non-empty subsets of [0, N):
      )Z          e#     Increment (to skip the empty set) and apply Z
      __1b\,d/    e#     Sum one copy, take length of another, divide for average
      \a+         e#     Wrap the subset and prepend its average value
    }%
    $             e#   Sort (lexicographically, so by average value)
  }%
  {               e# Filter out subsets of subsets with conflicts:
    _,1>{         e#   If the length is greater than 1
      2ew         e#     Take each consecutive pair of subsets
      {           e#     Map:
        z~        e#       Zip and expand to get [score1 score2] [subset1 subset2]
        ~&!\      e#       No element in common => 1
        ~=        e#       Different scores => 0
        >         e#       1 iff both constraints are met
      }%
      0&!         e#     1 iff no consecutive pair failed the test
    }{
      ,           e#   Otherwise filter to those of length 1
    }?
  },
  :,:e>           e# Map to size of subset and take the greatest
}

JavaScript (ES6), 175 bytes
A naive and rather slow recursive search. Takes about 15 seconds to compute the 7 first terms on TIO.
n=>(a=[...Array(n)].reduce(a=>[...a,...a.map(y=>[x,...y],x=n--)],[[]]),g=(p,b=a,n)=>a.map(a=>(m=a.map(n=>s+=++k*b.includes(n)?g:n,s=k=0)&&s/k)>p&&g(m,a,-~n),r=r>n?r:n))(r=0)|r

Try it online!
or test this modified version that outputs the longest ex-increasing set sequence.
How?
We first compute the powerset of \$\{1,2,\dots,n\}\$ and store it in \$a\$:
a = [...Array(n)].reduce(a =>
  [...a, ...a.map(y => [x, ...y], x = n--)],
  [[]]
)

Recursive part:
g = (                         // g = recursive function taking:
  p,                          //   p = previous mean average
  b = a,                      //   b = previous set
  n                           //   n = sequence length
) =>                          //
  a.map(a =>                  // for each set a[] in a[]:
    (m = a.map(n =>           //   for each value n in a[]:
      s +=                    //     update s:
        ++k * b.includes(n) ? //       increment k; if n exists in b[]:
          g                   //         invalidate the result (string / integer --> NaN)
        :                     //       else:
          n,                  //         add n to s
      s = k = 0)              //     start with s = k = 0; end of inner map()
      && s / k                //   m = s / k = new mean average
    ) > p                     //   if it's greater than the previous one,
    && g(m, a, -~n),          //   do a recursive call with (m, a, n + 1)
    r = r > n ? r : n         //   keep track of the greatest length in r = max(r, n)
  )                           // end of outer map()

Python 3, 205 197 184 182 bytes

Saved eight twenty-one bytes thanks to ovs.
Saved two bytes thanks to ceilingcat.

f=lambda N,c=[[1]]:max([len(c)]+[f(N,c+[n])for k in range(N)for n in combinations(range(1,N+1),k+1)if not{*c[-1]}&{*n}and sum(c[-1])/len(c[-1])<sum(n)/len(n)]);from itertools import*

Try it online!

197 bytes using sum instead of chain.from_iterable.

@ceilingcat Thank you.


text:
Draw the "Cool S"
Introduction
We all know the cool S (also known as Superman S, Stüssy S, Super S, Skater S, Pointy S, Graffiti S etc. etc.): billions of schoolchildren around the world drew this S and immediately felt proud of themselves. In case you've forgotten or had a completely uncool childhood, here is an image of said cool S:

Given a scale factor n as input (where \$1\leq n\leq 20\$), output the Cool S in ASCII art.
How to Draw It
From the Wikipedia page on the Cool S:

Output
The Cool S when n = 1 is:
   ^
  / \
 /   \
/     \
|  |  |
|  |  |
\  \  /
 \  \/
 /\  \
/  \  \
|  |  |
|  |  |
\     /
 \   /
  \ /
   v

And for different values of n, you simply make the output n times bigger. For example, n=2:
     ^
    / \
   /   \
  /     \
 /       \
/         \
|    |    |
|    |    |
|    |    |
|    |    |
\    \    /
 \    \  /
  \    \/
  /\    \
 /  \    \
/    \    \
|    |    |
|    |    |
|    |    |
|    |    |
\         /
 \       /
  \     /
   \   /
    \ /
     v

Note that the vertical sections are two times longer and the spacing between the vertical lines is two times wider.
And when n=3:
       ^
      / \
     /   \
    /     \
   /       \
  /         \
 /           \
/             \
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
\      \      /
 \      \    /
  \      \  /
   \      \/
   /\      \
  /  \      \
 /    \      \
/      \      \
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
\             /
 \           /
  \         /
   \       /
    \     /
     \   /
      \ /
       v

Note: Although not required, your code may also be able to support n=0:
 ^
/ \
\\/
/\\
\ /
 v

Winning
The shortest program in bytes wins.

Related: Draw an S-Chain

The ASCII-building 90's kid in me wants to suggest using /\ instead of ^ for the tip. Looks cleaner that way, plus it maintains the same slope inclination :)

@Flater only problem is that /\ uses two characters, so the central vertical line would have to be offset which makes it look very untidy

@BetaDecay: It looks fine on N=2 and N=3 (since it retains point symmetry), but I agree for N=1. There's also the option of the upside down V: Λ

@Flater Since we're judging by bytes, wouldn't a unicode character potentially count as >1 byte?

@JacobGarby: My argument was stylistic, not golfy :)

Charcoal, 58 53 47 43 41 bytes
Ｎθ≔⊕⊗θδ↗θ/⊗θ↘δ^‖Ｂ↓‖Ｍ← vＭδ⁰⊗θ↗⊕θＭ⁰δ↗θ/⊗θ⟲Ｔ

Try it online!
I just wanted to try another approach, this draws the outside via reflections (thanks to Neil for expanding the idea) and then draws the inside part. As Charcoal has :Left as default direction to draw lines, I make use of that direction as much as possible to save some bytes by drawing the S horizontally, like this:
     /----\    /----\
    /      \  /      \
   /        \/        \
  /         /          \
 /         /            \
v     ----/    /----     ^
 \            /         /
  \          /         /
   \        /\        /
    \      /  \      /
     \----/    \----/

And then I just need to rotate the canvas 90 degrees counterclockwise.

You may be onto something there... 22 bytes gets you all of the outside...

@Neil it wasn't exactly like that, your idea needed a minor fix, but indeed this has been a great improvement!

Yeah I made a similar mistake on my original post because I didn't check the effect of scaling correctly.

Did someone say Rotate? That gives me an idea...

@Neil hey, you got quite an improvement there! :-)

I'd say that either using the v and ^ or using the - is wrong. I assumed you used the ^ and v so that you can rotate the grid while retaining the characters, but then the same logic does not apply to - which you'd need to replace by | (and similarly, all slashes should then be inverted too... I think)

@Flater when you perform a RotateTransform in Charcoal, the only characters that get rotated are the ones Charcoal knows how to rotate. These include the / that gets rotated to \\ and the - that gets rotated to |, but not the v and the ^. So in this case I need to print the final characters even when I'm drawing the horizontal S.

Yes, it's a neat trick, saved me 3 bytes on "Double up some diamonds" too.

Charcoal, 47 42 41 bytes
Ｆv^«↓⊗θ↘⊗⊕θ←↓⊗θ↙⊕⊗θ↖ι↖⊕⊗θ→↑⊗θ↗⊕θＭθ⁺⊗θ⊕θ⟲⁴

Try it online! Link is to verbose version of code. Explanation: Draws the following lines in order:
   ^
  / \
 /   \
/     \
|  1  |
|  1  |
\  2  /
 \  2/
 8\  2
8  \  2
7  |  3
7  9  3
6     4
 6   4
  6 4
   5

Where 5 is the current character of the string v^. At the end of the first loop the cursor is then positioned at point 9. The entire canvas is then rotated so that the other half of the Cool S can be drawn. (The canvas actually gets rotated twice, but this is just an implementation detail.)
Charcoal doesn't support RotateCopy(:Up, 4) but if it did then this would work for 33 bytes:
↖^↖⊕⊗θ→↑⊗θ↗⊕θ‖ＢＭ↓↙⊗θ→↓⊗θ⟲Ｃ↑⁴Ｊ⁰¦⁰v

@BetaDecay Sorry about that. I also had the wrong byte count anyway...

Nice, it gets n=0 right too

Python 3, 255 249 248 209 bytes
-6 bytes thanks to Kevin Cruijssen
-1 byte thanks to Kevin Cruijssen
-39 bytes thanks to Rod and Jo King
n=int(input())
m=2*n
a,b,q,c,l='\ \n/|'
f=m*b
s=q+q.join([f[d:]+c+b*2*d+b+a+f[d:]for d in range(m+1)]+[l+f+l+f+l]*m+[d*b+a+f+a+f[d*2:]+c+d*b for d in range(n)]+[n*b+a+f+a+c+n*b])
print(f,'^'+s+q+s[::-1]+f,'v')

Try it online!
It now handles n=0.

Both o+~d can be m-d and range(o) can be range(m+1), and then you can remove o=m+1\n to save 6 bytes. Nice answer though, +1 from me.

Oh, and one more byte by changing p(s)\np(s[::-1]) to p(s+q+s[::-1]): 248 bytes

You can save 6 bytes if you use a single print, and more 4 by removing [] from join([...]), totalizing 238 bytes

You can also store q.join in a variable to save a byte

217. Joined all the q.joins, and a couple of other things

209 bytes

Canvas, 36 32 29 bytes
«|＊‼ｌ├／Ｌ１^╋；╶╵＼∔∔│α╶«├：╵╋：↔↕∔

Try it here!
A whole lot of stack manipulation. (outdated) explanation:
«|*                                an array of input*2 "|"s
   ‼                               cast to a 2D object (needed because bug)
    :                              duplicate that (saved for the center line)
     l├                            height+2
       /                           create a diagonal that long
        L1^╋                       and in it, at (width; 1) insert "^"
            ;∔                     append the vertical bars
                               ^
                              /
          so far done:       /
                            /
                            |
                            |
              ⁸╵                   input+1
                \                  antidiagonal with that size
                 ∔                 appended to the above
                  │                mirror horizontally
                              ^
                             / \
                            /   \
                           /     \
                current:   |     |
                           |     |
                           \     /
                            \   /                                                       |
                   α               get the 2nd to last popped thing - the antidiagonal  |
                    └∔             append it to the vertical line copied way before:    \
                      ⁸«├          input/2 + 2                                            \
                         :╵        duplicate + 1
                           ╋       at (input/2 + 2; input/2 + 3) in the big part insert  ^
                            :↔↕∔   mirror a copy vertically & horizontally and append that to the original

C (gcc), 260 254 bytes
-6 bytes thanks to ceilingcat.
f(n){int s=2*n++,t=s+1,I[]={1,t,s,n,n,s,t,1},A[]={s,1,1,1,2*t,1,t,t,1,t,1,n,t,t,1,t,t,1,1,1,t,s,1,1},x;for(s=8;s--;)for(n=0;n<I[s];n++,puts(""))for(t=3;t--;)x=s*3+t,printf("%*c",n*("AAAA?BAAAAC@?ABAAACA@AAA"[x]-65)+A[x],"w!!!0]}}}]]00]]}}}]!0_!!"[x]-1);}

Try it online!
Rundown
We can divide the shape into parts:
 ^           Top cap
/ \          Top slope
|||          Sides
\\/          Twist, part 1
/\\          Twist, part 2
|||          Sides
\ /          Bottom slope
 v           Bottom cap

Each part could be described by a number of lines, three chars, and three relationships to certain values that decides the field-width at each line.
A first iteration came to be:
#define g(x,s,A,B,C)for(i=0;i<x;i++)printf("%*c%*c%*c\n",A,*s,B,s[1],C,s[2]);
f(n)
{
    int s=2*n++,t=s+1,i;

    g(1,  "  ^",  1,      1,  t-1)
    g(t, "/ \\",t-i,      1,2*i+1)
    g(s,  "|||",  1,      t,    t)
    g(n,"\\\\/",i+1,      t,t-2*i)
    g(n,"/\\\\",n-i,  2*i+1,    t)
    g(s,  "|||",  1,      t,    t)
    g(t, "\\/ ",i+1,2*t-2*i,    1)
    g(1,  "  v",  1,      1,  t-1)
}

The calls to the g() macro looks very much like a table could be constructed and looped over. Field-widths are sometimes related to the index counter, and sometimes not. We can generalise the field-width to be F * i + A, where F is some factor to multiply i with, and A is some value to add to the width. So the last width of the fourth call above would be -2 * i + t, for example.
Thus we get:
f(n){int s=2*n++,t=s+1,         s = size of "side" parts, t = size of top and bottom slopes
I[]={1,t,s,n,n,s,t,1},          The number of lines per part.
A[]={...},x;                    A[] holds the values to add to each field-width.
for(s=8;s--;)                   Loop through the parts.
for(n=0;n<I[s];n++,puts(""))    I[s] decides how many lines to the part. Ends with newline.
for(t=3;t--;)                   Go through the three chars of each line.
x=s*3+t,                        Calculate offset.
printf("%*c",                   Print the char.
n*("..."[x]-65)+A[x],           Build field-width. The string holds the index factor, A[]
                                holds the offset part.
"..."[x]-1);}                   The char itself is grabbed from the string.
                                Shifted by 1 to eliminated double backspaces.

In the end it was not much shorter than a tightened version of the g() calling one, but shorter is shorter.

@ceilingcat Cheers.

@ceilingcat The undefined evaluation order of function arguments give me pause.

for(n=-1;++n<I[s];puts("")) saves a byte.

Building on @veqtrus 252 bytes

Python 2, 227 208 207 202 196 181 bytes
I=n=2*input()
R,L,S,P='/\ |'
k=n*[2*(P+S*n)+P]
exec"k=[R+S+2*S*I+L]+k+-~I%2*[L+S*n+L+S*I+R];I-=1;"*-~n
print'\n'.join(t.center(2*n+3)for t in['^']+k+[a[::-1]for a in k[::-1]]+['v'])

Try it online!
Thks to Jo King for 1 byte; and then another 5 bytes total (via n => 2*n).
Works for n=0 as well.

C (gcc), 379 353 344 334 bytes
I used a couple of #defines for subexpression elimination and several globals to communicate between the internal functions. The main loop goes {0,1,2,3,3,2,1,0} to construct the S.
Thanks to Jonathan Frech for the suggestions.
#define z(a,b...)printf("%*c%*c%*c\n"+a,b);}
#define y(a){for(i=~-a*t;v*i<v*a*!t+t;i+=v)
i,n,p,r,t,u,v;a(){z(6,r+2,94+t*24)b()y(-~r)z(3,-i-~r,47+u,i*2+2,92-u)c()y(r)z(0,~r,124,~r,124,~r,124)d()y(-~n)z(0,i+1,92-u,2*(n-t*i)+1,92,2*(n-!t*i)+1,47+u)(*x[])()={a,b,c,d};f(s){r=2*s;for(p=0;p<8;x[7*t-p++*(2*t-1)](n=s))t=p>3,v=2*!t-1,u=t*45;}

Try it online!

w -r-1 could possibly be golfed to w~r.

Though then inlining is one byte shorter.

344 bytes.

307 bytes

PHP, 378 374 378 377 376 335 331 328 bytes
-3 bytes, thanks to manatwork
-4 bytes, used str_pad instead of str_repeat
-41 bytes, thanks to manatworks' suggestions
-1 byte, merged two increments into a +=2
-1 byte, removed superfluous \
-4 bytes by echoing once. Forgot I needed to pass the string into the function so this is more bytes
Works for n = 0 as well.
function s($b){return str_pad($w,$b);}echo s($i=1+$a=2*$argv[1]).'^
';for(;$i;$j++,$y=$z.$y)echo$z=s(--$i).'/'.s(++$j).'\
';for(;$k<$a;$k++)$x.='|'.s($a).'|'.s($a).'|
';echo$x;for(;$l<=$a/2;)echo s($m++).$c='\\',s($a).$c.s($a-$l++*2).'/
';for(;$m;$n+=2)echo s(--$m).'/'.s($n).$c.s($a).'\
';echo$x.strtr($y,'/\\','\/').s($a+1).v;

Try it online!

As function declaration is quite expensive and you use t() only twice, would be shorter without it. If beside the 9 notices you take 1 warning too, you can remove the quotes around 'v' in the final echo.

You could use single loop for the top and bottom oblique parts. The initialization of $a and $i could be compacted by moving them at their first usage.

Oh, and $i>0 and $m>0 can be written simply as $i and $m.

With trailing spaces, as in some other solutions.

@manatwork thanks for all the help! Some really nice tricks to use in other answers too

You can also move the declaration of $c to its first usage. Just change the . concatenation after it to ,. Try it online!

Java, 435 bytes
The function itself takes 435 bytes. There is certainly room for improvement, "high level" by analyzing the rules about where to place which character (in the end the S is point-symmetric), and "low-level", by classical golfing (maybe pulling out another variable or combining two of the for-loops). But it's a first shot with this rather ungolfy language:
import static java.util.Arrays.*;
import static java.lang.System.*;

public class CoolS
{
    public static void main(String[] args)
    {
        print(1);
        print(2);
        print(3);
    }
    static void print(int n){int i,r,d=3+6*n,w=3+n*4,h=6+n*10,m=n+n,v=w/2,k=h-1,j=w-1;char t[],S='/',B='\\',P='|',s[][]=new char[h][w];for(char x[]:s)fill(x,' ');s[0][v]='^';s[k][v]='v';for(i=0;i<1+m;i++){r=i+1;t=s[r];t[v-r]=S;t[v+r]=B;t=s[k-r];t[v-r]=B;t[v+r]=S;}for(i=0;i<m;i++){r=2+m+i;t=s[r];t[0]=t[v]=t[j]=P;t=s[k-r];t[0]=t[v]=t[j]=P;}for(i=0;i<1+n;i++){r=2+m+m+i;t=s[r];t[i]=t[i+1+m]=B;t[j-i]=S;t=s[d-i];t[i]=S;t[v-i]=t[j-i]=B;}for(char x[]:s)out.println(x);}
}

Hi there. Imports are part of the byte-count I'm afraid, so your current answer is actually 478 bytes. You can however golf it down to (coincidentally enough) your current 435 bytes with some basic things to golf.

Been able to golf a bit more to 405 bytes by removing some variables and using t=... a bit less where it would save bytes. If you have any questions about any of the changes I made, let me know. :)

Thanks @KevinCruijssen , unfortunately I currently cannot invest more time here - this was just a recreational thing, and considering the "verbosity" of Java, not a serious competitor anyhow ;-) Consider adding your solution as an own answer, though - then we at least have some intra-language competition :-)

><>, 1024 bytes
i'0'-i1+:?!v1-'0'-$a*+1v
v          <           <
>~     :1-2*3+ >1-' 'v       v                                             oa&0~~~<
 v&1:oa*2:~o'^'^?:o  <                                              >~'/'o$:v    <^        <
>>' 'o1-: ?v   v                  >@ '\'o$v v   -1o<           >          v >:?vv^ -1<     ^     <
:^         <   ~                  ~>      \:>:?v       v  >'/'v^o' '^!?:-1<:<  > ' 'o^ >'\'o:1-?v^
- vo' '<:&o'/' < <                ^^?:o' '\  \ >' '/'\'\~$^ > o:?v~1>$  :?v$^   ~!   oa  $+2$-1 <
^1\1-:?^~'\'oao v                /        \-1<:@@~o/o1-    v^a<  >1+^v:$-2<vo'\'<      ^@~<v             <
 v^?:+1v!?:-1&+2/            /   /        \        \' '^!?:<         <     >$@@:>1-' 'o:?v^      >~'\'o$v^    oa<
       >         ^     /-1   /-1 /        \        \       \:0:<                ^        <   v      -1< :v o' '<^ +1$-2  <      v    -1<
 >~&~1&         >:2*:1->'|'o1>@@:>' 'o1-:?^~@'|'o:?^~ao:  ?^~&?^                 1+2*0     >:>:?!^' 'o^ >>1-: ?^~'/'o:2-?^@@2*ao>' 'o:?^'v'o ;

Takes one number 1-99 as input and draws the Cool S.
The program uses only one stack to store the number of spaces.
It is almost not golfed, coded just for practice and fun :D
Try it online!

Welcome to the site, and nice first answer! Since the question specifies that scale factors up to 20 must be supported, you'll need to modify your answer to allow 2-digit inputs. I think it shouldn't be too hard, given what you've already accomplished. :)

@DLosc Сhanged.

Python 3, 321 307 bytes
Thanks to @EsolangingFruit for saving 14 bytes
n=int(input())
b,f='\/'
c,l=4*n+3,10*n+6
r=range
h=c//2
L=[c*[' ']for _ in r(l)]
L[0][h],L[-1][h]='^v'
for i in r(h):a=L[h-i];a[i],a[c+~i]=f,b
for i in r(2*n):L[h-~i][0::h]='|'*3
for i in r(n+1):a=L[h+h+i];a[c+~i],a[i:c-1:h]=f,b*2
for i in r(1,l//2):L[l+~i]=L[i][::-1]
print('\n'.join(''.join(i)for i in L))

Try it online!
Python 2, 303 bytes
n=int(input())
b,f='\/'
c,l,r=4*n+3,10*n+6,range
h=c/2
L=[c*[' ']for _ in r(l)]
L[0][h],L[-1][h]='^v'
for i in r(h):a=L[h-i];a[i],a[c+~i]=f,b
for i in r(2*n):L[h-~i][0::h]='|'*3
for i in r(n+1):a=L[h+h+i];a[c+~i],a[i:c-1:h]=f,b*2
for i in r(1,l/2):L[l+~1]=L[i][::-1]
print'\n'.join(''.join(i)for i in L)

Try it online!

You can replace '\\','/' on the second line with *'\/' to save three bytes.

307 bytes: Try it online!

Thanks! @EsolangingFruit! I was not aware of bit operations in Python. Also, it would save a few bytes to use Python2 because of the division and parentheses in print

In Python 2, input() automatically eval()s the string, so you can skip the int() call as well.

For Python 3, you can change the last line to for l in L:print(*l,sep="") (I don't think there is an equivalent in Python 2).

Regenerate, 180 bytes
( {2*$~1}) ^\n(( {#3-1}|$1)/(  $4| )\\\n){#1+1}((\|$1\|$1\|\n){#1})(( $8|)(\\$1\\)( {#10-2}|$1)/\n){$~1+1}(( {#12-1}|$8)/(  $13|)$9\n){$~1+1}$5(( $15|)\\( {#16-2}|$4)/\n){#1+1}$1 v

Takes input as a command-line argument. Try it here!
Explanation
Hoo boy, this is long. It's not actually super-complicated, though; once you get a few basic principles of golfing in Regenerate, this just uses the same techniques over and over.
( {2*$~1})

Group 1: Take the command-line argument ($~1), multiply it by 2, and add that many spaces.
 ^\n

Complete the first line with one more space, ^, and a newline.
(...){#1+1}

Group 2 generates one line of the / \ section. Repeat it (length of group 1, plus 1) times. It contains groups 3 and 4.
( {#3-1}|$1)/

Group 3: Add spaces, one fewer than the last time we matched group 3; or, if group 3 hasn't been matched before, start with the contents of group 1 (arg * 2 spaces) instead. After group 3, add a forward slash.
(  $4| )\\\n

Group 4: Add spaces, two more than the last time we matched group 4; or, if group 4 hasn't been matched before, start with one space instead. After group 4, add a backslash and a newline.
((\|$1\|$1\|\n){#1})

Group 5 is the whole vertical lines section, which we're capturing because we can reuse it verbatim later. Specifically, this is (length of group 1) repetitions of group 6, which consists of: pipe, group 1, pipe, group 1, pipe, newline.
(...){$~1+1}

Group 7 generates one line of the \ \/ section. Repeat it (argument plus 1) times. It contains groups 8, 9, and 10.
( $8|)

Group 8: Add spaces, one more than the last time we matched group 8; or, if group 8 hasn't been matched before, start with empty string instead.
(\\$1\\)

Group 9: backslash, group 1, backslash (capture for reuse later).
( {#10-2}|$1)/\n

Group 10: Add spaces, two fewer than the last time we matched group 10; or, if group 10 hasn't been matched before, start with the contents of group 1 instead. After group 10, add a forward slash and a newline.
(...){$~1+1}

Group 11 generates one line of the /\ \ section. Repeat it (argument plus 1) times. It contains groups 12 and 13.
( {#12-1}|$8)/

Group 12: Add spaces, one fewer than the last time we matched group 12; or, if group 12 hasn't been matched before, start with the most recent contents of group 8 instead. After group 12, add a forward slash.
(  $13|)$9\n

Group 13: Add spaces, two more than the last time we matched group 13; or, if group 13 hasn't been matched before, start with empty string instead. After group 13, add the contents of group 9 (two backslashes with some spaces in between) and a newline.
$5

Add the contents of group 5 again (vertical pipes section).
(...){#1+1}

Group 14 generates one line of the \ / section. Repeat it (length of group 1, plus 1) times. It contains groups 15 and 16.
( $15|)\\

Group 15: Add spaces, one more than the last time we matched group 15; or, if group 15 hasn't been matched before, start with empty string instead. After group 15, add a backslash.
( {#16-2}|$4)/\n

Group 16: Add spaces, two fewer than the last time we matched group 16; or, if group 16 hasn't been matched before, start with the most recent contents of group 4 instead. After group 16, add a forward slash and a newline.
$1 v

For the last line, add the contents of group 1, a space, and v.

Oh, I like Regenerate, But Is there a way to add two numbers in Regenerate?

@Fmbalbuena Yep

C (gcc), 271 261 253 230 bytes
-10 bytes by moving 2* inside S macro
-8 bytes by placing u,d in the global scope and replacing (n-u) with d
-23 bytes by abusing the C preprocessor, thanks to @ceilingcat
#define S(i,c)printf("%*s"#c,2*i,"");
#define R(m)}for(u=0,d=n*m+1;d--;u++){S(0+
#define V(x,y)S(x,\\\n)R(2-1)0,|)S(n,|)S(n,|\n)R(y)u,\\)S(
u,d;f(n){{S(n+1,^\n)R(2)d,/)V(u+1,1)n,\\)S(d,/\n)R(1)d,/)S(u,\\)V(n,2)d+1,/\n)}S(n+1,v\n)}

Try it online!

Vyxal C, 49 bytes
\^?d›(\/n꘍øM)\|?꘍m∞?dḊ?›(\\?꘍m?›n-d꘍\/J)W:ṘRJṪ\vJ

Try it Online!
Will add explanation tomorrow.