text:
How many consecutive descending numbers in my number?
2019 has come and probably everyone has noticed the peculiarity of this number: it's in fact composed by two sub-numbers (20 and 19) representing a sequence of consecutive descending numbers.
Challenge
Given a number x, return the length of the maximum sequence of consecutive, descending numbers that can be formed by taking sub-numbers of x.
Notes :

sub-numbers cannot contain leading zeros (e.g. 1009 cannot be split into 10,09)
consecutive and descending means that a number in the sequence must be equal to the previous number -1, or \$n_{i+1} = n_{i}-1\$ (e.g. 52 cannot be split into 5,2 because 5 and 2 are not consecutive, 2 ≠ 5 - 1)
the sequence must be obtained by using the full number, e.g. in 7321 you can't discard 7 and get the sequence 3,2,1
only one sequence can be obtained from the number, e.g. 3211098 cannot be split into two sequences 3,2,1 and 10,9,8

Input

An integer number (>= 0) : can be a number, or a string, or list of digits

Output

A single integer given the maximum number of decreasing sub-numbers (note that the lower-bound of this number is 1, i.e. a number is composed by itself in a descending sequence of length one)

Examples :
2019         --> 20,19           --> output : 2
201200199198 --> 201,200,199,198 --> output : 4
3246         --> 3246            --> output : 1
87654        --> 8,7,6,5,4       --> output : 5
123456       --> 123456          --> output : 1
1009998      --> 100,99,98       --> output : 3
100908       --> 100908          --> output : 1
1110987      --> 11,10,9,8,7     --> output : 5
210          --> 2,1,0           --> output : 3
1            --> 1               --> output : 1
0            --> 0               --> output : 1
312          --> 312             --> output : 1
191          --> 191             --> output : 1

General rules:

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

Migrated from sandbox : https://codegolf.meta.stackexchange.com/questions/2140/sandbox-for-proposed-challenges/17247#17247

Is the test case 210 -> 2,1,0 wrong (same with 0 -> 0)? The tasks says "sub-numbers cannot contain leading zeros", is zero a special case?

@BMO: well, here the topic is kinda phylosofical... :D to me, 0 is a number with no (useless) leading zero, so yes zero is a special case

would you call these... condescending numbers? xD sorry that was like not even funny

Sorry, deleted my comment in which I asked about 212019. Seems I didn't read all the rules.

JavaScript (ES6), 56 bytes
A port of ArBo's Python answer is significantly shorter. However, it fails on some test cases because of too much recursion.
f=(n,a=0,c=0,s)=>a<0?f(n,a-~c):n==s?c:f(n,--a,c+1,[s]+a)

Try it online!

JavaScript (ES6), 66 bytes
Takes input as a string.
f=(s,n=x='',o=p=n,i=0)=>s[i++]?o==s?i:f(s,--n,o+n,i):f(s,p+s[x++])

Try it online!
Commented
f = (               // f = recursive function taking:
  s,                //   s = input number, as a string
  n =               //   n = counter
  x = '',           //   x = position of the next digit to be added to p
  o = p = n,        //   o = generated output; p = prefix
  i = 0             //   i = number of consecutive descending numbers
) =>                //
  s[i++] ?          // increment i; if s[i] was defined:
    o == s ?        //   if o is matching s:
      i             //     stop recursion and return i
    :               //   else:
      f(            //     do a recursive call with:
        s,          //       s unchanged
        --n,        //       n - 1
        o + n,      //       (n - 1) appended to o
        i           //       i unchanged (but it was incremented above)
      )             //     end of recursive call
  :                 // else:
    f(              //   this is a dead end; try again with one more digit in the prefix:
      s,            //     s unchanged
      p + s[x++]    //     increment x and append the next digit to p
    )               //   end of recursive call

54 bytes by implementing the changes to my code

Jelly,  15  9 bytes
Bugfix thanks to Dennis
ŻṚẆDfŒṖẈṀ

Try it online! (even 321 takes half a minute since the code is at least \$O(N^2)\$)
How?
ŻṚẆDfŒṖẈṀ - Link: integer, n
Ż         - [0..n]
 Ṛ        - reverse
  Ẇ       - all contiguous slices (of implicit range(n)) = [[n],...,[2],[1],[0],[n,n-1],...,[2,1],[1,0],...,[n,n-1,n-2,...,2,1,0]]
   D      - to decimal (vectorises)
     ŒṖ   - partitions of (implicit decimal digits of) n
    f     - filter discard from left if in right
       Ẉ  - length of each
        Ṁ - maximum

Perl 6, 43 41 40 bytes
-1 byte thanks to nwellnhof
{/(<-[0]>.*?|0)+<?{[==] 1..*Z+$0}>/;+$0}

Try it online!
Regex based solution. I'm trying to come up with a better way to match from a descending list instead, but Perl 6 doesn't do partitions well
Explanation:
{                                        }  # Anonymous code block
 /                                /;        # Match in the input
   <-[0]>.*?      # Non-greedy number not starting with 0
            |0    # Or 0
  (           )+  # Repeatedly for the rest of the number
                <?{             }>  # Where
                        1..*Z+$0       # Each matched number plus the ascending numbers
                                       # For example 1,2,3 Z+ 9,8,7 is 10,10,10
                   [==]                # Are all equal
                                    +$0  # Return the length of the list

40 bytes

Python 2, 78 74 73 bytes
l=lambda n,a=0,c=0,s="":c*(n==s)or a and l(n,a-1,c+1,s+`a-1`)or l(n,a-~c)

Try it online!
 -1 byte thanks to Arnauld
Takes input as a string. The program rather quickly runs into Python's recursion depth limit, but it can finish most of the test cases.
How it works
l=lambda n,                              # The input number, in the form of a string
         a=0,                            # The program will attempt to reconstruct n by
                                         #  building a string by pasting decreasing
                                         #  numbers, stored in a, after each other.
         c=0,                            # A counter of the amount of numbers
         s="":                           # The current constructed string
              c*(n==s)                   # Return the counter if s matches n
              or                         # Else
              a and l(n,a-1,c+1,s+`a-1`) # If a is not yet zero, paste a-1 after s
              or                         # Else
              l(n,a-~c)                  # Start again, from one higher than last time

Nice answer! a+c+1 can be shortened to a-~c.

Python 3, 232 228 187 181 180 150 149 bytes
-1 thanks to @Jonathan Frech
e=enumerate
t=int
h=lambda n,s=1:max([1]+[i-len(n[j:])and h(n[j:],s+1)or s+1for j,_ in e(n)for i,_ in e(n[:j],1)if(t(n[:j])-t(n[j:j+i])==1)*t(n[0])])

Try it online!
Initial ungolfed code:
def count_consecutives(left, right, so_far=1):
    for i,_ in enumerate(left, start=1):
        left_part_of_right, right_part_of_right = right[:i], right[i:]
        if (int(left) - int(left_part_of_right)) == 1:
            if i == len(right):
                return so_far + 1
            return count_consecutives(left_part_of_right, right_part_of_right, so_far + 1)
    return so_far

def how_many_consecutives(n):
    for i, _ in enumerate(n):
        left, right = n[:i], n[i:]
        for j, _ in enumerate(left, start=1):
            left_part_of_right = right[:j]
            if int(left) - int(left_part_of_right) == 1 and int(n[i]) > 0:
                return count_consecutives(left, right)
    return 1

s+1 for can be s+1for, (t(n[:j])-t(n[j:j+i])==1)*t(n[0]) can possibly be t(n[:j])-t(n[j:j+i])==1>=t(n[0]).

It seems that second suggestion doesn't work though it wouldn't bring anything because then you need space to separate expression from if.

True ... alternative 149.

05AB1E, 10 bytes
ÝRŒʒJQ}€gà

Extremely slow, so the TIO below only works for test cases below 750..
Try it online.
Explanation:
Ý           # Create a list in the range [0, (implicit) input]
            #  i.e. 109 → [0,1,2,...,107,108,109]
 R          # Reverse it
            #  i.e. [0,1,2,...,107,108,109] → [109,108,107,...,2,1,0]
  Œ         # Get all possible sublists of this list
            #  i.e. [109,108,107,...,2,1,0]
            #   → [[109],[109,108],[109,108,107],...,[2,1,0],[1],[1,0],[0]]
   ʒ  }     # Filter it by:
    J       #  Where the sublist joined together
            #   i.e. [10,9] → "109"
            #   i.e. [109,108,107] → "109108107"
     Q      #  Are equal to the (implicit) input
            #   i.e. 109 and "109" → 1 (truthy)
            #   i.e. 109 and "109108107" → 0 (falsey)
       €g   # After filtering, take the length of each remaining inner list
            #  i.e. [[109],[[10,9]] → [1,2]
         à  # And only leave the maximum length (which is output implicitly)
            #  i.e. [1,2] → 2

Code golf - where adding 1 byte to your program to go from n! to n lg n just isn't worth it.

Pyth, 16 bytes
lef!.EhM.+vMT./z

Try it online here, or verify all the test cases at once here.
lef!.EhM.+vMT./z   Implicit: z=input as string
             ./z   Get all divisions of z into disjoint substrings
  f                Filter the above, as T, keeping those where the following is truthy:
          vMT        Parse each substring as an int
        .+           Get difference between each pair
      hM             Increment each
   !.E               Are all elements 0? { NOT(ANY(...)) }
 e                 Take the last element of the filtered divisions
                     Divisions are generated with fewest substrings first, so last remaining division is also the longest
l                  Length of the above, implicit print

Jelly, 11 bytes
ŒṖḌ’Dɗ\ƑƇẈṀ

Byte for byte, no match for the other Jelly solution, but this one should be roughly \$O\left(n^{0.3}\right)\$.
Try it online!
How it works
ŒṖḌ’Dɗ\ƑƇẈṀ  Main link. Argument: n (integer)

ŒṖ           Yield all partitions of n's digit list in base 10.
        Ƈ    Comb; keep only partitions for which the link to the left returns 1.
       Ƒ       Fixed; yield 1 if calling the link to the left returns its argument.
      \          Cumulatively reduce the partition by the link to the left.
     ɗ             Combine the three links to the left into a dyadic chain.
  Ḍ                  Undecimal; convert a digit list into an integer.
   ’                 Decrement the result.
    D                Decimal; convert the integer back to a digit list.

Dyalog APL, 138 bytes
Bit of a mouthful, but it works fast for big numbers too. If you try it online, prefix the dfn by ⎕← and provide input on the right as a list of digits.
{⌈/⍵((≢⊂)×1∧.=2-/10⊥¨⊂)⍨⍤1⊢1,{⍬≡1↓⍵:↑⍬1⋄0=⊃⍵:0,∇1↓⍵⋄↑,0 1∘.,⊂⍤1∇1↓⍵}1↓⍵}

Explanation
First, the inner dfn on the right which recursively constructs a list of possible ways to partition (with ⊂) the list of digits. For example 1 0 1 0 ⊂ 2 0 1 9 returns the nested vector (2 0)(1 9).
{
   ⍬≡1↓⍵: ↑⍬1       ⍝ Edge case: If ⍵ is singleton list, return the column matrix (0 1)
   0=⊃⍵: 0,∇1↓⍵     ⍝ If head of ⍵ is 0, return 0 catenated to this dfn called on tail ⍵
   ↑,0 1∘.,⊂⍤1∇1↓⍵  ⍝ Finds 1 cat recursive call on tail ⍵ and 0 cat recursive call on ⍵.
}                    ⍝ Makes a matrix with a row for each possibility.

We use 1, to add a column of 1s at the start and end up with a matrix of valid partitions for ⍵.
Now the function train on the left in parens. Due to ⍨ the left argument to the train is the row of the partitions matrix and the right argument is the user input.
The train is a pile of forks with an atop as the far left tine.
((≢⊂)×1∧.=2-/10⊥¨⊂)⍨     ⍝ ⍨ swaps left and right arguments of the train.
                  ⊂       ⍝ Partition ⍵ according to ⍺.
             10⊥¨         ⍝ Decode each partition (turns strings of digits into numbers)
          2-/             ⍝ Difference between adjacent cells
      1∧.=                ⍝ All equal 1?
   ⊂                      ⍝ Partition ⍵ according to ⍺ again
  ≢                       ⍝ Number of cells (ie number of partitions)
     ×                    ⍝ Multiply.

If the partition creates a sequence of descending numbers, the train returns the length of the sequence. Otherwise zero.
⍤1⊢ applies the function train between the user input and each row of the partitions matrix, returning a value for each row of the matrix. ⊢ is necessary to disambiguate between operand to ⍤ and argument to the derived function of ⍤.
⌈/ finds the maximum.
Could find a shorter algorithm but I wanted to try this way which is the most direct and declarative I could think of.

Welcome to PPCG! This is an impressive first post!

Japt, 27 bytes
ò pÊÔpÊqÊfl²i1Uì q"l?"¹ÌèÊÉ

Try it online! or Check most test cases
This doesn't score well, but it uses a unique method and there might be room to golf it a lot more. It also performs well enough that all test cases other than 201200199198 avoid timing out.
Explanation:
ò                              #Get the range [0...input]
  pÊ                           #Add an "l" to the end
    Ô                          #Reverse it
     pÊ                        #Add an "l" to the end
       qÊ                      #Add an "l" between each number and turn to a string
         f            ¹        #Find the substrings that match this regex:
          l²                   # The string "ll"
            i1                 # With this inserted between the "l"s:
              Uì               #  All the digits of the input
                 q"l?"         #  With optional spaces between each one
                       Ì       #Get the last match
                        èÊ     #Count the number of "l"s
                          É    #Subtract 1

I think this works for 27.

25 bytes

@Shaggy both of those fail on input 21201 because they don't enforce that the sequence end aligns correctly (from my original version the "ends with a comma" line). This or this alternative works.

Ah, OK. In that case: 26 bytes

@Shaggy That and the 28 byte solutions I had fail on 210 because there isn't a delimiter after 0. Here's a fixed 28 byte that works.

Ah, I see you figured out a fix - nicely done.

Python 3, 302 282 271 bytes
-10 bytes thanks to the tip by @ElPedro.
Takes input as a string. Basically, it takes increasing larger slices of the number from the left, and sees if for that slice of the number a sequence can be formed using all the numbers.
R=range
I=int
L=len
def g(n,m,t=1):
 for i in R(1,L(m)+1):
  if I(m)==I(n[:i])+1:
   if i==L(n):return-~t
   return g(n[i:],n[:i],t+1)
 return 1
def f(n):
 for i in R(L(n)):
  x=n[:i]
  for j in R(1,L(x)+1):
   if (I(x)==I(n[i:i+j])+1)*I(n[i]):return g(n[i:],x)
 return 1

Try it online!

Since you are using range 3 times you can define R=range outside of both functions and then use R(whatever) instead of range(whatever) to save 4 bytes.

Charcoal, 26 bytes
Ｆ⊕ＬθＦ⊕Ｌθ⊞υ⭆κ⁻Ｉ…θιλＩ﹪⌕υθ⊕Ｌθ

Try it online! Link is to verbose version of code. Explanation:
Ｆ⊕Ｌθ

Loop i from 0 to the length of the input.
Ｆ⊕Ｌθ

Loop k from 0 to the length of the input.
⊞υ⭆κ⁻Ｉ…θ⊕ιλ

Calculate the first k numbers in the descending sequence starting from the number given by the first i digits of the input, concatenate them, and accumulate each resulting string in the predefined empty list.
Ｉ﹪⌕υθ⊕Ｌθ

Find the position of the first matching copy of the input and reduce it modulo 1 more than the length of the input.
Example: For an input of 2019 the following strings are generated:
 0
 1  0
 2  0-1
 3  0-1-2
 4  0-1-2-3
 5
 6  2
 7  21
 8  210
 9  210-1
10
11  20
12  2019
13  201918
14  20191817
15
16  201
17  201200
18  201200199
19  201200199198
20
21  2019
22  20192018
23  201920182017
24  2019201820172016

2019 is then found at index 12, which is reduced modulo 5 to give 2, the desired answer.

Haskell, 87 bytes
maximum.map length.(0#)
a#(b:c)=[a:x|c==[]||b>0,x<-b#c,a==x!!0+1]++(10*a+b)#c
a#b=[[a]]

Input is a list of digits.
Try it online!
Function # builds a list of all possible splits by looking at both

prepending the current number a to all splits returned by a recursive call with the rest of the input (x<-b#c), but only if the next number not zero (b>0) (or it's the last number in the input (c==[])) and a is one greater than the first number of the respective previous split x (a==x!!0+1).

and

appending the next digit b from the input list to the current number a and going on with the rest of the input ((10*a+b)#c)

Base case is when the input list is empty (i.e. does not pattern match (b:c)). The recursion starts with the current number a being 0 ((0#)), which never hits the first branch (prepending a to all previous splits), because it will never be greater than any number of the splits.
Take the length of each split and find the maximum (maximum.map length).
A variant with also 87 bytes:
fst.maximum.(0#)
a#(b:c)=[(r+1,a)|c==[]||b>0,(r,x)<-b#c,a==x+1]++(10*a+b)#c
a#b=[(1,a)]

which basically works the same way, but instead of keeping the whole split in a list, it only keeps a pair (r,x) of the length of the split r an the first number in the split x.

Haskell, 65 bytes
f i=[y|x<-[0..],y<-[1..length i],i==(show=<<[x+y-1,x+y-2..x])]!!0

Input is a string.
Try it online!
Completely different to my other answer. A simple brute force that tries all lists of consecutive descending numbers until it finds one that equals the input list.
If we limit the input number to 64-bit integers, we can save 6 bytes by looping y through [1..19], because the largest 64-bit integer has 19 digits and there's no need to test lists with more elements.
Haskell, 59 bytes
f i=[y|x<-[0..],y<-[1..19],i==(show=<<[x+y-1,x+y-2..x])]!!0

Try it online!

Python 2, 95 bytes
lambda n:max(j-i for j in range(n+1)for i in range(-1,j)if''.join(map(str,range(j,i,-1)))==`n`)

Another slow, brute-force solution.
Try it online!

TSQL, 169 bytes
Note: this can only be executed when the input can be converted to an integer.
Recursive sql used for looping.
Golfed:
DECLARE @ varchar(max) = '1211109876';

WITH C as(SELECT left(@,row_number()over(order by 1/0))+0t,@+null z,0i
FROM spt_values UNION ALL
SELECT t-1,concat(z,t),i+1FROM C WHERE i<9)SELECT
max(i)FROM C WHERE z=@

Ungolfed:
DECLARE @ varchar(max) = '1211109876';

WITH C as
(
  SELECT
    left(@,row_number()over(order by 1/0))+0t,
    @+null z,
    0i
  FROM
    spt_values
  UNION ALL
  SELECT
    t-1,
    concat(z,t),
    i+1
  FROM C
  WHERE i<9
)
SELECT max(i)
FROM C
WHERE z=@

Try it out

R, 101 bytes
function(a,N=nchar(a)){for(x in 1:N)F=max(F,which(Reduce(paste0,seq(substr(a,1,x),,-1,N),a=T)==a));F}

Try it online!
More than 2 weeks have passed without any R answer, so I decided to post my own :)
The code is pretty fast since it uses a "limited" brute force approach
Unrolled code and explanation :
function(a){                  # get string a as input (e.g. "2019")

  N = nchar(a)                # set N = length of a (e.g. 4)
  Y = 0                       # initialize Y = 0 (in the actual code we abuse F)

  for(x in 1:N){              # for x in 1 ... N

    S = substr(a,1,x)         # get the first x characters of a (e.g. "20" for x=2)

    Q = seq(S,,-1,N)          # create a decreasing sequence (step = -1)
                              # of length N starting from S converted into integer
                              # (e.g. Q = c(20,19,18,17) for x=2)

    R = Reduce(paste0,Q,a=T)  # concatenate all the increasing sub-sequences of Q
                              # (e.g. R = c("20","2019","201918","20191817") for x=2)

    I = which(R == a)         # Get the index where R == a, if none return empty vector
                              # (e.g. I = 2 for x=2)

    Y = max(Y,I)              # store the maximum index found into Y
  }
  return(Y)                   # return Y
}


text:
Write a function/method that takes in a string and spells that word out using the NATO Phonetic Alphabet. Titlecase optional
Write a program that takes in a string and spells that word out using the NATO Phonetic Alphabet.
The mapping is as follows:
'A' -> 'Alfa'
'B' -> 'Bravo'
'C' -> 'Charlie'
'D' -> 'Delta'
'E' -> 'Echo'
'F' -> 'Foxtrot'
'G' -> 'Golf'
'H' -> 'Hotel'
'I' -> 'India'
'J' -> 'Juliett'
'K' -> 'Kilo'
'L' -> 'Lima'
'M' -> 'Mike'
'N' -> 'November'
'O' -> 'Oscar'
'P' -> 'Papa'
'Q' -> 'Quebec'
'R' -> 'Romeo'
'S' -> 'Sierra'
'T' -> 'Tango'
'U' -> 'Uniform'
'V' -> 'Victor'
'W' -> 'Whiskey'
'X' -> 'Xray'
'Y' -> 'Yankee'
'Z' -> 'Zulu'

Example:
'Hello World' -> ['Hotel', 'Echo', 'Lima', 'Lima', 'Oscar', 'Whiskey', 'Oscar', 'Romeo', 'Lima', 'Delta']
The input can be any string, but will always be comprised of only letters and spaces. Case is irrelevant in the output, but the input may contain letters in uppercase, lowercase, or both. Spaces should be ignored in the output.
You can output in any reasonable format, but it must be a delimited set of NATO callsigns.

Welcome to PPCG! This question has already been asked. But it probably would have been closed anyway for several other reasons: 1) Unless there's a good reason to do so, asking to answer in a specific way (a function) in a specific language is usually frowned upon. 2) Challenges must be self-contained: you should explain what the NATO phonetic alphabet exactly is within the body of the question. 3) In its current form, it looks like a homework assignment. If it is, you might find help on Stack Overflow, provided that you include what you've done so far and explain where you're stuck.

I'd be in favour of reopening this if the points @Arnauld raised above were addressed as it doesn't have the source restriction or input validation of the linked challenge.

@JoKing, from the test case, which includes a space, it looks like they're simply stripped.

I've edited this to possibly be re-openable, since it doesn't have the restriction on characters. Are all my changes appropriate? Especially check the input restrictions.

@Riker, personally, I'd say ditch the - in X-ray and require the output be in title case.

I agree with @Shaggy about ditching the - in X-ray. Whether the output must be titlecase or not I personally don't mind either.

@Shaggy I'll leave that up to OP. I had the - in since I copied that from a list of NATO callsigns and I haven't voted to reopen yet. OP can decide the rest.

This is the ICAO alphabet; the NATO alphabet uses Alpha and Juliet instead.

Can we optionally have the - in X-ray?

Whisky in the example is not equals to Whiskey in the mapping.

sfk, 78 59 57 bytes
+filt
+spell -nato
+xed _ph_f_ _et_ett_ _-__ "*: [keep]""

Try it online!
Just use the right tool.
Output is the phonetics separated by one or more spaces.

x86-16 machine code, IBM PC DOS, 192 bytes
be80 00ad 8ac8 ac51 24df 8ad0 2c40 3c1b 7321 8af0 b024 b18b 9090 bf37 01f2 aefe
ce75 fab4 02cd 218b d7b4 09cd 21b2 20b4 02cd 2159 e2d0 c324 6c66 6124 7261 766f
2468 6172 6c69 6524 656c 7461 2463 686f 246f 7874 726f 7424 6f6c 6624 6f74 656c
246e 6469 6124 756c 6965 7474 2469 6c6f 2469 6d61 2469 6b65 246f 7665 6d62 6572
2473 6361 7224 6170 6124 7565 6265 6324 6f6d 656f 2469 6572 7261 2461 6e67 6f24
6e69 666f 726d 2469 6374 6f72 2468 6973 6b65 7924 7261 7924 616e 6b65 6524 756c
7524

    MOV  SI, 80H            ; point SI to DOS PSP
    LODSW                   ; load arg length into AL, advance SI to 82H
    MOV  CL, AL             ; set up loop counter
SEARCH:
    LODSB                   ; load next char from DS:SI into AL, advance SI
    PUSH CX                 ; save outer loop position
    AND  AL, 0DFH           ; uppercase the input letter
    MOV  DL, AL             ; save for output
    SUB  AL, 'A'-1          ; convert letter to one-based index (A=1, Z=26, etc)
    CMP  AL, 27             ; if greater than 26, not a valid char
    JNC  NOTFOUND           ; if not, move to next
    MOV  DH, AL             ; DH is loop counter
    MOV  AL, '$'            ; search for string delimiter
    MOV  CL, LNATO          ; repeat search through length of word data
    MOV  DI, OFFSET NATO    ; re-point SCASB to beginning of word data
SCANLOOP:
    REPNZ SCASB             ; search until delimiter in AL is found ES:DI, advance DI
    DEC  DH                 ; delimiter found, decrement counter
    JNZ  SCANLOOP           ; if counter reached 0, index has been found
    MOV  AH, 02H            ; display first char
    INT  21H
    MOV  DX, DI             ; put found string memory location to DX for display
    MOV  AH, 09H            ; display string function
    INT  21H
    MOV  DL, ' '            ; display a space between words
    MOV  AH, 02H
    INT  21H
NOTFOUND:
    POP  CX                 ; restore outer loop counter
    LOOP SEARCH             ; move to next char in input
    RET
NATO    DB  '$lfa$ravo$harlie$elta$cho$oxtrot$olf$otel$ndia$'
        DB  'uliett$ilo$ima$ike$ovember$scar$apa$uebec$omeo$'
        DB  'ierra$ango$niform$ictor$hiskey$ray$ankee$ulu$'
LNATO   EQU $-NATO

Test output:
A>NATO abc aaa
Alfa Bravo Charlie Alfa Alfa Alfa
A>NATO abc DefG1HIJ
Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett
A>NATO Alfa Bravo!
Alfa Lima Foxtrot Alfa Bravo Romeo Alfa Victor Oscar

You can save 2 bytes by figuring out how to turn off the NOP padding, or using a different version that doesn't do it. I used ML.EXE and it does not do the padding. You can save another 18 bytes or so by removing the $ delimiters and separating the words by capitalizing their first letter instead (and by first I mean second, because you already left out the first). (A higher level of compression could probably be reached before the length of code needed to decompress it would outweigh the advantage of the compression, but the simple scheme of capital-letter-delimiters would be a good start.)

Using MASM 5, I've tried all variations of ALIGN and EVEN, and moving instructions around and no matter what it really likes to pad before the REPNZ.  The $ delimiter was a cheap way to have both an array delimited and a string delimiter so I could use INT 21H:09 and not have to write a loop structure to print it char by char.  I like your idea about using capitals as delimiters, something like 'LfaRavoHarlie' , yes? Per the spec, case is irrelevant so outputting ALfa or CHarlie would be perfectly acceptable. Great ideas! Will need to code it up and see what the size diff end up being.

Apparently MASM 9 was the last version that had an /AT option (for .MODEL TINY), and in my test with your code it did not do the NOP padding. The ML.EXE /? output says Microsoft (R) Macro Assembler Version 9.00.30729.01. Yep, 'LfaRavoHarlie' is exactly what I meant. :) I would do the "OR AL, 20H" to make it lowercase again in the output, but it's up to you.

BTW, why not include the header and footer in your unassembled view? MASM 9 wouldn't compile it for me without that. I mean the .MODEL TINY .CODE ORG 100H START: at the beginning and END START at the end. Did you not need this to compile it with MASM 5?

I don't typically include the MASM boilerplate because it's not part of the assembled code (you can get to the same byte code multiple ways depending on your version of MASM and all). I use the "old" syntax because I like to test it on MASM 1.1. :)  I believe I've found the NOP issue and it's likely a MASM bug that existed at least between 1.1 and 5. If you place the LNATO EQU above the code or hard code 08BH in place, it does not insert the two NOPs. However since the LNATO EQU is below the code, there's a difference in what it does between pass1 and pass2, leaving that space there. Bizarre!

Let us continue this discussion in chat.

05AB1E, 102 96 95 bytes
álSA”AlfaÐ†vo¼¯¤œ®È¨›trotŠˆƒ‹Š™ÈŸtt Kilo´àma—……ÍÐ—Žêpa¼°«Äoµ†Çâgo¸šÉµ Whiskey Xrayµ‹nkeeâ¸lu”#‡

Output is a list of Titlecased NATO words.
Try it online.
Explanation:
á              # Only leave the letters of the (implicit) input
 l             # Convert it to lowercase
  S            # Split it to a list of characters
   A           # Push the alphabet
    ”...”      # Push all the NATO words in titlecase and space-delimited
         #     # Split the string by spaces
          ‡    # Transliterate; map all letters in the lowercase input with this
               # list at the same indices (and output the resulting list implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why ”AlfaÐ†vo¼¯¤œ®È¨›trotŠˆƒ‹Š™ÈŸtt Kilo´àma—……ÍÐ—Žêpa¼°«Äoµ†Çâgo¸šÉµ Whiskey Xrayµ‹nkeeâ¸lu” is "Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett Kilo Lima Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform Victor Whiskey Xray Yankee Zulu". Credit of this compressed dictionary string goes to @ErikTheGolfer in this comment (with an added t for Juliett instead of Juliet).

May be able to use interpolation, and compression to lower the byte-count of the non-existant words (trot, tt Kilo, Whiskey Xray). Halfassed example: Try it online! I've done it before, but it was for a LARGE amount of words, in this it'd save at best 1 byte if you spent time.

Jelly,  80  77 bytes
ḟ⁶O%32ị“¡µQỤ(cɠṘwlṁ;Ɗœ<NẸ½ṗN¬ṙẋxḶb¤*O~Æƒ¹.ß8Ḋ¡tJ|Ḷ<İİḂ^1eȷjċbY9TYƭ¹Ẉ¥¤K0¹f»Ḳ¤

Try it online! (The footer formats the list by joining with spaces to avoid implicit smashing print when run as a full program)

JavaScript (ES6), 181 189 bytes
s=>s.match(/\w/g).map(c=>'IndiAlfABravOscaRomeOQuebeCharliEchODeltAGolFoxtroTangOHoteLimAJulietTKilOZulUniforMikENovembeRPapASierrAVictoRWhiskeYankeEXraY'.match(c.toUpperCase()+'.*?[A-Z]'))

Since output case doesn't matter, we can save bytes by running words together:
... GolFoxtroTangO ...

Try it online!

C# (Visual C# Interactive Compiler), 218 bytes
n=>n.ToUpper().Select(x=>"AlfaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJuliettKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu".SkipWhile(k=>x!=k).TakeWhile((k,l)=>l<1|k>96&k<123))

Try it online!
Alternate version using Split(), 194 bytes
n=>n.ToUpper().Select(x=>x>64?x+"lfa,ravo,harlie,elta,cho,oxtrot,olf,otel,ndia,uliett,ilo,ima,ike,ovember,scar,apa,uebec,omeo,ierra,ango,niform,ictor,hiskey,ray,ankee,ulu".Split(',')[x%65]:x+"")

Try it online!

Perl 6, 176 170 166 bytes
*.comb>>.&{$_~:128[q`>$RbD[Orlo~Q1nX,OVq8x9'6%h'1.I$83ua7	vsD=s-{W}{>iQ:Js37py)hNN,i{Pt\~#f4<>`.ords].base(35).split('J')[.ord%32]}.words

Try it online!
Outputs in uppercases with the first letter in the original case. Compresses the string, which only saves 6 bytes over the simpler plain text:
*.comb>>.&{$_~ <lfa ravo harlie elta cho oxtrot olf otel ndia uliett ilo ima ike ovember scar apa uebec omeo ierra ango niform ictor hiskey ray ankee ulu>[.ord%32-1]if ' 'ne$_}

Try it online!
Explanation:
*.comb>>.&{                 }         # Map each letter to
           $_~                        # The letter plus
              <...>[.ord%32]          # The letter indexed into the list of words
                             .words   # And remove the extra spaces

Python 3, 250 191 bytes
-47 bytes thanks to @Jo King, -2 more thanks to @Jonathan Allen
It goes through all non-space characters of the input, and for each of them it selects the relevant phrase for the letter, which can be reduced a bit because the first letter of each phrase is the character itself. Splits a string instead of storing the phrases as an array to save bytes from the unnecessary 's and ,s.
lambda s:[c+"lfa ravo harlie elta cho oxtrot olf otel ndia uliett ilo ima ike ovember scar apa uebec omeo ierra ango niform ictor hiskey ray ankee ulu".split()[ord(c)%32-1]for c in s if' '<c]

Try it online!
Original solution
lambda s:[c+['lfa','ravo','harlie','elta','cho','oxtrot','olf','otel','ndia','uliett','ilo','ima','ike','ovember','scar','apa','uebec','omeo','ierra','ango','niform','ictor','hiskey','ray','ankee','ulu'][ord(c)-65]for c in s.replace(" ", "").upper()]

Try it online!

191 with if' '<c

Red, 210 193 bytes
func[s][foreach c trim/all s[prin c print pick[:lfa:ravo:harlie:elta:cho:oxtrot:olf:otel:ndia:uliett:ilo:ima:ike:ovember:scar:apa:uebec:omeo:ierra:ango:niform:ictor:hiskey:ray:ankee:ulu]c% 32]]

Try it online!
Explanation:
foreach iterates over the string after all whitespaces are removed by trim/all. prin prints the character (no newline). print prints a symbol, picked from the list of get-word!s (symbols) using the character mapped to the range 1..26 as an index.

Charcoal, 99 bytes
ＥΦ↥Ｓ№αι⁺ι§⪪”&⌊%w⁸D⦃σν:…ⅈ$|@Ｈ¦χＴ⸿]ECrΣＭ^¿←←&⁵↘⁼s(ＪＦ8X´▷⧴⎚Ｐ0V÷AＷχπ¶⌈≧\"dＪ^ZU{M≔⁴｜<¶⁹Ｂ⊞⊟1ＬPH⪪∨Y3`”j⌕αι

Try it online! Link is to verbose version of code. Outputs in proper case. Explanation:
   Ｓ                    Input string
  ↥                     Uppercased
 Φ                      Filtered where
     α                  Predefined uppercase alphabet
    №                   Contains
      ι                 Current character
Ｅ                       Mapped over characters
        ι               Current character
       ⁺                Concatenated with
           ”...”        Compressed string
          ⪪             Split on
                j       Literal string `j`
         §              Indexed by
                 ⌕      Index of
                   ι    Current character
                  α     In uppercase alphabet
                        Implicitly print each word on its own line

Clean, 218 bytes
import StdEnv
$s=[takeWhile((<=)c)(dropWhile((<)c)['ZuluYankeeXrayWhiskeyVictorUniformTangoSierraRomeoQuebecPapaOscarNovemberMikeLimaKiloJuliettIndiaHotelGolfFoxtrotEchoDeltaCharlieBravoAlfa'])\\c<-map toUpper s|c>' ']

Try it online!

IBM PC DOS 8088 machine language, 165 bytes
This is directly based on gwaugh's answer, but I shaved off 26 bytes by omitting the $ delimiters from the "NATO" word table and an extra 1 byte by not skipping the first character of the command-line parameter string (which will always be either / or   and thus will be ignored by the program anyway). The program ended up being exactly the same length to be able to process the table in this format (in which the words are delimited only by uppercase characters, which serve the double purpose of also being the second letter of each word), or 2 bytes longer if the output capitalization is kept the same as before. The table is 26 bytes smaller.
In the following program dump, concatenation by : is used to show each sequence of consecutive bytes corresponding to an instruction:
0000  BE:80:00 AC 91 AC 24:DF 8A:D0 2C:40 3C:1A 77:21  ······$···,@<·w!
0010  8A:F0 B4:02 CD:21 56 BE:34:01 AC A8:20 75:FB FE: ·····!V·4··· u··
0020 :CE 75:F7 8A:D0 CD:21 AC A8:20 75:F7 B2:20 CD:21  ·u····!·· u·· ·!
0030  5E E2:D2 C3 4C 66 61 52 61 76 6F 48 61 72 6C 69  ^···LfaRavoHarli
0040  65 45 6C 74 61 43 68 6F 4F 78 74 72 6F 74 4F 6C  eEltaChoOxtrotOl
0050  66 4F 74 65 6C 4E 64 69 61 55 6C 69 65 74 74 49  fOtelNdiaUliettI
0060  6C 6F 49 6D 61 49 6B 65 4F 76 65 6D 62 65 72 53  loImaIkeOvemberS
0070  63 61 72 41 70 61 55 65 62 65 63 4F 6D 65 6F 49  carApaUebecOmeoI
0080  65 72 72 61 41 6E 67 6F 4E 69 66 6F 72 6D 49 63  erraAngoNiformIc
0090  74 6F 72 48 69 73 6B 65 79 52 61 79 41 6E 6B 65  torHiskeyRayAnke
00A0  65 55 6C 75 40                                   eUlu@

Download the DOS NATO.COM executable:
With uncorrected capitalization (165 bytes)
With clean capitalization (167 bytes)
Bonus version that capitalizes the first letter of each word the same as the input (167 bytes)
Unassembled:
    .MODEL TINY            ; .COM program, maximum addressing space 65536 bytes
    .CODE
    ORG 100h
start:
    MOV  SI, 80h           ; Point SI to DOS PSP (Program Segment Prefix).
    LODSB                  ; Load command-line parameter (input string) length
                           ; into AL; assume AX=0 before this, which is true
                           ; in most versions of DOS; advance SI to first char
                           ; of parameter, which is either '/' or ' '.
    XCHG CX, AX            ; Set up loop counter with length of input string.
search:
    LODSB                  ; Load next character from [SI] into AL; advance SI.
    AND  AL, NOT ('A' XOR 'a')  ; Make this character uppercase.
    MOV  DL, AL            ; Save character for output. Move this before the
                           ; AND instruction to capitalize the first letter of
                           ; each word identically to how it is in the input.
    SUB  AL, 'A'-1         ; convert letter to one-based index (A=1, Z=26, etc)
    CMP  AL, 'Z'-'A'+1     ; Is this an alphabetical character?
    JA   notFound          ; If not, move to next character.
    MOV  DH, AL            ; Set up DH as our word-finding loop counter.
    MOV  AH, 02h           ; AH=02h, INT 21h: Write character to STDOUT
    INT  21h               ; Display first character of this NATO word.
    PUSH SI                ; Save our current position in the input string.
    MOV  SI, OFFSET table  ; Point LODSB to beginning of word data.
scanLoop:                  ; Find the word in the table corresponding to our
                           ; current character.
    LODSB                  ; Load next character from [SI] into AL; advance SI.
    TEST AL, 'A' XOR 'a'   ; Is this character uppercase?
    JNZ  scanLoop          ; If not, move to next character.
    DEC  DH                ; Delimiter (uppercase) found; decrement counter.
    JNZ  scanLoop          ; Keep looping until counter reaches 0.
    OR   AL, 'A' XOR 'a'   ; Make this character lowercase. This is not
                           ; required by the challenge's specification, and
                           ; this instruction can be removed.
wordLoop:
    MOV  DL, AL            ; Display next character from NATO word.
    INT  21h               ; (We still have AH=02h from before.)
    LODSB
    TEST AL, 'A' XOR 'a'   ; Is this character lowercase?
    JNZ  wordLoop          ; If so, continue the loop.
    MOV  DL, ' '           ; Display a space between words.
    INT  21h               ; (We still have AH=02h from before.)
    POP  SI                ; Restore our current position in the input string.
notFound:
    LOOP search            ; Move to next character in input string.
    RET
table   DB  'LfaRavoHarlieEltaChoOxtrotOlfOtelNdia'
        DB  'UliettIloImaIkeOvemberScarApaUebecOmeo'
        DB  'IerraAngoNiformIctorHiskeyRayAnkeeUlu'
        DB  '@'            ; Terminate the list to make sure that uninitialized
                           ; memory doesn't cause a problem.
    END start

Sample input:
>NATO The quick brown fox jumped over the lazy dog.
>NATO Jackdaws love my big sphinx of quartz.

Output (165 byte version):
TAngo hOtel eCho qUebec uNiform iNdia cHarlie kIlo bRavo rOmeo oScar wHiskey nOvember fOxtrot oScar xRay jUliett uNiform mIke pApa eCho dElta oScar vIctor eCho rOmeo tAngo hOtel eCho lIma aLfa zUlu yAnkee dElta oScar gOlf
JUliett aLfa cHarlie kIlo dElta aLfa wHiskey sIerra lIma oScar vIctor eCho mIke yAnkee bRavo iNdia gOlf sIerra pApa hOtel iNdia nOvember xRay oScar fOxtrot qUebec uNiform aLfa rOmeo tAngo zUlu

Clean-capitalization version (167 bytes):
Tango Hotel Echo Quebec Uniform India Charlie Kilo Bravo Romeo Oscar Whiskey November Foxtrot Oscar Xray Juliett Uniform Mike Papa Echo Delta Oscar Victor Echo Romeo Tango Hotel Echo Lima Alfa Zulu Yankee Delta Oscar Golf
Juliett Alfa Charlie Kilo Delta Alfa Whiskey Sierra Lima Oscar Victor Echo Mike Yankee Bravo India Golf Sierra Papa Hotel India November Xray Oscar Foxtrot Quebec Uniform Alfa Romeo Tango Zulu

Clean-capitalization version with same capitalization as input (167 bytes):
Tango hotel echo quebec uniform india charlie kilo bravo romeo oscar whiskey november foxtrot oscar xray juliett uniform mike papa echo delta oscar victor echo romeo tango hotel echo lima alfa zulu yankee delta oscar golf
Juliett alfa charlie kilo delta alfa whiskey sierra lima oscar victor echo mike yankee bravo india golf sierra papa hotel india november xray oscar foxtrot quebec uniform alfa romeo tango zulu

Nice work there!

C++, 229 228 bytes
[](auto s){for(;auto t=*s?"LfaRavoHarlieEltaChoOxtrotOlfOtelNdiaUliettIloImaIkeOvemberScarApaUebecOmeoIerraAngoNiformIctorHiskeyRayAnkeeUlu":0;s++)if(int c=*s&31){for(cout<<*s;*t>96||--c;t++);for(;cout<<*t,*++t>96;);cout<<' ';}}

Try it online!
Ungolfed:
[](const char *s)
{
    const char *table = "LfaRavoHarlieEltaChoOxtrotOlfOtelNdiaUliettIloImaIkeOvemberScarApaUebecOmeoIerraAngoNiformIctorHiskeyRayAnkeeUlu";
    for (; *s; s++)
    {
        char c = *s & 0x1F;
        if (c != 0)
        {
            cout << *s;
            const char *w = table;
            while (*w >= 'a' || --c)
                w++;
            do
                cout << *w;
            while (*++w >= 'a');
            cout << ' ';
        }
    }
}

Output:
TAngo hOtel eCho qUebec uNiform iNdia cHarlie kIlo bRavo rOmeo oScar wHiskey nOvember fOxtrot oScar xRay jUliett uNiform mIke pApa eCho dElta oScar vIctor eCho rOmeo tAngo hOtel eCho lIma aLfa zUlu yAnkee dElta oScar gOlf
JUliett aLfa cHarlie kIlo dElta aLfa wHiskey sIerra lIma oScar vIctor eCho mIke yAnkee bRavo iNdia gOlf sIerra pApa hOtel iNdia nOvember xRay oScar fOxtrot qUebec uNiform aLfa rOmeo tAngo zUlu

Clean-capitalization version (234 bytes):
[](auto s){for(;auto t=*s?"LfaRavoHarlieEltaChoOxtrotOlfOtelNdiaUliettIloImaIkeOvemberScarApaUebecOmeoIerraAngoNiformIctorHiskeyRayAnkeeUlu":0;s++)if(int c=*s&31){for(cout<<*s;*t>96||--c;t++);for(;putchar(*t|32),*++t>96;);cout<<' ';}}

Try it online!
Output:
Tango hotel echo quebec uniform india charlie kilo bravo romeo oscar whiskey november foxtrot oscar xray juliett uniform mike papa echo delta oscar victor echo romeo tango hotel echo lima alfa zulu yankee delta oscar golf
Juliett alfa charlie kilo delta alfa whiskey sierra lima oscar victor echo mike yankee bravo india golf sierra papa hotel india november xray oscar foxtrot quebec uniform alfa romeo tango zulu

Japt, 108 106 bytes
¸®¬Ë+u cg`ovem¼rws¯r°pawue¼cÙ o±ØÇ¯fmØtØkeyÙ°nkeewªuwlfaæ1ÃÉr¦e³ltawÖoxÉwolfÙ*lÙAawªieâ-¹µ±ke`qw

Try it
The backticks contains the compressed string:
ovemberwscarwapawuebecwomeowierrawangowniformwictorwhiskeywraywankeewuluwlfawravowharlieweltawchowoxtrotwolfwotelwndiawuliettwilowimawike

PowerShell, 187 183 bytes
$args|% t*y|%{'AlfaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJuliettKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu'-csplit'(?=[A-Z])'-like"$_*"}

Try it online!
Test script:
$f = {
$args|% t*y|%{'AlfaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJuliettKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu'-csplit'(?=[A-Z])'-like"$_*"}
}

@(
    ,('Hello World', 'Hotel', 'Echo', 'Lima', 'Lima', 'Oscar', 'Whiskey', 'Oscar', 'Romeo', 'Lima', 'Delta')
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$result"-eq"$expected"
    "$result"
}

Output:
True
Hotel Echo Lima Lima Oscar Whiskey Oscar Romeo Lima Delta

PHP, 209 205 206 bytes
while($l=$argv[1][$x++])echo$l!=' '?$l.preg_split('/([A-Z][a-z]*)/',ALfaRavoHarlieEltaChoOxtrotOlfOtelNdiaUliettIloImaIkeOvemberScarApaUebecOmeoIerraAngoNiformIctorHiskeyRayAnkeeUlu,0,3)[31&ord($l)].' ':'';

Try it online!
Output:
"Hello World" => "HOtel eCho lIma lIma oScar WHiskey oScar rOmeo lIma dElta"

Or 195 bytes, with spaces not fully removed:
while($l=$argv[1][$x++])echo$l,preg_split('/([A-Z][a-z]*)/',ALfaRavoHarlieEltaChoOxtrotOlfOtelNdiaUliettIloImaIkeOvemberScarApaUebecOmeoIerraAngoNiformIctorHiskeyRayAnkeeUlu,0,3)[31&ord($l)].' ';

Try it online!
Output:
"Hello World" => "HOtel eCho lIma lIma oScar   WHiskey oScar rOmeo lIma dElta"

Nice, but your latest edit introduced an off-by-one error. One way to fix it is to change [31&ord($l)] back to [31&ord($l)-1], costing two bytes, but you can also fix it in just one byte by fully spelling out ALfa.

Whoops! Good catch and very clever fix. Thx @deadcode!

JavaScript, 179 bytes
s=>s.match(/\w/g).map(c=>c+'LfaRavoHarlieEltaChoOxtrotOlfOtelNdiaUliettIloImaIkeOvemberScarApaUebecOmeoIerraAngoNiformIctorHiskeyRayAnkeeUlu'.match(/.[a-z]+/g)[parseInt(c,36)-10])

Try it online!

TSQL, 313 bytes
Golfed:
DECLARE @ varchar(max)='Hello World'

DECLARE @x INT=len(@)WHILE @x>0SELECT @=stuff(@,@x,1,substring(@,@x,1)+choose(ascii(substring(@,@x,1))%32,'lfa','eta','harlie','elta','cho','oxtrot','olf','otel','ndia','uliett','ilo','ima','ike','ovember','scar','apa','uebec','omeo','ierra','ango','niform','ictor','hiskey','ray','ankee','ulu')+';'),@x-=1PRINT @

Ungolfed:
DECLARE @ varchar(max)='Hello World'

DECLARE @x INT=len(@)
WHILE @x>0
  SELECT @=stuff(@,@x,1,substring(@,@x,1)+choose(ascii(substring(@,@x,1))%32,
    'lfa','eta','harlie','elta','cho','oxtrot','olf','otel','ndia','uliett','ilo',
    'ima','ike','ovember','scar','apa','uebec','omeo','ierra','ango','niform',
    'ictor','hiskey','ray','ankee','ulu')+';'),
    @x-=1

PRINT @

Try it out
Output ends with semicolon

PHP, 212 bytes
while($c=ord($argn[$i++]))echo[_,Alpha,Bravo,Charlie,Delta,"Echo",Foxtrot,Golf,Hotel,India,Juliett,Kilo,Lima,Mike,November,Oscar,Papa,Quebec,Romeo,Sierra,Tango,Uniform,Victor,Whiskey,Xray,Yankee,Zulu][$c&31]," ";

Run as pipe with -nR or try it online.
Yields warnings in PHP 7.2; put array elements in quotes to fix.
Will print an underscore for spaces.

PowerShell, 228 225 bytes
-3 bytes thanks to @mazzy
"$args".ToLower()-replace' '|% T*y|%{$a+=$_+((-split"lfa ravo harlie elta cho oxtrot olf otel ndia uliett ilo ima ike ovember scar apa uebec omeo ierra ango niform ictor hiskey ray ankee ulu")[('a'..'z').IndexOf($_)])+' '};$a

Try it online!
This is quite possibly the ugliest piece of code I have ever written. In addition, this can certainly get a lot shorter. In my defense, I'm still recovering from final exams.

-split'lfa ravo ...' is shorter because '\s' is splitter by default :)

C (clang), 309 283 bytes
-26 bytes thanks to @ceilingcat
*k[]={"lfa","ravo","harlie","elta","cho","oxtrot","olf","otel","ndia","uliett","ilo","ima","ike","ovember","scar","apa","uebec","omeo","ierra","ango","niform","ictor","hiskey","ray","ankee","ulu"};i;main(z,v)char**v;{for(;z=toupper(v[1][i]);i++)z>64&z<92&&printf("%c%s ",z,k[z-65]);}

Try it online!

source: Stack Exchange

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

sort: votes


text:
Pattern Finder - Find Repeated Pattern in String
Introduction
This is a little challenge with the goal of identifying repeated pattern "blocks" in a string, and outputting them with their frequency of occurence from left to right.
A friend asked me this question and I realized it wasn't as simple as tossing what you've seen into a hash table and popping them off if previously seen.
Example Input and Output
Input:

"TTBBPPPBPBPBPBBBBPBPBPBB"

The idea:

T T | B B | P P P | BP BP BP | B B B B | PB PB PB | B

Output:

2T, 2B, 3P, 3BP, 4B, 3PB, B

However any output format that shows the number of repetitions, and respective repeated substrings, are allowed.
Is it possible to do this with reasonable time complexity?
I'm curious as to the standard, legible approach to this kind of question, but as this is code golf - shortest code wins!
Cheers!

Welcome to PPCG!. This seems a good challenge though you need to specify what is the winning criteria.

Thanks @LuisfelipeDejesusMunoz ! I've set the criteria to be shortest code wins! But I'm hoping to also see understandable code, as I'm trying to learn from this experience myself :)

@R.Gosman Welcome to PPCG, where people abuse code to the fullest extent to golf it! Seriously though, please don't consider PPCG as an example of good practices. :P Also, is this challenge restricted to Python?

What if several outputs are possible? For instance, what is the expected result for "ABABCABCBC"?

...also what about AAABBBAAABBB is it [A3, B3, A3, B3], [AAABBB2], or [[A3, B3]2]?

As defined, the easiest way to implement this is to just output the number of repetitions of each character. Is the goal to minimize the number of separate blocks?

I've voted to close as unclear, but I think this is a good challenge! As you're new here, you probably haven't heard of The Sandbox, but it's pretty useful for refining challenges to fit our expectations, and for preventing the comments section from blowing up.

Must the number appear at the beginning of each string in the output or can it come at the end? How should we handle inputs that contain digits? (E.G., should 22 output 22?)

Welcome to PPCG. My suggestion would be that you move this question to the sandbox as suggested by @Giuseppe and temporarily delete it from the main site. There you will be able to get help from other community members on how to make your question into a good challenge and then repost it when you think it is ready. Have fun here anyway.

Potential duplicate of Detecting loops in in in strings

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


text:
Multi-level marketing "legs" investment rule
Multi-level marketing related challenge.
A peer wants to get rewarded. So it attracted N investors (N>=1), each i-th investor invested x[i]. When a total sum exceeds threshold x[0]+x[1]+...+x[N-1] >= T a peer could be rewarded. But only if a following conditions are satisfied:

Minimum amount of investors should be greater than M, (M<=N)
For at least one integer k, where k>=M and k<=N, any k investors have to invest at least T/k each;

Given N, x[], T, M you should determine whether the peer's reward is generated or not (boolean result, "yes" or "no"). Shortest code wins.
Examples:

N=5; M=3; T=10000, in order to generate the peer's reward one of the following must be satisfied:

any 3 invested at least 3334 each
any 4 invested at least 2500 each
all 5 invested at least 2000 each

N=6; M=2; T=5000:

any 2 invested at least 2500 each
any 3 invested at least 1667 each
any 4 invested at least 1250 each
any 5 invested at least 1000 each
all 6 invested at least 834 each

generalized: for any k, where k>=M and k<=N:

any k of N investors invested at least T/k each

Test cases:
format:
N, x[], T, M -> correct answer
6, [999, 999, 59, 0, 0, 0], 180, 3 -> 0
6, [0, 60, 0, 60, 60, 0], 180, 3 -> 1
6, [179, 89, 59, 44, 35, 29], 180, 3 -> 0
6, [179, 89, 59, 44, 35, 30], 180, 3 -> 1
6, [179, 89, 59, 44, 36, 29], 180, 3 -> 1
6, [179, 90, 59, 44, 35, 29], 180, 3 -> 0
6, [30, 30, 30, 30, 29, 30], 180, 3 -> 0
6, [30, 30, 30, 30, 30, 30], 180, 3 -> 1

N is implied by len(x), I suppose we can but do not have to take it as an input, right?

@JonathanAllan Sure, if your language allows it, and writing len(x) will be shorter than writing N. That is made, because for dynamically allocated array x in C there is no direct len(x) function - so you may always refer to length as N. For convenience, you may consider all input data N, x[], T, M as some externally defined constants, or some language built-ins.

@luis-mendo  It's unclear "what is exactly unclear?"

@erik-the-outgolfer Could you explain?

I don't think those notifications reached them (with the hyphens) as I got them in my inbox.

@JonathanAllan not quite familar with pinging syntax, and non-latin names.. maybe they will return some day :)

It might be worth adding some test cases ...including some at edges like: 6, [100, 50, 77, 22, 14, 44], 180, 3 -> 0; and 6, [100, 50, 77, 22, 14, 45], 180, 3 -> 1.

Does M have a minimum value? e.g. at least more than 0, or can it also be negative?

Can M be 0-indexed? (i.e., 2 in each of the test cases)

Also, can output be reversed? A falsey value for true and  truthy value for false?

@EmbodimentofIgnorance, I don't think it would be possible to have a negative number of investors! But the first part of your question does need answering; the current requirements that M<=N>=1 do imply that M could be 0.

Can't the second bullet point be more simply put as "Each investor must invest $T/N$"?  If there is any $k$ that fulfills the requirements it holds that $k=N$ fulfills the requirement and of course the converse is trivial.  Am I missing something?

There also doesn't seem to be a winning criterion?

@WîtWisarhd Code golf is a winning criterion... look at the tags.

@WitWisarhd Initially it was there, but was removed after a bit of thinking - it does distract away from real condition point, and it can be derived, (just check condition for a case k==N)

I noticed the example for N=5; M=3; T=10000 allows for 3 investors with 3334. This implies that "integer division" (i.e. round down) wouldn't work. Was this intentional?

Jelly,  12  9 bytes
ṢṚ×J$ṫ⁵<Ṃ

A full program which accepts x T M and prints 0 if the peer is rewarded and 1 if not.
Try it online!
How?
ṢṚ×J$ṫ⁵<Ṃ - Main Link: list of numbers, x; number, T   e.g. [100, 50, 77, 22, 14, 45], 180
Ṣ         - sort x                                          [ 14, 22, 45, 50, 77,100]
 Ṛ        - reverse                                         [100, 77, 50, 45, 22, 14]
    $     - last two links as a monad:
   J      -   range of length                               [  1,  2,  3,  4,  5,  6]
  ×       -   multiply                                      [100,154,150,180,110, 84]
     ṫ    - tail from index:
      ⁵   -   5th argument (3rd input), M   (e.g. M=3)      [        150,180,110, 84]
       <  - less than T?                                    [          1,  0,  1,  1]
        Ṃ - minimum                                         0

seems not working: https://tio.run/##y0rNyan8///hzkWHp/uoHJ5wbMnDnasfNW61ebiz6dCah7sW/P//P9rQwEBHwdhYR8EISENR7H@g6H9jAA

in example third investor invested less than 1/3rd of T (less than 33), but result still counted as positive ("any k invested at least T/k each" failed)

Yeah, I created it using prefixes of reverse-sorted values and thought I could change it to postfixes of sorted, but actually couldn't because I'm then tailing... reverted :)

Yes, now border test case  [179, 89, 59, 44, 35, 29], 180, 3 correctly gives 0. And any increment of four last values will yield 1

Saved a couple of bytes by noticing I don't actually need each prefix, but only the last value of each prefix. Also flipped around 0 and 1 to save a byte

Added test cases, for convenience. Can you please explain how does that code work? :) I dont know Jelly..

Yeah, now I've finished golfing I'm writing an explanation.

Elegant solution, but strange, output is 1 now again. Even for [0, 0, 0, 0, 0, 0] output is 1

It now "prints 0 if the peer is rewarded and 1 if not". (i.e. 0 is "yes"). It saves 1 byte :)

I think yours is to be accepted! You were the first to post it, given a great explanation, a port to python, and had most influence to many's other answers. Also its still shortest. Well done, great job!

Btw, are you familar with hilbert curve? Could you help me to find efficient algorithm to converting 2D image to 1D representation with spatial locality property?

05AB1E, 9 bytes
{Rƶ.ssè›ß

Try it online or verify all test cases.
Port of @JonathanAllan's Jelly answer, so also takes the inputs x T M and outputs 0 for "yes" and 1 for "no". If this is not allowed, and it should be inverted, a trailing _ can be added.
Explanation:
{           # Sort the (implicit) input `x`
            #  i.e. `x`=[100,50,77,22,14,45] → [14,22,45,50,77,100]
 R          # Reverse it
            #  i.e. [14,22,45,50,77,100] → [100,77,50,45,22,14]
  ƶ         # Multiply it by it's 1-indexed range
            #  i.e. [100,77,50,45,22,14] → [100,154,150,180,110,84]
   .s       # Get all the suffices of this list
            #  i.e. [100,154,150,180,110,84]
            #   → [[84],[110,84],[180,110,84],[150,180,110,84],[100,154,150,180,110,84]]
     s      # Swap to take the (implicit) input `T`
      è     # Get the prefix at index `T`
            #  i.e. [[84],[110,84],[180,110,84],[150,180,110,84],[100,154,150,180,110,84]]
            #   and `T=3` → [150,180,110,84]
       ›    # Check for each list-value if the (implicit) input `M` is larger than it
            #  i.e. [150,180,110,84] and `M`=180 → [1,0,1,1]
        ß   # And pop and push the minimum value in the list (which is output implicitly)
            #  i.e. [1,0,1,1] → 0

Alternative for .ssè:
sG¦}

Try it online or verify all test cases.
Explanation:
s       # Swap to take the (implicit) input `T`
 G }    # Loop `T-1` times:
  ¦     #  Remove the first item from the list that many times
        #   i.e. [100,154,150,180,110,84] and `T=3` → [150,180,110,84]

I didn't stated on "how should you map output", just that it have to be boolean (to has only 2 states). So yes, definetely you may use 0 for "yes" and 1 for "no" :)

C# (Visual C# Interactive Compiler) with flag /u:System.Linq.Enumerable, 69 bytes
(n,x,t,m)=>Range(0,n-m+1).Where(b=>x.Count(a=>a>=t/(b+m))>=b+m).Any()

Try it online!
// Takes in 4 parameters as input
(n,x,t,m)=>
// Create a new array with the length of all the numbers from m to n, inclusive
Range(0,n-m+1)
// And filter the results by
.Where((_,b)=>
// If the number of people that invested more than the total amount divided by the index plus m
x.Count(a=>a>=t/(b+m))
// Is greater than the index plus m
>= b+m)
// And check if there is at least one value in the filtered IEnumerable<int>, and if there is, return true
.Any()

Without any flags, 73 bytes
(n,x,t,m)=>new int[n-m+1].Where((_,b)=>x.Count(a=>a>=t/(b+m))>=b+m).Any()

Try it online!

I thought of that, and stated in the description that N>=1, and M<=N So you may shorten your solution a bit :)

JavaScript, 54 52 bytes
(x,t,m,n)=>x.sort((a,b)=>a-b).some(i=>i*n-->=t&n>=m)

Try it online

Also 35-40% more performant that 72-byted solution. Lovely code, felt like its ready to be embedded in production MLM-related web projects :^)

Just noticed. Test case #2 [0, 60, 0, 60, 60, 0], 180, 3 -> true seems to be not working! 72 byted bersion handles it ok. Bug or feature?)

Retina, 79 bytes
\d+
*
O^`_+(?=.*])
_+(?=.*])(?<=(\W+_+)+)
$#1*$&
+`\W+_+(.*_)_$
$1
(_+).*], \1,

Try it online! Takes input in the format [x], T, M. Link includes test cases. Explanation:
\d+
*

Convert to unary.
O^`_+(?=.*])

Sort [x] in descending order.
_+(?=.*])(?<=(\W+_+)+)
$#1*$&

Multiply each element of [x] by its index.
+`\W+_+(.*_)_$
$1

Delete the first M-1 elements of [x].
(_+).*], \1,

Test whether any remaining element of [x] is greater or equal to T.

Perl 6, 46 33 29 bytes
{$^b>all $^a.sort Z*[...] @_}

Try it online!
Anonymous code blocks that takes input in the form list, amount, length of list, minimum amount of investors and returns a truthy/falsey all Junction, where truthy is failed and falsey is success.
Explanation:
{                           }  # Anonymous code block
     all                       # Are all of
         $^a.sort                # The sorted list
                  Z*             # Zip multiplied by
                     [...] @_    # The range from length of list to the minimum amount
 $^b>                          # Not smaller than the given amount?

05AB1E, 6 bytes
Input taken in the order T, N, x[], M
Output is 0 for peer reward and 1 if not
Ÿs{*›W

Try it online!
or as a Test Suite
Explanation
Ÿ        # push the range [N ... T]
 s{      # push the list x[] sorted ascending
   *     # elementwise multiplication (crops to shortest list)
    ›    # for each element, check if M is greater than it
     W   # push min of the result
         # output implicitly

Nice trick of using * with the range to implicitly crop the list!

C# (.NET Core), 129, 89 bytes
EDIT:  Thanks to Kevin Cruijssen for golfing off 40 bytes while explaining the mechanics as to why!
(n,q,t,m)=>{int c=0,j;for(;m<=n&c<1;c=c<m++?0:1)for(j=n;j-->0;)c+=q[j]<t/m?0:1;return c;}

Try it online!

106 bytes Some of the things I've changed: Removed the input n since you don't use it anywhere; removed k since you can use m itself; added a variable l for q.Length since you use it twice; combined the variables int c=0,l=q.Length,j; so you don't need the additional var; removed the unnecessary brackets by putting everything in the for-loop body; changed the c>=k check to c<k; and changed the if(c>0)break; to m=c>0?l+1:m;, since the loop stops if m<=l, changing m to l+1 saves a byte over break (and it also saves on 2 brackets). :)

If you haven't seen it yet, Tips for golfing in C# and Tips for golfing in  might be interesting to read, through.

89 bytes Some additions to the golfs in my first comment. The m=c>0?l+1:m can be removed completely and a &c<1 check can be added to the loop instead. And by taking the input n again, you don't need the q.Length anymore but can use n instead.

JavaScript, 72 bytes
Code
(x,T,M)=>x.sort(t=(d,e)=>e-d).map((s,i)=>s*i+s).slice(M-1).sort(t)[0]>=T

Try it online!
Accepts input in format (x[],T,M)
Explanation
x.sort(t=(d,e)=>e-d)     \\sort numbers in reverse numerical order
.map((s,i)=>s*i+s)       \\Multiply each number in array by position(1 indexed) in array
.slice(M-1)              \\Remove the first M-1 elements (at least M people)
.sort(t)[0]              \\Get the maximum value in the array
>=T                      \\True if the maximum value is >= the threshold

54 bytes?

(Or 53 bytes if the meaning of the Boolean value can be inverted.)

@Arnauld, 52 bytes ;)

(By the way, I came up with my solution independently of your comment, in case you were wondering - it's a port of my Japt solution. On mobile so can't see timestamps properly to tell who posted first.)

Python 3, 136 bytes
Just tests the conditions to make sure they are met. 1 if the reward is given, 0 if not.
lambda N,x,T,M:(sum(x)>=T)*(M<=N)*any(any(all(j>=T/k for j in i)for i in combinations(x,k))for k in range(M,N+1))
from itertools import*

Try it online!

Japt, 16 14 13 11 bytes
ñ í*WõX)d¨V

Try it
ñ í*WõX)d¨V
                  :Implicit input of array U=x and integers V=T, W=M & X=N
ñ                 :Sort U
  í               :Interleave with
    WõX           :  Range [W,X]
   *              :  And reduce each pair of elements by multiplication
       )          :End interleaving
        d         :Any
         ¨V       :  Greater than or equal to V

Python,  71  65 bytes
lambda x,T,M:all(i*v<T for i,v in enumerate(sorted(x)[-M::-1],M))

Try it online!
An unnamed function; port of my Jelly answer. As such "yes" is False and "no" is True. Here, however, we discard test-cases as a part of the reversal and take advantage of the ability to initiate the enumerate count to M. (min would also work in place of all)

R, 43 42 bytes
-1 bytes by implementing the approach even more closely
function(N,x,S,M)min(sort(x,T)[M:N]*M:N<S)

Try it online!
Simple R implementation of Jonathan's Jelly approach. I tried a bunch of variations but this pips the best I could think of by a few bytes.
1 implies failure, 0 implies success.

Java 8, 91 (or 89?) bytes
(N,x,T,M)->{int c=0,j;for(;M<=N&c<1;c=c<M++?0:1)for(j=N;j-->0;)c+=x[j]<T/M?0:1;return c;}

Port of @Destroigo's C# .NET answer (after I golfed it some more), so make sure to upvote him!
Takes inputs N,x,T,M and outputs true/false for "yes"/"no" respectively.
Since the challenge specifically asks for boolean results, I can't return the 1/0 as is, since those aren't valid truthy/falsey values in Java. If any two distinct output values for "yes"/"no" is valid for this challenge instead, the >0 in the return can be dropped to save two bytes, in which case it'll return 1/0 for "yes"/"no" respectively.
Try it online.
Explanation:
(N,x,T,M)->{           // Method with the four parameters and boolean return-type
  int c=0,             //  Count integer, starting at 0
      j;               //  Temp index integer
  for(;M<=N            //  Loop as long as `M` is smaller than or equal to `N`
       &c<1            //  and `c` is not 1 yet:
      ;                //    After every iteration:
       c=c<M++?        //     If `M` is smaller than `c`:
                       //     (and increase `M` by 1 afterwards with `M++`)
          0            //      Set `c` to 0
         :             //     Else:
          1)           //      Set `c` to 1
    for(j=N;j-->0;)    //   Inner loop `j` in the range (`N`,0]:
       c+=             //    Increase the counter `c` by:
          x[j]         //     If the `j`'th value in `x`
              <T/M?    //     is smaller than `T` divided by `M`:
                   0   //      Leave the counter `c` unchanged by adding 0
                  :    //     Else:
                   1;  //      Increase the counter `c` by 1
  return c>0;}         //  Return whether the counter `c` is 1

C# (Visual C# Interactive Compiler), 66 bytes
(n,x,t,m)=>Enumerable.Range(m,n-m+1).Any(k=>x.Count(y=>y>=t/k)>=k)

Try it online!
Inspired by @EmbodimentOfIgnorance's answer.
I've mentioned this before, but C# 8 has a range literal which could make this answer something like this:
(n,x,t,m)=>[m..n-m+1].Any(k=>x.Count(y=>y>=t/k)>=k)

I saw a link to SharpLab with an example, but I wasn't able to get it to work myself.
One thing I changed was the x and t values are decimals. This handles the case where t is not divisible by k a little better.


text:
Mis-decode a date
Background
Inspired by a now deleted question by John Burger from which I quote:

Now obviously no human made this mistake. It's a mis-decode of something - perhaps the ISBN? My question is: does anyone know of an existing algorithm that was so messed up it would invent an entirely new calendar?

TFeld ingeniously commented:

It seems that the book was published on 2008-09-16, so maybe it was somehow read as 00809162 -> 00=dec?, 80, 9162

Task
Given a date represented as a three-element list, answer with the corresponding three-element mis-decoded list.
Mis-decoding happens as follows (example for [2008,9,16] in parentheses):

Join the digits of the year, month, and day, inserting leading zeros as necessary ("20080916")
Move the first digit to the end ("00809162")
Split the eight digits into groups of two, two, and four ("00","80","9162")
Interpret them as numbers ([0,80,9162])
Normalise the month number by wrapping 0 around to 12, and wrapping 13 around to 1, 14 to 2, 15 to 3, …, 25 to 1 etc. ([12,80,9162])
Rearrange the list to get the original order ([9162,12,80])

You may take the original date in any order, but your answer must use the same order. Please state any non-default order.
The given year will always have four digits, but dates in October will lead to a three- or two-digit answer year.
You may take a list of strings or a character-delimited string, but it may not include leading zeros and you must answer in the same format and again without leading zeros.

Examples
[1700,1,1] → [1011,10,0]
[1920,4,29] → [4291,8,0]
[1966,11,27] → [1271,12,61]
[1996,12,13] → [2131,3,61]
[2008,9,1] → [9012,12,80]
[2008,9,16] → [9162,12,80]
[1010,10,1] → [11,1,1]

Can we take the input as a list of strings?

@WindmillCookies Yes, but then they may not include leading zeros, and you must answer with a list of strings (without leading zeros) too.

Is it okay if the program prints the numbers separated by spaces to stdout?

@fəˈnɛtɪk What does your input/argument look like?

The input argument is in 3 integers from stdin. I am trying to do it using Cardinal.

@fəˈnɛtɪk Are they space or newline separated in stdin?

Newline separated

@fəˈnɛtɪk (sorry for slow responses) The printing on three lines is good. Space separated, not so much.

Is the output year guaranteed to have 4 digits (no leading zero)?

@NeilA. It follows from the spec that dates in October have a three-digit result year, no?

@Adám Ah, I wasn't sure if when you said "The year will always have four digits." you were referring to input, output, or both

The clear reason for the date of publishing is that it was published in the 92nd century when they fixed all the months to have 100 days each and sent back with a time machine due to how good the book was.

Python 2, 95 67 66 65 64 bytes
lambda y,m,d,t=10,T=1000:(m%t*T+d*t+y/T,y%T/t%12or 12,y%t*t+m/t)

Try it online!
-1 byte, thanks to Chas Brown

Given the task description, I kinda had to try it :)

C# (Visual C# Interactive Compiler), 69 bytes
(y,m,d)=>(m%10*1000+d*10+y/1000,(d=y%1000/10%12)<1?12:d,y%10*10+m/10)

Try it online!
Lambda with 3 inputs (y,m,d) that returns a 3-value tuple that has the resulting date parts in the same order.
The result is calculated by shifting digits to the left and right using regular division and the modulo operator with different powers of 10.
The d variable is used to caputure the month calculation so that it can be returned or wrapped to 12 when 0.

JavaScript, 74 72 65 bytes
Thanks @Shaggy for saving 2 bytes
Thanks @Arnauld for saving 7 bytes
(a,b,c)=>[b%10*1e3+c*10+a/1e3|0,a/10%100%12|0||12,b/10|0+a%10*10]

Try it online!
Straight modular arithmetic. Receives 3 integers (Y,M,D) and returns an array of 3 integers ([Y,M,D])

(a,b,c,T=10)=>[b%T*1e3+c*T+a/1e3|0,a/T%100%12|0||12,b/T|0+a%T*T]

Japt, 46 42 32 27 bytes
-10 bytes thanks to fəˈnɛtɪk and -1 byte thanks to Shaggy
ùT2 ¬éJ ò4 vò c mn v_%CªCÃé

Try it online

Explanation:
ùT2 ¬éJ ò4 vò c mn v_%CªCÃé  // Full program
                             // Test input:                     [2008,9,16]
ù                            // Left-pad each item
  2                          //   To length 2                   ["2008"," 9","16"]
 T                           //   With "0"                      ["2008","09","16"]
   ¬                         // Join into a string               "20080916"
    éJ                       // Rotate counter-clockwise         "00809162"
       ò4                    // Cut into slices of length 4     ["0080","9162"]
          vò                 // Slice the first item into 2    [["00","80"],"9162"]
             c               // Flatten                         ["00","80","9162"]
               mn            // Cast each item into numbers     [0,80,9162]
                  v_         // Apply to the first item:        [0
                    %C       //   %12                           [0
                      ªC     //      ||12                       [12
                        Ã    // Escape v_                       [12,80,9162]
                         é   // Rotate clockwise                [9162,12,80]

Wish I had some time to work on this with you properly, looks like an interesting one. ù2'0 -> ùT2 for a quick saving, though.

Why do you need to do if x>12 return x%12||12 else return x. Can't you just do return x%12||12?

Jelly,  19  18 bytes
-1 thanks to Erik the Outgolfer (D¹ŻṖ? → d⁵DẎ)
d⁵DẎ€Ẏṙ5ṁƲḌṃ2¦12Ṫ€

A monadic link accepting a list of integers which yields a list of integers.
Try it online! Or see the test-suite.
How?
d⁵DẎ€Ẏṙ5ṁƲḌṃ2¦12Ṫ€ - Link: list of integers, dt     e.g. [        1779,        3,        14]
d⁵                 - divmod 10 (vectorises)              [      [177,9],    [0,3],     [1,4]]
  D                - to decimal digits                   [[[1,7,7],[9]],[[0],[3]],[[1],[4]]]]
   Ẏ€              - tighten €ach:                       [    [1,7,7,9],    [0,3],     [1,4]]
         Ʋ         - last four links as a monad (call that x):
     Ẏ             -   tighten x                         [     1,7,7,9,      0,3,       1,4]
       5           -   literal five
      ṙ            -   rotate (left) left by (right)     [     3,1,4,1,      7,7,       9,0]
        ṁ          -   mould like x                      [    [3,1,4,1],    [7,7],     [9,0]]
          Ḍ        - from decimal digits                 [         3141,       77,       90]
             ¦     - sparse application: {
            2      -   to indices: literal two                                 77
           ṃ  12   -   do: base decompress using [1..12]                    [6,5]
                   - }                                   [         3141,    [6,5],       90]
                Ṫ€ - tail €ach                           [         3141,       5,        90]

D¹ŻṖ? → d⁵DẎ.

Very smart, thanks!

It's really not very smart; d⁵ is a usual way to add a leading zero to a one-digit number's decimal representation, when dealing with two-digit numbers. DẎ just extends this to >2-digit numbers, so that they're converted to their decimal representation properly (it's really D1¦Ẏ, since it only needs to cater for the first element of the divmod, but letting it cater for both doesn't harm). Finally, since only Ẏ needs to be mapped, we just stick an € after it and we're done.

Python 3, 126 111 bytes
Input and output as a list of strings. Probably could be shorter if I can rewrite this as a lambda.
def f(d):d=d[0][1:]+d[1].zfill(2)+d[2].zfill(2)+d[0][0];return[d[4:],str((int(d[:2])-1)%12+1),str(int(d[2:4]))]

Try it online!

Retina 0.8.2, 78 bytes
,(.\b)?
$#1$*0$1
(.)(..)(..)(...)
$4$1;11$*1$2$*1,$3$*
;(1{12})*
,1
,(1*)
,$.1

Try it online! Link includes test cases. Explanation:
,(.\b)?
$#1$*0$1

Replace the commas with zeros or just delete them for 2-digit numbers.
(.)(..)(..)(...)
$4$1;11$*1$2$*1,$3$*

Rearrange the year and extract the mis-decoded month and day in unary, adding 11 to the month.
;(1{12})*
,1

Reduce the month modulo 12 and add 1, bringing it into the desired range.
,(1*)
,$.1

Convert the month and day back to decimal without leading zeros.

05AB1E, 22 bytes
T‰JJ5._422S£εïNi12LÁsè

Try it online or verify all test cases.
Explanation:
T‰                       # Divmod each value in the (implicit) input with 10
                         #  i.e. [4291,8,0] → [[429,1],[0,8],[0,0]]
                         #  i.e. [2000,10,1] → [[200,0],[1,0],[0,1]]
  JJ                     # Then join everything together into a single string
                         #  i.e. [[429,1],[0,8],[0,0]] → "42910800"
                         #  i.e. [[200,0],[1,0],[0,1]] → "20001001"
    5._                  # Rotate it 5 times towards the left
                         #  i.e. "42910800" → "80042910"
                         #  i.e. "20001001" → "00120001"
       422S£             # Split it into parts of size 4,2,2
                         #  i.e. "80042910" → ["8004","29","10"]
                         #  i.e. "00120001" → ["0012","00","01"]
            ε            # Map each part to:
             ï           # Cast the string to an integer (removing leading zeros)
                         #  i.e. ["8004","29","10"] → [8004,29,10]
                         #  i.e. ["0012","00","01"] → [12,0,1]
              Ni         # And if the index is exactly 1:
                12L      # Push the list [1,2,3,4,5,6,7,8,9,10,11,12]
                   Á     # Rotate once towards the right: [12,1,2,3,4,5,6,7,8,9,10,11]
                    s    # Swap to get the map item
                     è   # And index it into the list (with automatic wraparound)
                         #  i.e. 0 → 12
                         #  i.e. 29 → 5
                         # (output the resulting list implicitly)
                         #  i.e. [8004,5,10]
                         #  i.e. [12,12,1]

Clojure, 178 bytes
An anonymous function that takes a sequence of integers (Y M D) as input.
#(let[s(apply format"%d%02d%02d"%)](let[[w x y z](map(fn[a](read-string(apply str\1\0\r a)))(partition 2(concat(rest s)[(first s)])))n(rem w 12)][(+(* 100 y)z)(if(= n 0)12 n)x]))

Try it online!

Pyth, 31 bytes
.e?tkb@S12tbvc.>sm.[\02`dQ3j46T

Try it online here, or verify all the test cases at once here.
.e?tkb@S12tbvc.>sm.[\02`dQ3j46T   Implicit: Q=eval(input()), T=10
                                    # Example input: [2008,9,16]
                 m       Q        Map each element of Q, as d, using:
                       `d           Stringify d
                  .[                Pad the above on the left...
                      2             ... to length of a multiple of 2...
                    \0              ... with "0"
                s                 Concatenate into a single string
                                    # '20080916'
              .>          3       Rotate 3 positions to the right
                                    # '91620080'
             c             j46T   Chop the above at indexes 4 and 6 (j46T -> 46 to base 10 -> [4,6])
                                    # ['9162', '00', '80']
            v                     Evaluate each element of the above as a numeric
                                    # [9162, 0, 80]
.e                                Map each element of the above, as b with index k, using:
  ?tk                               If k-1 is nonzero...
     b                              ... yield b, otherwise...
      @S12                          ... look up in [1-12]...
          tb                        ... element with index b-1 (modular indexing)
                                    # [9162, 12, 80]
                                  Implicit print result of previous map

Perl 6, 58 bytes
{m/(.)(..)(..)(...)/;$3~$0,$1%12||12,+$2}o*.fmt('%02d','')

Try it online!
Returns the year with leading zeros.