text:
Simplification of numbers
How, you can’t remember the 6 or 7-digit phone number that appeared on the TV screen for a second?! Using the special technique described below, you will turn into a walking phonebook!
Obviously, the number 402 is easier to remember than the number 110010010, and the number 337377 is easier to remember than the number 957472.
This means that the memorized number, on the one hand, should contain as few digits as possible, and on the other hand, it is desirable that the number contains as many repeating numbers as possible.
As a criterion for the difficulty of remembering, we take the sum of the number of digits in number and the number of different digits in number. A memorized number can be written in another number system, perhaps then it will be easier to remember. For example, the number 65535 in the hexadecimal notation looks like FFFF.
Task
You need to write a program for selecting the base of the number system to minimize the complexity criterion. The base of the number system must be selected in the range from 2 to 36, then the numbers 0-9 and the English letters A-Z can be used to represent the number.
Input
The input contains a decimal integer from 1 to 999999999.
Output
The output must contain the base of the number system (from 2 to 36), minimizing the criterion of memorization complexity, and the number in the selected number system, separated by one space. If several bases give the same value for the criterion, then choose the smallest among them.
Notes

The letters must be uppercase(A-Z).

Test Cases
Input             Output
1               2 1
2              3 2
65535       16 FFFF
123          12 A3

Great challenge, but it needs more test cases.

Also, the output format is a bit too strict, you might want to allow e.g. an array of two elements, the base and the string, or allowing them in reverse order or separated by another character. Also, I assume that you add the sum of the digits to the number of digits, but you may want to clarify that.

Can I use a-z instead of A-Z?

Can we just use the corresponding numbers instead of A-Z?

@Neil Sorry, but it has to be A-Z.

@flawr No, it should be A-Z.

@VerNick Next time you write a similar challenge I would suggest allowing both these requests, as they are just an unnecessary complication  which are discouraged: see e.g. here.

@flawr I see... well, I can edit the question and change the rules, since there not so many answers.

@VerNick For at least one participant that would mean a big change in the submission, so I'd recommend not changing the rules now.

Perl 6, 55 54 bytes
-1 byte thanks to Jo King.
{~map({$^b,.base($b)},2..36).min:{@$_+.Set}o*[1].comb}

Try it online!

You can replace @$_ with @_ and it still works.

@SirBogman This just happens to work with the very few test cases.

That makes sense. It didn't feel quite right.

Python 2, 150 149 127 144 bytes
lambda n:min((len(c(n,b))+len(set(c(n,b))),b,c(n,b))for b in range(2,37))[1:]
c=lambda n,b,s='':n and c(n/b,b,chr(n%b+48+7*(n%b>9))+s)or s or'0'

Try it online!

Python 3, 136 bytes
lambda n:min((len((*c(n,b),*{*c(n,b)})),b,c(n,b))for b in range(2,37))[1:]
c=lambda n,b,s='':n and c(n//b,b,chr(n%b+48+7*(n%b>9))+s)or s

Try it online!

Python 3.8 (pre-release), 131 bytes
lambda n:min((len((*(x:=c(n,b)),*{*x})),b,x)for b in range(2,37))[1:]
c=lambda n,b,s='':n and c(n//b,b,chr(n%b+48+7*(n%b>9))+s)or s

Try it online!

c converts a base 10 number to any base (2-36), and the first (anonymous) function finds the smallest result.

05AB1E, 16 14 bytes
-1 byte thanks to Kevin Cruijssen
₆LBāøΣнDÙìg}1è

Try it online!
Or add R)» at the end to conform exactly to the specified output format, but most other answers didn't bother.
Explanation:
₆L          # range 1..36
  B         # convert the input to each of those bases
   āø       # enumerate (pair each element with its 1-based index)
Σ     }     # sort by
     g      # length
 н          # of the first element
    ì       # concatenated to
  DÙ        # itself, uniquified
1è          # take the second entry (first will always be base 1)

-1 byte by using ₆L©B®ø instead of ₆LεBy‚}

@KevinCruijssen Thanks! Another -1 by using ā, seems like you always forget about that one.

Lol, I indeed do.. I remembered it with this challenge earlier today, not that it helped in any way, haha xD

@recursive you don't seem to have read the answer. I link a version that complies with the strict output requirements, and explain why I didn't make that the main version.

@Grimy guilty as charged.  Sorry to bother you.

JavaScript (ES6),  87 85  101 bytes
Edit: +16 useless bytes to comply with the strict output format
n=>(g=m=>--b>2?g(m<(v=new Set(s=n.toString(b)).size+s.length)?m:(o=b+' '+s.toUpperCase(),v)):o)(b=37)

Try it online!

Ah, I missed that part

Japt v2.0a0 -gS, 24 23 bytes
Not pretty, but it does the job. +2 bytes for the completely unnecessary requirement that output be uppercase.
37o2@sX u ¸iXÃñÈÌiXÌâ)l

Try it
37o2@sX u ¸iXÃñÈÌiXÌâ)l     :Implicit input of integer
37o2                        :Range [2,37)
    @                       :Map each X
     sX                     :  Convert the input to a base-X string
        u                   :  Uppercase
          ¸                 :  Split on spaces (there are none, so this returns a singleton array)
           iX               :  Prepend X
             Ã              :End map
              ñ             :Sort by
               È            :Pass each X through the following function
                Ì           :  Last element of X
                 i          :  Prepend
                  XÌâ       :    Last element of X, deduplicated
                     )      :  End prepend
                      l     :  Length
                            :Implicit output of the first sub-array, joined with spaces

Yes, it works nice, but the letters must be uppercase.

@VerNick, why? That adds absolutely nothing to the challenge.

...I guess the next thing will be "separated by one space". Seems the output format has been made very strict on this challenge, and from the comments does not look like it will change.

@JonathanAllan, luckily I can "fix" that one with a change of flag.

PHP, 124 119 bytes
for($i=36;$b=strtoupper(base_convert($argn,10,--$i));$o[strlen($b.count_chars($b,3))]="$i $b");krsort($o);echo end($o);

Try it online!
A shame about the +12 bytes in PHP to uppercase the output... but... anyway.

Zsh, 85 bytes
for b ({36..2})x=$[[#$b]$1]&&x=${x#*\#}&&a[$#x+${#${(us::)x}}]=$b\ $x
a=($a)
<<<$a[1]

For this number of statements inside the for loop, using ...&&...&&... is shorter than {...;...;...;}.
for b ({36..2})                   # order decreasing: smaller bases overwrite larger ones
    x=$[[#$b]$1] && \             # set x to [base]#[num]
    x=${x#*\#} && \               # strip leading [base]#
    a[$#x+${#${(us::)x}}]=$b\ $x  # use score as index to store "[base] [number]"
#            ${(us::) }           # (s::)plit into characters, take (u)nique
a=($a)                            # remove empty elements from array
<<<$a[1]                          # print out the first element (smallest score)

Try it online!
Here's an 81-byte solution which prints in the form [base]#[num] instead:
for b ({36..2})x=$[[#$b]$1]&&y=${x#*\#}&&a[$#y+${#${(us::)y}}]=$x
a=($a)
<<<$a[1]

Try it online!

J, 67 bytes
(];'0123456789ABCDEF'{~b)[:(2+]i.<./)](#+#@~.)@(b=:#.inv~)"+2+i.@35

Try it online!

Charcoal, 38 bytes
Ｎθ≔ＥＥ³⁴↨θ⁺²ιＬ⁺ιΦι⁼λ⌕ικη≔⁺²⌕η⌊ηηＩη ↥⍘θη

Try it online! Link is to verbose version of code. Explanation:
Ｎθ

Input the integer.
≔ＥＥ³⁴↨θ⁺²ι

Convert it from base 2 to base 36...
Ｌ⁺ιΦι⁼λ⌕ικη

... deduplicate, concatenate, and take the length.
≔⁺²⌕η⌊ηη

Take the index of the minimum complexity and add 2 to get the base.
Ｉη ↥⍘θη

Print the base and the integer converted to that base in upper case.

Stax, 19 bytes
Ç╛;ⁿY3█↕(╖S♪*ò▌?½╦l

Run and debug it
No fancy algorithm, just straightforward brute force.  About a third of the program is format-wrangling for the precise output rules.
Bonus program: Output for [1..1000]

Jelly, 25 bytes
bⱮ36µQL+LN)Mḟ1Ḣ,ị‘ịØBʋ¥⁸K

Try it online!
A monadic link taking an integer as its argument and returning a Jelly string of the desired format. If a two-item list was acceptable output (as per most challenges), could save 2 bytes. If base 1 were acceptable for the edge case of 1 as input, could save a further 2 bytes.

Brachylog, 44 bytes
∧Y≜∧36≥Xℕ₂≜&ḃ↙X Zd,Zl≡Y∧XwṢwZ{-₁₀;Ạụᵗ∋₍|}ᵐwᵐ

Try it online!
This hurt a bit to write.

Japt v2.0a0, 31 bytes
2o37 ñ@sX Ê+UsX â ÊÃÎ
+S+NÎsU u

Try it

Perl 5, 161 bytes
sub f{$X=99;for$b(2..36){$_=c($_[0],$b);$x=uniq(/./g)+y///c;($X,$B,$C)=($x,$b,$_)if$x<$X}$B,$C}
sub c{my($n,$b)=@_;$n?c(int$n/$b,$b).chr(48+$n%$b+7*($n%$b>9)):''}

Try it online!

Wolfram Language (Mathematica), 109 111 bytes
Print[a=OrderingBy[#~IntegerDigits~Range@36,Tr[1^#]+Tr[1^Union@#]&,1][[1]]," ",ToUpperCase[#~IntegerString~a]]&

+2: fixed. Thanks for the catch @Roman
OrderingBy was introduced  in Mathematica 12.0, which TIO does not seem to have updated to yet.

"If several bases give the same value for the criterion, then choose the smallest among them.": OrderingBy doesn't conform to this requirement.

Maybe something with MinimalBy, like this?

@Roman doesn't it? As far as I can tell, it preserves the relative order of two indices that have the same value..

With the argument 123, your solution prints 36 3F instead of the required 12 A3. From OrderingBy[123~IntegerDigits~Range@36, Tr[1^#] + Tr[1^Union@#] &] I get the answer {36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 6, 5, 11, 10, 9, 8, 7, 4, 3, 2, 1}, so the usual assumption of no re-ordering equivalent entries seems to be ignored here. My $Version is "12.0.0 for Mac OS X x86 (64-bit) (April 7, 2019)".

Ah, you're right. My bad for not noticing that.

Python 2, 140 135 bytes
lambda n:min([(b,g(n,b))for b in range(2,36)],key=lambda(b,s):len(s)+len(set(s)))
g=lambda n,b:n and g(n/b,b)+chr(n%b+48+7*(n%b>9))or''

Try it online!

Perl 5 -Minteger -MList::Util=uniq,first -ap, 123 112 bytes
$"=$,;map{@r=();$t="@F";do{unshift@r,(0..9,A..Z)[$t%$_]}while$t/=$_;$a[@r+uniq@r]||="$_ @r"}2..36;$_=first{$_}@a

Try it online!

C (clang), 165 161 bytes
j,r,m,x,*_;t(n){for(char*g,b[74][37]={},i=1,p=99;g=b[++i],i<37;r=j<p?_=g,p=j,i:r)for(j=0,m=n;m;m/=i,*--g=x+=x>9?87:48)j-=~!b[i+36][x=m%i]++;printf("%i,%s",r,_);}

Try it online!

Shortened and improved by @ceilingcat

n//input

,i=2//iterator from base 2 to 36

,j//current complexity

,p=99//best complexity

,r//result = iterator

,m// temp copy of n

,x ;// m%i

char*g // current string ptr

,*_ // best str ptr

,b[74][37];//buffer

/* [37+37] = [strings obtained +
              test for used characters  ]
*/

t(n){

 for(; g=b[i], // move ptr

       i<37 ;
       r=j<p?_=g,p=j,i:r, // save best solution

       ++i){//for every base

  for( j=0,m=n; m ; m/=i, // extract digit

       *--g=x+=x>9?87:48)
       // move ptr backward for printf use and transform to ascii value

   j+=b[i+36][x=m%i]++?1:2;
   // increment byte relative to the character

   // and if it was 0 increments j by 2 : 1 for the new character used and 1 for digit count

   // else incr only digits count + move pointer

  //printf("%s - ",g);// test

// printf("r%i p%i j%i\n",r,p,j);// test

 }

 printf("%i,%s",r,_);//output

}

Scala, 105 97 bytes
n=>{val(b,x)=2.to(36)map(b=>b->n.toString(b))minBy((_,x)=>(x++x.toSet).size);b+" "+x.toUpperCase}

Try it online!


text:
Crossing sequences
Crossing Sequences
Given a list of positive integers A, call it an increasing sequence if each element is greater than or equal to the previous one; and call it a decreasing sequence if each element is less than or equal to the previous one.
Some increasing sequences:
[1,2,4,7]
[3,4,4,5]
[2,2,2]
[]

Some decreasing sequences:
[7,4,2,1]
[5,4,4,3]
[2,2,2]
[]

A crossing sequence is a list that can be decomposed into two disjoint subsequences, one an increasing sequence and the other a decreasing sequence.
For example, the list:
[3,5,2,4,1]

is a crossing sequence, since it can be decomposed into:
[3,    4  ]
[  5,2,  1]

where [3,4] is the increasing subsequence and [5,2,1] is the decreasing subsequence. We'll call such a pair of (increasing,decreasing) subsequences a decomposition of the crossing sequence.
The list:
[4,5,2,1,3]

is not a crossing sequence; there is no way to decompose it into an increasing and decreasing subsequence.
Your task is to write a program/function taking as input a list of positive integers; and if it is a crossing sequence, return the two lists in one of its decompositions; or some consistent "falsey" value if the list is not a crossing sequence.
This is code-golf; shortest program/function in each language is the winner.
Rules:

Input is flexible.
The usual loopholes are forbidden.
If there are multiple valid ways to decompose the input, you may output one or all of them.
Output formatting for the decomposition is flexible; but it must be unambiguous regarding the distinction between the two subsequences.
You may use any consistent output value to indicate that the input is not a crossing sequence; so long as it is unambiguous compared to the output for any crossing sequence. You should specify the falsey value in your answer.

Test Cases:
Using False to indicate non-crossing sequences:
[3, 5, 2, 4, 1] => [3, 4], [5, 2, 1]
[3, 5, 2, 4, 4, 1, 1] => [3, 4, 4], [5, 2, 1, 1]

[7, 9, 8, 8, 6, 11] => [7, 8, 8, 11], [9, 6]
[7, 9, 8, 8, 6, 11] => [7, 9, 11], [8, 8, 6] # also valid
[7, 9, 8, 8, 6, 11] => [7, 8, 11], [9, 8, 6] # also valid

[7, 8, 9, 10, 20, 30] => [7, 8, 9, 20, 30], [10]
[7, 8, 9, 10, 20, 30] => [8, 9, 10, 20, 30], [7] # this is also valid

[5, 5, 5] => [5, 5, 5], []

[4, 5, 2, 1, 3] => False
[3, 4, 3, 4, 5, 2, 4] => False

Possible duplicate. Only two differences I see is that the other challenge should be run in polynomial time in the length of the input, and allows for a truthy value instead of the two subsequences (returning the subsequences themselves will receive a 20% bonus though). Still sounds like a dupe to me, but I won't hammer it.

@KevinCruijssen time restriction is probably enough on its own not to make this a dupe.

@NickKennedy Possibly yeah, which is why I refrained from hammering it. :)

Suggested test case: [3, 5, 2, 4, 4, 1, 1]. The current test cases let you get away with >= / <, when it should really be >= / <=.

You should specify the falsey value in your answer -> may this value be truthy, as long as it's consistent and cannot be interpreted as a solution?

@Arnauld : Yes, it can be any value ("falsey" is just to say: it is false that the input is a crossing sequence).

Brachylog, 17 bytes
;Ṣzpᵐz{ℕˢ}ᵐ≤₁ʰ≥₁ᵗ

Try it online!
There's probably considerable room to golf this.

You've already answered this challenge before here, where you did it in 16 bytes. ;)

I couldn't shake the feeling that there was something similar I'd done, but for some reason my mind decided it had to have been this instead

05AB1E, 15 14 13 bytes
2.Œ.ΔćRšεü@}W

Try it online or validate all test cases.
Explanation:
2.Œ                    # all partitions of the input in 2 subsequences
   .Δ                  # find the first partition such that the following gives 1
     ćRš               # reverse the first subsequence
        ε  }           # map each subsequence to
         ü@            # pairwise greater-than
            W          # minimum (1 if all 1s, 0 otherwise)

Jelly, 12 bytes
ŒPżṚ$ṢNÞƭ€ƑƇ

Try it online!

JavaScript (ES6),  110 105  104 bytes
Returns either [[decreasing], [increasing]] or \$1\$ if there's no solution.
f=(a,n,b=[[],[]])=>a.some((v,i)=>[...x=b[i=n>>i&1]].pop()*(x.push(v),i-=!i)>v*i)?n>>a.length||f(a,-~n):b

Try it online!
How?
We try all values of a bitmask \$n\$ between \$0\$ and \$2^L\$, where \$L\$ is the length of the input array.
At each iteration, we split the original array into two subsequences \$b[0]\$ (decreasing) and \$b[1]\$ (increasing), using each bit \$i\$ of \$n\$ to know where each value goes.
When a new value is added to a subsequence, we simultaneously make sure that it's not invalid by comparing it with the last value, popped from a copy of the subsequence. The direction of the inequality is always the same, but the operands are multiplied by either \$1\$ (if \$i=1\$) or \$-1\$ (if \$i=0\$):
[...x = b[i = n >> i & 1]].pop() * (x.push(v), i -= !i) > v * i

We stop and return \$b\$ as soon as all values are passing, i.e. some() is falsy.

Haskell, 84 bytes
(([],[])#)
(d,i)#(a:b)=(#b)=<<[(d++[a],i)|all(a<=)d]++[(d,i++[a])|all(a>=)i]
p#_=[p]

Returns a list of all valid (decreasing,increasing) pairs or the empty list if there's no such pair.
Try it online!

Python 3, 109 107 bytes
def f(l,i=[],d=[]):
 if l:s,*r=l;i and s<i[-1]or f(r,i+[s],d);d and s>d[-1]or f(r,i,d+[s])
 else:print(i,d)

Try it online!
The function prints all possible decompositions to the standard output. If there are no possible decompositions, nothing is printed.
Thanks to @Sriotchilism O'Zaic for improvement suggestions.

Welcome to the site.  I suggest doing s<i[-1] rather than i[-1]>s  and similar with d[-1]<s , both save a byte.

Thanks for the suggestion. I've updated the answer. Is there any copy-pastable template here for publishing answers?

I'm not sure what you mean?  TIO has a template that you seem to already be using.

I only generated a link on TIO and added the link to my post. I did not use any template there. Where is it?

@Joel - At the top of the TIO page there's an icon that looks like some chain links. Click that, and then you get a page of options. One of them is 'Code Golf Submission'. That will put into your copy buffer the formatted stuff you want! Welcome also, and nice solution!

@Chas Brown Oh, I see. Thank you very much !

Python 2, 147 bytes
def f(a):
 for i in range(2**len(a)):
	x=[];y=[]
	for c in a:[x,y][i&1]+=[c];i/=2
	if x==sorted(x)and y[::-1]==sorted(y[::-1]):return x,y
 return 0

Try it online!

source: Stack Exchange

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

sort: votes


text:
Telephone number in spoken words
Goal
Write a program or function that translates a numerical telephone number into text that makes it easy to say.  When digits are repeated, they should be read as "double n" or "triple n".
Requirements
Input
A string of digits.

Assume all characters are digits from 0 to 9.
Assume the string contains at least one character.

Output
Words, separated by spaces, of how these digits can be read out loud.

Translate digits to words:
0 "oh"
1 "one"
2 "two"
3 "three"
4 "four"
5 "five"
6 "six"
7 "seven"
8 "eight"
9 "nine"
When the same digit is repeated twice in a row, write "double number".
When the same digit is repeated thrice in a row, write "triple number".
When the same digit is repeated four or more times, write "double number" for the first two digits and evaluate the rest of the string.
There is exactly one space character between each word.  A single leading or trailing space is acceptable.
Output is not case sensitive.

Scoring
Source code with the least bytes.
Test Cases
input        output
-------------------
0123         oh one two three
4554554      four double five four double five four
000          triple oh
00000        double oh triple oh
66667888     double six double six seven triple eight
19999999179  one double nine double nine triple nine one seven nine

Anyone interested in "speech golf" should note that "double six" takes longer to say than "six six". Of all the numerical possibilities here, only "triple seven" saves syllables.

@Purple P: And as I'm sure you know, 'double-u double-u double-u'>'world wide web'..

I vote to change that letter to "dub".

You should have used non-English/standard digit names for all digits to avoid build-ins…

"oh" and not "zero"?

So oh and zero are both acceptable?

@ShaunBebbers Is there a builtin in your language? ;)

@recursive the test cases show 9999999 should be double nine double nine triple nine, not double nine double nine double nine nine as your comment suggests is correct?

I think I misread the spec.  It says "When the same digit is repeated four or more times, write "double number" for the first two digits and evaluate the rest of the string."  However, I read it as "first two pairs of digits".  @640KB:  I think you're totally correct.

I know this is only an intellectual exercise, but I have in front of me a gas bill with the number 0800 048 1000, and I would read that as "oh eight hundred oh four eight one thousand". The grouping of digits is significant to human readers, and some patterns such as "0800" are treated specially.

@PurpleP Anyone interested in clarity of speech, however, especially when speaking over the phone, might want to use "double 6" since it's clearer that the speaker means two sixes and didn't repeat the number 6 accidentally. People aren't robots :P

05AB1E, 53 52 51 50 49 bytes
γε€T2äθ¬MÊi¨₃1ǝR]˜“Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‹¶½¿“#sè¸»

Try it online!
Explanation:
γ                      # split input in groups of consecutive equal digits
 ε              ]      # for each group
  €T                   #  add a 10 before each digit (66 -> [10, 6, 10, 6])
    2äθ                #  keep only the second half of that list
       ¬MÊi     ]      #  if the first element is not the maximum
           ¨           #   drop the last element
            ₃1ǝ        #   replace the second element with 95
               R       #   reverse the list
˜                      # flatten
 “...“                 # compressed string: "oh one two ... nine double triple"
      #                # split on spaces
       sè              # index (wraps around, so 95 yields "triple")
         ¸»            # join with spaces

Oh, M also looks inside lists when determining the maximum integer on the stack? Didn't knew that. Sounds like something to remember. :)

8088 Assembly, IBM PC DOS, 164 159 156 155 bytes
Binary:
00000000: d1ee 8a0c 03f1 53fd ac3a d075 0343 e2f7  ......S..:.u.C..
00000010: 85db 741c 5f8a d043 f6c3 0174 0a57 bd64  ..t._..C...t.W.d
00000020: 0155 83eb 0374 0957 bd5d 0155 4b4b 75f7  .U...t.W.].UKKu.
00000030: 8ad0 2c2f 7213 518a f0b0 24b1 31bf 6a01  ..,/r.Q...$.1.j.
00000040: fcf2 aefe ce75 fa59 57e2 bc5a 85d2 740c  .....u.YW..Z..t.
00000050: b409 cd21 b220 b402 cd21 ebef c364 6f75  ...!. ...!...dou
00000060: 626c 6524 7472 6970 6c65 246f 6824 6f6e  ble$triple$oh$on
00000070: 6524 7477 6f24 7468 7265 6524 666f 7572  e$two$three$four
00000080: 2466 6976 6524 7369 7824 7365 7665 6e24  $five$six$seven$
00000090: 6569 6768 7424 6e69 6e65 24              eight$nine$

Build and test executable using xxd -r from above, or download PHONE.COM.
Unassembled listing:
D1 EE       SHR  SI, 1              ; point SI to DOS PSP (80H) for input string
8A 0C       MOV  CL, BYTE PTR[SI]   ; load input string length into CX
03 F1       ADD  SI, CX             ; move SI to end of input
53          PUSH BX                 ; push a 0 to signal end of output stack
        CHAR_LOOP:
FD          STD                     ; set LODS direction to reverse
AC          LODSB                   ; load next char from [SI] into AL, advance SI
3A D0       CMP  DL, AL             ; is it same as previous char?
75 03       JNZ  NEW_CHAR           ; if not, it's a different char
43          INC  BX                 ; otherwise it's a run, so increment run length
E2 F7       LOOP CHAR_LOOP          ; move on to next char
        NEW_CHAR:
85 DB       TEST BX, BX             ; is there a run greater than 0?
74 1C       JZ   GET_WORD           ; if not, look up digit name
5F          POP  DI                 ; get name for the current digit
8A D0       MOV  DL, AL             ; save current char in DL
43          INC  BX                 ; adjust run count (BX=1 means run of 2, etc)
F6 C3 01    TEST BL, 1              ; is odd? if so, it's a triple
74 0A       JZ   IS_DBL             ; is even, so is a double
57          PUSH DI                 ; push number string ("one", etc) to stack
BD 0164     MOV  BP, OFFSET T       ; load "triple" string
55          PUSH BP                 ; push to stack
83 EB 03    SUB  BX, 3              ; decrement run count by 3
74 09       JZ   GET_WORD           ; if end of run, move to next input char
        IS_DBL:
57          PUSH DI                 ; push number string to stack
BD 015D     MOV  BP, OFFSET D       ; load "double" string
55          PUSH BP                 ; push to stack
4B          DEC  BX                 ; decrement by 2
4B          DEC  BX
75 F7       JNZ  IS_DBL             ; if not end of run, loop double again
        GET_WORD:
8A D0       MOV  DL, AL             ; save current char into DL
2C 2F       SUB  AL, '0'-1          ; convert ASCII char to 1-based index
72 13       JB   NOT_FOUND          ; if not a valid char, move to next
51          PUSH CX                 ; save outer loop counter
8A F0       MOV  DH, AL             ; DH is the index to find, use as scan loop counter
B0 24       MOV  AL, '$'            ; word string is $ delimited
B1 31       MOV  CL, 031H           ; search through length of word data (49 bytes)
BF 016A     MOV  DI, OFFSET W       ; reset word data pointer to beginning
FC          CLD                     ; set DF to scan forward for SCAS
        SCAN_LOOP:
F2/ AE      REPNZ SCASB             ; search until delimiter '$' is found in [DI]
FE CE       DEC  DH                 ; delimiter found, decrement counter
75 FA       JNZ  SCAN_LOOP          ; if counter reached 0, index has been found
59          POP  CX                 ; restore outer loop position
57          PUSH DI                 ; push string on stack
        NOT_FOUND:
E2 BC       LOOP CHAR_LOOP          ; move to next char in input
        OUTPUT_STACK:
5A          POP  DX                 ; get string from top of stack
85 D2       TEST DX, DX             ; it is the last?
74 0C       JZ   EXIT               ; if so, exit
B4 09       MOV  AH, 09H            ; DOS display string function
CD 21       INT  21H                ; write string to console
B2 20       MOV  DL, ' '            ; load space delimiter
B4 02       MOV  AH, 02H            ; DOS display char function
CD 21       INT  21H                ; write char to console
EB EF       JMP  OUTPUT_STACK       ; continue looping
        EXIT:
C3          RET                     ; return to DOS

D   DB "double$"
T   DB "triple"
W   DB "$oh$","one$","two$","three$","four$","five$","six$","seven$","eight$","nine$"

TL;DR:
The input string is read right to left to make it easier to find a triple.  The output is pushed onto the x86 stack to simplify reversing out the display order and also facilitate rearranging the "double" and "triple" words to precede the digit's name.
If the next digit is different than the last, the name is looked up in the list of words and pushed on to the stack.  Since there's no formal concept of an "indexed array of variable-length strings" in machine code, the list of words is scanned i (the word's index) number of times for the string delimiter ($) to find the corresponding word. Helpfully, x86 does have a pair of short instructions (REPNZ SCASB which is similar to memchr() in C), that simplifies this (thanks CISC!).
If the digit is the same as the previous one, the counter for the length of a "run" is incremented and continues looping leftward on the input.  Once the run is over, the digit's name is taken from the stack since it will need to placed after the "double" or "triple" for each grouping.  If the length of the run is odd (and run length is > 1), the digit's name followed by the string "triple" is pushed to the stack and the run length is reduced by 3.  Since the run length will now be even, the step is repeated for "double" until the run length is 0.
When the input string has reached the end, the stack is dumped out with each saved string written to the screen in reverse order.
I/O:
A standalone PC DOS executable, input from command line output to console.

Download and test PHONE.COM.

repne scasb is memchr (or strchr if you know there's going to be a hit), not strstr.

Is CH=0 on process entry guaranteed by a standard, or is that just what some DOS version happens to do?  I notice you assume that mov cl, byte[si]  is equivalent to movzx cx, byte [si].  I wonder if using a different reg, like AH, for the count with dec ah / jnz instead of loop would save anything from not having to push/pop CX.  Probably not, and you don't have any 16-bit regs left that would allow 1-byte dec.

@PeterCordes, for the CH=0 I go by http://www.fysnet.net/yourhelp.htm, which for any reasonable release of DOS is always zero'd, same with BX. Good thought about the zero-extend mov, though technically I don't think movzx is available on the 808x (keeping the target platform an IBM PC 5150 and all). I fiddled around with all of the registers as best I could to save the bytes, but if you see something I likely missed, please let me know!

It's more accurate to call it memchr IMO.  The "string instruction" naming misleads people into thinking they work on implicit-length C strings, but really they work on explicit-length strings like std::string or buffers.  Like memcpy, memset (movs/stos), memchr/memrchr (repne scas with DF=0 or 1), and memcmp (repe cmps).  The only C equivalent for repe scas is strspn because I don't think there's a mem function for that.  You can even describe stosw or stosd as wmemset for example.

movzx costs an extra opcode byte, and yes it was only introduced with 386.  It was just easier to type to describe the fact that you're doing a low-byte-merge and assuming it's correctly zero extended.  If you do know CX or at least CH=0, then yes for golfing always go with mov to CL.  But outside of golfing, x86's go-to byte-load instructions are movzx and movsx: they avoid any false dependencies or other partial-register shenanigans.  On modern CPUs with a dword destination, they're as fast as dword mov  loads.

Looking for optimizations, I wonder if we can swap CX and BX so we can use JCXZ instead of test/jz.  That's a tradeoff against not being able to use loop for CX, though.  So probably not worth it.

If you program for 186 instead of 8086/8, you can use push OFFSET T instead of needing BP as a temporary.  push imm8 and push imm16 were new with 186. (https://nasm.us/doc/nasmdocb.html lists when each form of each instruction was introduced.)  I don't think being 8086 compatible is particularly special; a .com executable is still a thing that can run on modern CPUs (under a 16 or 32-bit kernel).

@PeterCordes interesting... using CX instead of BX.  I can play around a little bit there and see.  I would have to zero CL since it's pretty much guaranteed to be FF. What's bugging me the most is those three byte SUB BX, 3 and TEST BL, 1 but I can't find a way around that doesn't end up costing another byte somewhere else!

You don't have a 1 or odd number in another register, do you?  Maybe if one of your static addresses in a register has bit 0 set and bit 1 clear, you could test bx, ??  and use jp to distinguish 0, or 2 from 1, or 3.  (You need the 2nd bit cleared for the other AND/TEST input otherwise the parity won't distinguish 0b01 from 0b10.  And you know BL <= 3 so you don't care about any higher bits in the static address.)  But IDK if that even helps; you have different static addresses floating around in regs at different times.  But you could hoist a mov bp, ... out of one branch maybe.

05AB1E, 61 56 53 52 51 bytes
γvyDg;LàäRv… ‹¶½¿#ygè“Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“#yè])áðý

-9 bytes thanks to @Grimy.
Try it online or verify all test cases.
Explanation:
γ               # Split the (implicit) input into substrings of equal adjacent characters
                #  i.e. "199999991779" → ["1","9999999","1","77","9"]
 v              # Loop over each substring `y`:
   Dg           #  Get the length of a copy of the substring
     ;          #  Halve it
      L         #  Create a list in the range [1, length/2], where odd lengths are
                #  automatically truncated/floored
                #   i.e. "1" (length=1) → 0.5 → [1,0]
                #   i.e. "9999999" (length=7) → 3.5 → [1,2,3]
       à        #  Pop and push the maximum of this list
  y     ä       #  Divide the string into that many parts
                #   → ["1"]
                #   → ["999","99","99"]
         R      #  Reverse the list
                #   → ["99","99","999"]
  v             # Inner loop over each item `y`:
   … ‹¶½¿       #  Push dictionary word: "  double triple"
         #      #  Split it on spaces: ["","","double","triple"]
          yg    #  Get the length of the current item `y`
            è   #  And use it to (0-based) index into the list
   “Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“
                #  Push dictionary string "oh two three four five six seven eight nine"
     #          #  Split it on spaces: ["oh","two","three",...,"nine"]
      yè        #  Use `y` to index into the string-list (with automatic wrap-around,
                #  so since there are 10 words, it basically indexes with a single digit
                #  due to an implicit modulo-10)
                #   i.e. "77" → "seven"
 ]              # Close both loops
  )             # Wrap all values on the stack into a list
   á            # Only keep letters, which removes the empty strings from the list
    ðý          # And join the list on spaces
                # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why … ‹¶½¿ is "  double triple" and “Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“ is "oh two three four five six seven eight nine".

@Grimy Ah, of course.. I added the if(length>=4) before adding the rest, but of course it isn't necessary for integers of size 1,2,3, because the ;Å2¨3ª£ will leave the strings intact (merely wrapped in a list we flatten after the map anyway). Thanks for noticing! And looking forward seeing your answer with Åγ. I indeed had the feeling the first part could be done a lot shorter somehow.

Here's my current best. Åγ didn't turn out as great as I thought; a better score might be possible by golfing your approach instead.

@Grimy Not as short as I thought, but yours is still shorter than mine, so obvious +1. I like the single string with added 10/12 indices for the double/triple. Out of curiosity though, why the work-around ¸» when a simple ðý suffices? ;)

It's actually 11 for triple, not 12. Why ðý when ¸» does the job? ðý is a rigid two-byter, while ¸» offers golfing opportunities if you can wrangle the rest of the code such that ¸ is not necessary.

@Grimy Ah, the 12 was a typo.. And I personally tend to use the most straight-forward approach if byte-counts are the same anyway (unless an equal-bytes but less straight-forward approach is a huge improvement for performance). I personally think using "push space, join by it" is easier to understand for someone reading through the docs than "wrap list in list, join each inner-most list by spaces, and then those strings by newlines (but since there is only a single inner string, no newlines are added)". ;) But feel free to use whatever you'd want; everyone has their own coding style of course.

@Grimy Ah, yн to y is an obvious one I forgot.. >.> But āÉ¨Å¡JõK is pretty weird I wouldn't have come up with, thanks! Weird how Å¡ transforms it to a list of characters, though.. I personally think it's a bug for strings tbh.

Dg;LàäR is still a byte shorter than āÉ¨Å¡JõK, and much more similar to what you originally had.

@Grimy Ah, that's indeed closed to what I initially had indeed, I like it. :) Thanks again!

@Grimy Been able to find one more golf myself which I forgot about.. á instead of õK at the end. :)

Nice find with á! Here's a 51 and another one. 50 feels possible.

@Grimy Ah, nice nested loop. And too bad three contains two adjacent ee, otherwise I could have used ]ðýÔ instead to save that byte. ;)

I did find a few 50s in the end!

@Grimy 49 even, nice!

QuadR, 137 bytesSBCS
Title case with a leading space.
∊¯2↑¨@(∊∘⎕A)⍵
(.)\1*
{⍺←(,¨⎕D)⎕R('OhOneTwoThreeFourFiveSixSevenEightNine'(∊⊂⊣)⎕A)⋄' '∊w←⍺,⊃⍵:⍬⋄1=≢⍵:⍺⍵⋄3=≢⍵:'Triple',w⋄'Double',w,∇2↓⍵}⍵M

Try it online!
∊ ϵnlist (flatten)
¯2↑¨ take the last two characters (padding on left with a space) of each characters
@ at positions where
(∊∘⎕A) characters are members of the uppercase Alphabet
⍵ in the result of the below PCRE Replace operation…
(.) any character
\1 followed by itself
* zero or more times, is replaced by the result of the following…
{…}⍵M "dfn"; ⍵ is the Match of the above pattern
 ('OhOneTwoThreeFourFiveSixSevenEightNine'(…)⎕A) apply the following anonymous tacit function with the long string and the uppercase Alphabet as left arguments:
 ∊ membership (of letters in the long string in the uppercase alphabet)
 ⊂ partitions (with a new partition beginning whenever is-a-member
 ⊣ the left argument (i.e. the long string)
(…)⎕R PCRE Replace the following patterns with those words:
 ⎕D the digits 0 through 9
 ,¨ treat each as a separate pattern
⍺← assign this replacement function to ⍺ (for alphabetise)
⋄ then,
⊃⍵ the first character of the match
, as a string
⍺ apply ⍺ to it
w← assign this to w (for word)
' '∊…: if space is a member thereof (i.e. if the match was empty):
 ⍬ return nothing (becomes the empty string)
⋄ else,
1=≢⍵: if one equals the tally of characters in the match (i.e. its length):
 ⍺⍵ alphabetise that digit
⋄ else,
3=≢⍵: if three equals the tally of characters in the match (i.e. its length):
 'Triple',w prepend "Triple" to the word
⋄ else,
2↓⍵ drop to digits from the match
∇ recurse on that
w, prepend the word
'Double', prepend "Double"

JavaScript (ES6),  161 160 152  144 bytes
The output includes a single leading space.
s=>[n=>' '+'oh/one/two/three/four/five/six/seven/eight/nine'.split`/`[n],'$1 double$2','triple$2'].map(r=>s=s.replace(/(\S*)( \S+)\2|\d/g,r))&&s

Try it online!
or See the formatted source code
How?
The conversion is processed in three steps:

replace each digit with the corresponding English word, preceded by a space
replace each pattern "X X" with "double X"
replace each pattern "double X X" with "triple X"

To save bytes, we use the same regular expression for all steps:
/(\S*)( \S+)\2|\d/g

which works as follows:
(\S*)  -> 1st capturing group: any word, or nothing at all
( \S+) -> 2nd capturing group: a space, followed by a word
\2     -> a copy of the 2nd capturing group
|\d    -> or try to capture a digit instead (for step 1)

At step 1, we use a callback function that picks the correct word from a lookup table:

"799999" → " seven nine nine nine nine nine"

At step 2, we replace with "$1 double$2":

" (seven)( nine)( nine)" → " seven double nine"
"( nine)( nine) nine" → " double nine nine"

At step 3, we replace with "triple$2":

" (double)( nine)( nine)" → " triple nine"

Wolfram Language (Mathematica), 115 bytes
{Switch[L=Tr[1^{##}],1," ",3," triple ",_," double "],If[#<1,"oh",IntegerName@#],If[L>3,#0@##3,""]}&@@@Split@#<>""&

Try it online!
Takes a list of digits as input. Output includes a leading space.

Stax, 56 bytes
ÇÖ◘⌡¿╒ô╞Γ▓8m☻t7♦3├(Ä⌂≤(┬Ω☻9▲ç╕C╞⌡òσ╗─╣╥─☻╪▼⌡5■ÿ,(┬¥?☺÷•±

Run and debug it

Python 2, 171 169 168 bytes
s=input()
while s:c=s[0];n=(s[1:2]==c)+(s[:3]==c*3!=s[1:4]);print'   eellpbiurotd'[-n:0:-2]+'oh one two three four five six seven eight nine'.split()[int(c)],;s=s[1+n:]

Try it online!
-1 byte, thanks to Jitse

Beat me again! Save 1 byte like so

@Jitse, that doesn't work for 1312 ;)

Ah, you're right!

How about this one then: ['','double ','triple '][n] to '   eellpbiurotd'[-n:0:-2] for 168 bytes: Try it online!

Alternatively, also 168 bytes

Scala, 213 bytes
Got it. Somehow the recursive version I was trying to build was strongly more verbose-y than this one (still recursive though, but only in one case). Function f takes as an input string the phone number and outputs its phonetics with a trailing whitespace.
var u="oh one two three four five six seven eight nine" split " "
"(.)\\1*".r.replaceAllIn(s,x=>{var o=x.matched
var k=u(o(0)-48)+" "
o.length match{case 3=>"triple "+k
case 1=>k
case _=>"double "+k+f(o drop 2)}})

Try it online!
Edit : -8b thanks to DrY Wit!
Scala, 215 bytes
And here comes the leading whitespace version, two bytes longer for some reason (even with massive refactoring).
var u="oh one two three four five six seven eight nine" split " "
"(.)\\1*".r.replaceAllIn(s,x=>{var o=x.matched
var k=u(o(0)-48)
" , double , triple ".split(",")(if(o.length>3){k+=f(o drop 2);1}else o.length-1)+k})

Try it online!

You can save 8 bytes by replacing (o(0)+"").toInt with o(0)-48.

Oof well done @DrYWit thanks!

PHP, 174 169 166 159 bytes
for(;$s=strspn($argn,$d=$argn[$i],$i++);$s==3?($i+=2)+print'triple ':$s<2?:++$i+print'double ',print[oh,one,two,three,four,five,six,seven,eight,nine][$d].' ');

Try it online!
For each digit at index of $i starting from 0:

If span of the same digit starting from location of $i is equal to 3, prints 'triple ' and adds 2 to $i so next iteration will have 2 digits jumped over.
If span of the same digit starting from location of $i is equal to or more than 2 but is not 3, prints 'double ' and adds 1 to $i so next iteration will have 1 digit jumped over.
Prints word for the digit and a space.
$i++.

Perl 5 -p, 111 bytes
s/(\d)\1/ double$1/g;s/\w+(\d)\1/triple$1/g;s/\d/' '.qw(oh one two three four five six seven eigth nine)[$&]/ge

Try it online!
Explanation:
s/(\d)\1/ double$1/g; # Replace non-overlapping double digits with " double<digit>"
s/\w+(\d)\1/triple$1/g; # Replace remaining double digits preceded by "double" with "triple<digit>"
s/\d/' '.qw(oh one two three four five six seven eigth nine)[$&]/ge # Replace digits with " <word>"

Shaved a few bytes off: 106

C++, 382 bytes
It's not superclever, but someone needed to write a C++ version.  The recursive function R goes through the input string and counts repeated values. If there are more than 3 repeats, it pretends there were 2 repeats, then rewinds and tries again.
A few more source chars could probably be squeezed out with #define major, but I'm sure a better algo could squeeze out more.
#include <iostream>
#include <sstream>
using namespace std;
char*n[]={"oh","one","two","three","four","five","six","seven","eight","nine"};
void R(ostream& s,const char*r,char p='x',int c=0){if(*r==p)R(s,r+1,p,c+1);else
{if(c>1){if(c>= 4){s<<"double ";r-=(c-2);}else if(c==3)s<< "triple ";else if(c==2)s<< "double ";
}if(c >0)s<<n[p-'0']<<" ";if(!*r)return;R(s,r+1,*r,1);}}

void check(const char* in, const char* out)
{
    std::stringstream ss;
    R(ss,in);
    if (out == ss.str()) std::cout << "PASS: "; else std::cout << "FAIL! ";
    std::cout << in << "\n< " << out << "\n> " << ss.str() << std::endl;
}

int main(int c,char**argv)
{
    if (argv[1] == std::string("test"))
    {
        check("0123"         ,"oh one two three ");
        check("4554554"      ,"four double five four double five four ");
        check("000"          ,"triple oh ");
        check("00000"        ,"double oh triple oh ");
        check("66667888"     ,"double six double six seven triple eight ");
        check("19999999179"  ,"one double nine double nine triple nine one seven nine ");
    }
    else
    {
        char* v = argv[1];
        R(std::cout,v);
        std::cout << std::endl;
    }
}

and verification of test cases:
pa-dev01$ ./a.out test
PASS: 0123
< oh one two three
> oh one two three
PASS: 4554554
< four double five four double five four
> four double five four double five four
PASS: 000
< triple oh
> triple oh
PASS: 00000
< double oh triple oh
> double oh triple oh
PASS: 66667888
< double six double six seven triple eight
> double six double six seven triple eight
PASS: 19999999179
< one double nine double nine triple nine one seven nine
> one double nine double nine triple nine one seven nine

Does the golfed part actually need #include <sstream>?  Or could you move that down after the golfed part for the test function?  I think typing std::ostream&s would take less space than using namespace std;, unless there are other places where you'd need a std::.

253 bytes

Perl 6, 96 93 bytes
{S:g/(.)$0?[$0{}<!$0>]?/{(<triple double>X$)[3-$/.comb]}{+$/??uniname(~$0).words[1]!!'oh'} /}

Try it online!
This is an anonymous code block that takes a number and returns a string with the numbers in uppercase, e.g. 0123 => oh ONE TWO THREE with a single trailing space.
This was deleted for a while until I found out how to use captures in a lookahead, but it should be fixed now.

T-SQL 2017, 238 bytes
Added some linebreaks to make it readable
WHILE''<left(@,1)SELECT @=stuff(@,1,iif(p<4,p,2),'')+
iif(p=1,' ',iif(p=3,' triple ',' double '))
+trim(substring('oh  one  two  threefour five six  seveneightnine',left(@,1)*5,5))
FROM(SELECT~-patindex('%[^'+left(@,1)+']%'+'^',@)p)z
PRINT @

Try it online

Retina 0.8.2, 105 bytes
+`(.)\1
=$1
.
 $&
= =
triple
=
double
9
nine
8
eight
7
seven
6
six
5
five
4
four
3
three
2
two
1
one
0
oh

Try it online! Outputs a leading space. Explanation: I originally tried a regex that automatically matches 2 or 3 digits but @Arnauld's approach of turned out to be golfier. Explanation:
+`(.)\1
=$1

Match pairs of identical digits and replace the first with a =. Then repeat, so that for an odd number the second last digit is also replaced with a =.
.
 $&

Space the digits (and =s) out.
= =
triple

Handle the case of three identical digits.
=
double
9
nine
8
eight
7
seven
6
six
5
five
4
four
3
three
2
two
1
one
0
oh

Replace all remaining characters with words.

Jelly, 59 bytes
⁵;`,0;$Ɗ€Ẏ;`Ø0ṭ;-œṣjƭƒV€‘$ị“¡ıc⁴Ṛ⁽]@ɱ2¦Ż©Ẉḷ$Æ!)ɗ[ı8ɱḃ%ċ»Ḳ¤K

Try it online!
A monadic link that takes a string of digit characters as its argument and returns a Jelly string of space-separated words. When called as a full-program, outputs implicitly.

JavaScript, 142 bytes
s=>s.replace(/(.)(\1\1(?!\1)|\1|)/g,t=>(t[2]?' triple ':t[1]?' double ':' ')+'oh one two three four five six seven eight nine'.split` `[t[0]])

Try it online!

(Roblox) Lua 5.1, 166 bytes
for I,N in('111 triple 11 double 1 '):gmatch'(%d+)(%D+)'do for i,n in('0oh1one2two3three4four5five6six7seven8eight9nine'):gmatch'(.)(%l+)'do s=s:gsub(i*I,N..n)end end

Ensure s is a predefined string value populated only with digits; that will be the variable to be modified.  The result will include a leading space [\u20] character.

Welcome to the site! As Lua can take input via standard methods, it's against the rules to require s to already have the input. Aside from that, you've got a good first post! I would recommend you include a link to an online testing site e.g. https://tio.run/#lua so that others can test your solution

Hi.  The variant of Lua I was testing on (Rbx.Lua) doesn't contain input methods, although the sandbox has print, warn, and error output methods.

Red, 242 bytes
func[s][b:[copy t skip t]parse s[any[change[b t ahead not t](rejoin["triple "t])|
change b(rejoin["double "t])| skip]]foreach c s[prin either i:
find"0123456789"c[rejoin[pick[:oh:one:two:three:four:five:six:seven:eight:nine]index? i" "]][c]]]

Try it online!

Scala, 253 bytes
def g(s:String):String={val t="oh one two three four five six seven eight nine".split(" ")(s(0)-48)
s.length match{case 3=>"triple "+t;case 2=>"double "+t;case 1=>t;case _=>"double "+t+" "+g(s drop 2)}}
s=>"(.)\\1*".r.findAllIn(s).map(g(_)) mkString " "

Try it online!

Oracle SQL, 578 bytes (in formatted form)
Solution is not concise by any means so posting it in formatted way.
with r(s) as
(select x from t
  union all
 select case
           when length(regexp_substr(s, '(.)(\1)+')) = 3
           then regexp_replace(s, '^...')
           else regexp_replace(s, '^(.)\1|^.')
        end
   from r
  where s is not null)
select listagg(decode(length(r),  2, 'double ',  3, 'triple ') ||
               decode(substr(r, 1, 1), 0, 'oh', to_char(to_date(substr(r, 1, 1), 'j'), 'jsp')), ' ')
               within group (order by rownum)
  from (select regexp_replace(s, lag(s) over (order by length(s)) || '$') r
          from r order by length(s) desc);

Test in SQL*Plus
SQL> create table t(x) as select /*'45547777777774'*/ '1999999910079' from dual;

Table created.

SQL> set pages 0
SQL> with r(s) as
  2  (select x from t
  3    union all
  4   select case
  5             when length(regexp_substr(s, '(.)(\1)+')) = 3
  6             then regexp_replace(s, '^...')
  7             else regexp_replace(s, '^(.)\1|^.')
  8          end
  9     from r
 10    where s is not null)
 11  select listagg(decode(length(r),  2, 'double ',  3, 'triple ') ||
 12                 decode(substr(r, 1, 1), 0, 'oh', to_char(to_date(substr(r, 1, 1), 'j'), 'jsp')), ' ')
 13                 within group (order by rownum)
 14    from (select regexp_replace(s, lag(s) over (order by length(s)) || '$') r
 15            from r order by length(s) desc);
one double nine double nine triple nine one double oh seven nine

The main trick is that digits converted into words using Oracle format models instead of hard-coded literals "one" ... "nine".

any chance of this getting golfed ? it seems you can remove a bunch of spaces. I also imagine you can rewrite WHERE s is not null to WHERE s>''

You can save a few characters by replacing what’s after union all with select regexp_replace(s,case when length(regexp_substr(s, '(.)(\1)+')) = 3 then '^...' else '^(.)\1|^.' end) from r.

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


text:
Create the least compressible picture
"A picture is worth a thousand words"—so the old saying goes. The average word is about four characters long, so a picture conveys 4kB of information. But how much entropy, rather than information, can a picture convey?
Your task is to generate an image, exactly 4,000 bytes in size, with the highest entropy possible. You may use any language, libraries, or image format you choose, and you may output to the console or to a file so long as you upload your image here.
Scoring
Your score is the compression ratio (4000 ÷ compressed size) when your image is compressed with GNU tar version 1.28 and gzip version 1.6, using the DEFLATE algorithm and default settings — specifically, the command tar -czvf out.tar.gz image. The smallest compression ratio wins.

tar includes metadata, including mtime, in output files by default. This affects the final compressed file size - some mtimes compress better than others. Changing the command to gzip -n image would make the output size deterministic regardless of mtime (and input file name).

Never mind, gzip -n image cannot produce a file larger than 4023 bytes given a 4000-byte input. It needs 10 bytes for the header, 8 for the footer, 1 for the DEFLATE block header and padding, and 4 for the DEFLATE block size; the rest are just stored as uncompressed bytes. Most files comprised of random bits are stored uncompressed, as they should be.

I can confirm that. Instead of compression getting worse with increasing entropy, it just flags that the data should be stored uncompressed. Deflate adds 2 bytes to the data. Gzip adds the rest.

0.9514747859 (4204-byte output)

Note: the image above is not the actual file I used, but it is the image.
Here is a hexdump of the file: https://gist.github.com/pommicket/cf2982e8ecf09a4de89d3a849526c64b
The file is in the netpbm format, and can be generated with this C code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "Please pass in seed.\n");
        return EXIT_FAILURE;
    }
    srand(atoi(argv[1]));
    FILE *fp = fopen("image.pgm", "w");
    int width = 2, height = 1993;
    fprintf(fp, "P5 %d %d 255 ", width, height);
    for (int i = 0; i < width * height; i++) {
        fputc(rand() & 0xFF, fp);
    }
    fclose(fp);
    return 0;
}

The random seed must be passed into the program. After trying some seeds, I got one which produced a 4204 byte gzipped file. As Nnnes pointed out, tar will include metadata in the file, so your results might differ from mine.
netpbm isn't supported everywhere, but it works with imagemagick's convert (so just do convert image.pgm image.png to turn it into a png).
Why this image/format?
A file which consists of entirely random bytes is very hard to compress (in fact, any possible compression algorithm will do on average, no better than not compressing for random files). The content of the actual file is just P5 2 1993 followed by 3986 random bytes, which is why gzip has such a hard time compressing it.

@KrzysztofSzewczyk it’s not about the seed, it’s about the image format. Your PNGs’ headers include a lot of deterministic bytes, so they compress easily.

@KrzysztofSzewczyk There's potentially much more than 8 bytes of non-random data in a random PNG file. The bare minimum is to include the file signature followed by the IHDR, IDAT and IEND chunks, but most PNG generators will include a couple of optional chunks that are likely to compress pretty well -- as Grimy said -- except maybe the CRC's that can be assumed to be pretty random.

The file you generated has 4KB of entropy, but the image doesn't. (Even the PNG has 785 bytes!) You're filling it with 3990 random bytes, but it's only displaying 3990 random bits, so it can be reduced to this 542-byte PBM file: https://gist.github.com/Nnnes/7026b7ff3d55a36bdbb01c3582beb80a - Rows in PBM are padded to the end of the byte, so there are a bunch of 0 bits every 14th (though still not enough for gzip to pick up on them, as it works on the byte level). 336 x 95 works for 3990 * 8 bits. [Also see my comment on the main post - the different sizes are not a result of different seeds.]

@Nnnes Good point! I switched to using a pgm file. The png is now >5000 bytes. If it's not the seed that's changing the size of the output, I'm not sure what in the metadata is doing that, because the file name was the same every time...


text:
Lípínguapua dopo Pêpê
Língua do Pê, or P Language, is a language game spoken in Brazil and Portugal with Portuguese. It is also known in other languages, such as Dutch and Afrikaans. (Wikipedia)
There are some dialects in this language game. The different languages the game is played with even have their own unique dialects. Some people are fluent in speaking P Language and the best can even translate any text to their preferred dialect on the spot!
P Language
In this challenge, we will use the Double Talk dialect.
To translate text into P Language, any sequence of vowels in the text is appended with a single p character followed by a copy of the sequence of vowels.
Challenge
Write a function or program that accepts a string as input and outputs its translation in P Language.

The input consists only of printable ASCII characters.
The output consists only of the translated input and optionally a trailing newline.
Vowels are any of the following characters aeiouyAEIOUY.
A sequence of vowels is delimited by any other character. The string "Aa aa-aa" has three vowel sequences.
Leading and trailing whitespace may optionally be omitted from the translated output string.

Examples
""                              =>   ""
"Lingua do Pe"                  =>   "Lipinguapua dopo Pepe"
"Hello world!"                  =>   "Hepellopo woporld!"
"Aa aa-aa"                      =>   "AapAa aapaa-aapaa"
"This should be easy, right?"   =>   "Thipis shoupould bepe eapeasypy, ripight?"
"WHAT ABOUT CAPS?"              =>   "WHApAT ApABOUpOUT CApAPS?"
"   Hi "                        =>   "   Hipi " or "Hipi"

The double quotes character " is used to delimit the input and output strings in the examples but obviously this character may also appear in any valid input string.

I'm not sure if anyone has welcomed you to the stack yet, so: welcome to Code Golf Stack Exchange! Nicely specified first challenge. :-)

@Giuseppe Thanks for the kind words!

Also in Spanish https://es.wikipedia.org/wiki/Jerigonza

JavaScript (ES6), 35 bytes
s=>s.replace(/[aeiouy]+/gi,'$&p$&')

Try it online!
Where the special replacement pattern $& means matched substring.

I did not know about $&.  All these years, I've been wrapping the whole regex in a capture group.  Who said code golf is impractical?!

Is $& the more common way? In Java it's $0 a.f.a.i.k., and Retina allows both. Didn't knew $& came from JavaScript. Or is it a .NET flavored regex, and JavaScript also uses it?

Sed, 30, 25, 21, 19 Bytes
-5 Bytes Thanks to Arnauld!
-4 Bytes Thanks to Shaggy!
-2 Bytes Thanks to Leo Tenenbaum!
s/[aeiouy]\+/&p&/gi

Try it Online!

19 bytes: https://tio.run/##BcGxCsIwEAbg/Z7id@mikkco0SWDYMEUB3U4yZEcBCONofTp4/dVCb1X82DR0rbXc2@G72Ci9k4X/cTGCAWTkJOcC9ay5LAjy2A@MpNPWlFTaTngLRCu2wGLxvQb6e6shz1dZ4@znW4jAXCKPw

Japt, 10 bytes
r"%y+"_+ip

Try it
r"%y+"_+ip     :Implicit input of string
r              :Replace
 "%y+"         :RegEx /[aeiouy]+/gi
      _        :Pass each match through a function
       +       :  Append a copy of the match
        ip     :  Prepended with "p"

Darn it, 2 minutes too late! I had the exact same answer, except it used Japt 2.0 short regexes "%v" -> \v

@EmbodimentofIgnorance, you'd need \y instead of \v.

Java 8, 40 bytes
s->s.replaceAll("(?i)[aeiouy]+","$0p$0")

Try it online.
Explanation:
s->                              // Method with String as both parameter and return-type
  s.replaceAll("(?i)[aeiouy]+",  //  Replace the regex matches
               "$0p$0")          //  With this replacement

Regex explanation:
(?i)[aeiouy]+                    // MATCH:
(?i)                             //  Enable case insensitivity
            +                    //  Match one or more
    [aeiouy]                     //  Adjacent vowel characters

$0p$0                            // REPLACEMENT:
$0                               //  The entire match (the vowel 'sequence')
  p                              //  Appended with a literal "p"
   $0                            //  Appended with the entire match again

Perl 5 -p, 20 bytes
s/[aeiouy]+/$&p$&/gi

Try it online!

Python 3, 55 bytes
lambda s:re.sub('([aeiouy]+)',r'\1p\1',s,0,2)
import re

Try it online!

Sans regex:
Python 3, 101 bytes
def f(s,q=''):i=s[:1];t=i in{*'aeiouyAEIOUY'};return(q+(q!='')*'p'+q+i)*0**t+(s and f(s[1:],(q+i)*t))

Try it online!
Python 3.8 (pre-release): 99 bytes
Explanation
Recursive function, accepting a string s and an optional argument q. If the first character of s (i) is a vowel, it is stored in the queue q. If not, a string is returned which is composed of q, the letter 'p', q again, the character i and the result of the recursive function with the first character of the string stripped off. Recursion stops when the function encounters an empty string s.

Love the solution without regex!

05AB1E, 22 20 bytes
.γžÁyå}vyžÁyнåi'py}J

05AB1E doesn't have any regexes unfortunately.
I don't really like the duplicated žÁyнå, but I'm currently a bit too busy to look for alternatives..
-2 bytes thanks to @Grimy for showing me a constant I didn't even knew existed (and was missing from the Wiki page.. >.>)
Try it online or verify all test cases.
Explanation:
.γ               # Group the characters in the (implicit) input-string by:
  žÁ             #  Push vowels builtin: "aeiouyAEIOUY"
    yå           #  And check if the current character is in this string
 }v              # After grouping: loop over each group `y`:
   y             #  Push group `y`
    žÁyнåi   }   #  If the first character of the group is a vowel:
          'p    '#   Push a "p"
            y    #   And push group `y` again
              J  #  Join everything on the stack together to a single string
                 # (after the loop, implicitly output the result)

žÁ instead of žO lets you drop the l.

@Grimy Maybe I should start using the info.txt file instead of the Wiki page.. -_-'

They're both missing lots of commands, though not the same ones (hopefully. Sometimes I wonder if there are secret commands missing from both).

@Grimy Yeah, maybe we should use the source code instead of the info.txt or Wiki pages. ;)

Retina 0.8.2, 17 bytes
i`[aeiouy]+
$&p$&

Try it online! Link includes test cases. Explanation: Trivial regexp approach; the i flag turns on case insensitivity (Retina already defaults to a global match).

Red, 92 bytes
func[s][v: charset"aeiouyAEIOUY"parse s[any[to v copy t any v insert(rejoin["p"t])| skip]]s]

Try it online!
Of course Red's Parse is much more verbose than regex.

More verbose than regex for sure, but perhaps that makes it more interesting as well. I like it!

@MaartenBamelis Thank you! Yes, Red (like Rebol) is an interesting language.

SNOBOL4 (CSNOBOL4), 97 bytes
	I =INPUT
S	I ARB . L SPAN('AEIOUYaeiouy') . V REM . I	:F(O)
	O =O L V 'p' V	:(S)
O	OUTPUT =O
END

Try it online!
Vowel clusters match SPAN('AEIOUYaeiouy').

Stax, 17 bytes
àº`≈Zö=q╦ⁿ↔èblTï÷

Run and debug it at staxlang.xyz!
Unpacked (20 bytes) and explanation:
Vv'y+c^+:}'++{'pnL}R
                   R    Regex replace using
                        Pattern:
Vv'y+                     Push "aeiou", push "y", and concatenate
     c^+                  Copy, convert copy to all caps, and concatenate
        :}                Enclose in []
          '++             Push "+" and concatenate
                        And replacement:
             {    }       Block:
              'p            Push "p"
                n           Copy second item (matching substring) to top
                 L          Listify
                          Implicit concatenate
                        Implicit print

No case-insensitive regular expressions in Stax, and the vowel builtins don't include Y. The documentation won't tell you about using a block as a replacement, but it's a working feature nevertheless.

Jelly, 20 bytes
Żṁe€ØyŒg$$,j”pƊ€ÐeẎḊ

Try it online!


text:
Chunk + Enumerate a list of digits
I have a list of decimal digits:
4, 4, 4, 7, 7, 9, 9, 9, 9, 2, 2, 2, 4, 4
The list of decimal digits are known as items. We can form "chunks" from these items by grouping together identical and adjacent numbers. I want to assign each chunk a unique number, starting from 1, and increasing by 1 in the order the chunks appear in the original list. So, the output for the given example would look like this:
1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5
Input format
A list of digits. (0-9) You may use your language built-ins to read this list however you want. Encoding: ASCII
Output format
A series of decimal numbers, separated by a delimiter. Your program must always use the same delimiter. The delimiter must be longer than 0 bits. Encoding: ASCII
Standard loopholes apply.

Any particular reason for the strict input and output format?

@UnrelatedString Hmm, I shall loosen them.

Can the output start from 0 instead?

@EmbodimentofIgnorance No.

Can we start the output sequence from 0? Can we output a 2D-array?

@Shaggy Embodiment just asked about 0 and was answered!

@Adám: Ah, hadn't refreshed. Thanks.

The IO is still rather strict. Can't you just say "input and output is as a list" and let the site defaults take care of it for you?

Can we assume the list is non-empty?

"The delimiter must be longer than 0 bits" — probably bytes? Because (ASCII) character is a byte, not a bit!

@JoKing edited!

You only changed the input section and not the output part

@JoKing outputting with stuff before or after is allowed

I don't understand why you keep going on about delimiters. Are you implying that we have to be outputting to STDOUT, or that functions have to return a string? If not, then why not just simplify it and just say "Input is a list of digits"

@JoKing Delimiters are not mentioned in the input section. The output or its string representation must have delimiters by definition because the number of chunks can exceed 9, and be multi-digit.

A list by definition has delimiters already. That's why it's a list. I also don't understand what you mean by You may use your language built-ins to read this list however you want.. Does that mean we have to include a string to list converter in our submission? And are we allowed to output as a list?

Python 3.8 (pre-release), 41 bytes
lambda l,n=0:[n:=n+(l!=(l:=x))for x in l]

Try it online!
Praise the magic walrus := of assignment expressions.

Python 2, 42 bytes
n=0
for x in input():n+=x!=id;id=x;print n

Try it online!

Hmm, how long would this be in Pyth?

Huh, I avoided id because it's 2 bytes long...

Oof nice idea of id

@noɥʇʎԀʎzɐɹƆ 8 bytes for a straightforward translation: Try it online!

Python 2, 44 bytes
l=input()
n=0
for i in l:n+=i!=l;l=i;print n

Try it online!

APL (dzaima/APL), 7 bytesSBCS
Anonymous tacit prefix function. Prints space-separated.
+\1,2≠/

Try it online!
2≠/ pair-wise inequality
1, prepend 1
+\ cumulative sum

Jelly, 6 5 bytes
ŒɠµJx

Try it online!
Saved one byte thanks to UnrelatedString!
Inputs and outputs as array's (with opening/closing brackets)
How it works
ŒɠµJx - Main link, takes one argument:                       [7, 7, 5, 5, 5, 1]
Œɠ    - Get the lengths of consecutive elements:             [2, 3, 1]
  µ   - Call these lengths A
   J  - range(length(A))                                     [1, 2, 3]
    x - Repeat each element by the corresponding value in A: [1, 1, 2, 2, 2, 3]

5 bytes

@UnrelatedString all these new-fangled atoms!

Jelly, 4 bytes
ŒgƤẈ

Try it online!
How?
ŒgƤẈ - Link: list of integers  e.g. [7,7,2,7,7]
  Ƥ  - for prefixes:     [7]   [7,7]   [7,7,2]      [7,7,2,7]        [7,7,2,7,7]
Œg   -   group runs      [[7]] [[7,7]] [[7,7],[2]]  [[7,7],[2],[7]]  [[7,7],[2],[7,7]]
   Ẉ - length of each    [1,   1,      2,           3,               3]

05AB1E, 4 bytes
γdƶ˜

Try it online!
γ       # group adjacent equal digits together
 d      # replace all digits with 1
  ƶ     # multiply each group by its 1-based index
   ˜    # flatten

I keep forgetting that 05ab1e has that ƶ... +1

Here an alternative 4-byter: ηεγg

R, 33 bytes
function(x)cumsum(c(1,!!diff(x)))

Try it online!
Uses the same cumulative sum method as Luis Mendo and others.

MATL, 8 bytes
Y'wn:wY"

Try it online!
Explanation:
    Y'      % run-length encoding
    w       % swap elements in stack
    n       % number of elements in array / size along each dimension
    :       % range; vector of equally spaced values
    w       % swap elements in stack
    Y"      % replicate elements of array
            % (implicit) convert to string and display

Oracle SQL, 121 bytes
select m from t match_recognize(order by i measures match_number()m all rows per match pattern(p+)define p as x=first(x))

Test in SQL*PLus.
SQL> with t(i,x) as (select rownum,value(v) from table(sys.odcinumberlist(4, 4, 4, 7, 7, 9, 9, 9, 9, 2, 2, 2, 4, 4))v)
  2  select m from t match_recognize(order by i measures match_number()m all rows per match pattern(p+)define p as x=first(x))
  3  /

         M
----------
         1
         1
         1
         2
         2
         3
         3
         3
         3
         4
         4
         4
         5
         5

14 rows selected.

JavaScript (ES6), 30 bytes
Takes input as an array of integers.
a=>a.map(p=n=>i+=p!=(p=n),i=0)

Try it online!
Commented
a =>                // a[] = input array
  a.map(p =         // initialize p to a non-numeric value
  n =>              // for each value n in a[]:
    i +=            //   increment i if:
      p != (p = n), //     p is not equal to n; and update p to n
    i = 0           //   start with i = 0 (chunk counter)
  )                 // end of map()

Octave / MATLAB, 25 bytes
@(x)cumsum([1 ~~diff(x)])

Try it online!

Wolfram Language (Mathematica), 29 bytes
Join@@(i=1;0#+i++&/@Split@#)&

Try it online!

05AB1E, 5 bytes
¥Ā.¥>

Try it online!

Minor 5-bytes alternative: ¥Ā could also be üÊ.

4 bytes

Haskell, 40 bytes
f(a:t)=1:map(+sum[1|a/=t!!0])(f t)
f e=e

Try it online!

Perl 6, 21 bytes
{+<<[\+] $,|$_ Zne$_}

Try it online!
Anonymous code block that takes a list and returns a list. This works by comparing whether each pair of adjacent elements are not equal, than taking the cumulative sum of the list.

J, 12 bytes
1+/\@,2~:/\]

Try it online!
Similar to Adám's APL answer
      2~:/\]  - pair-wise inequality
1    ,        - prepend 1
    @         - and
+/\           - find the cumulative sum

Pyth, 13 11 bytes
s.e*]hkhbr8

Try it online!
         r8  # Run-length encode (implicit argument is the input) (-> [[frequency, char], ...]
 .e          # Enumerated map (current element is b, index is k) over rQ8
   *]hk      # [ k+1 ] *
       hb    #           b[0]
s            # Reduce list on + ([a]+[b] = [a,b])

-2 bytes thanks to Mr. Xcoder

hMsM._+0nVt for -2 bytes.

Or if you want to keep your approach, rQ8 is the same as r8 and .n can be s for -2 as well

Ah nice, the docs didn't mention what functions take an implicit Q

Scala, 114 bytes
s.split(", ").zipWithIndex.scan(s.head,0){(a,b)=>if(a._1==b._1)a else b._1->(a._2+1)}.tail.unzip._2.mkString(", ")

Try it online!

Scala, 75 bytes
s=>s.scanLeft(("",0))((x,y)=>(y,x._2+(if(x._1!=y)1 else 0))).tail.map(_._2)

Try it online!
If input and output must be comma separated String (and not List) then 102 bytes.
s=>s.split(", ").scanLeft(("",0))((x,y)=>(y,x._2+(if(x._1!=y)1 else 0))).tail.map(_._2).mkString(", ")

C (gcc), 62 bytes
f(_,l)int*_;{printf("%d ",l=--l?f(_,l)+(_[l]!=_[l-1]):1);_=l;}

Try it online!
A function that takes the list and its length as arguments.

C (gcc), 60 bytes
f(_,l)int*_;{_=printf("%*d",--l?f(_,l)+(_[l]!=_[l-1]):2,0);}

Try it online!
Outputs in unary, delimited by 0s

PHP, 52 bytes
while(''<$d=$argv[++$x])echo$i+=$argv[$x-1]!=$d,' ';

Try it online!
Input via command line, output to STDOUT.
Thx to @Night2 for the pesky '0' == 0 comparison bugfix!

@Night2 good catch!  Updated and fixed.  Thx!

x86-16, 12 bytes
Unassembled listing:
        NUM_LOOP:
AC          LODSB                   ; load [SI] into AL, advance SI
3A C2       CMP  AL, DL             ; is this char same as last?
74 01       JZ   SAME               ; if so, same index
43          INC  BX                 ; otherwise increment index
        SAME:
92          XCHG AX, DX             ; save current char for next compare
8A C3       MOV  AL, BL             ; put index value in AL to store
AA          STOSB                   ; store AL into [DI], advance DI
E2 F4       LOOP NUM_LOOP           ; keep looping

Input is byte array at SI,  length in CX.  Output is byte array at DI.  Of course, this is if default I/O rules apply now.
Example: SI = 120H, DI = 130H

Ruby, 38 bytes
->a{i=0;a.map{|x,y|p i+=(a==a=x)?0:1}}

Try it online!
On the first iteration, a is equal to the input list, so we always increment the chunk count. On subsequent iterations it's equal to the previous element.

Julia 1.0, 56 bytes
l->foldl(l,init=(0,0))do(p,i),c
println(i+=p!=c)
c,i
end

Try it online!

Stax, 10 bytes
▓ª2ªmD?Ä╧╖

Run and debug it
The output uses space as a delimiter.  The input follows the precise specifications using commas as separators, and now enclosing braces.

Perl 5, 27 bytes
s/\d/$i+=$&!=$p;$p=$&;$i/ge

Try it online!
The command line option -p makes perl read the input line from STDIN into the "default variable" $_. It then search-replaces all digits in $_ with the counter $i. And $i is increased for each digit which is different than the previous digit, which it also is at the first digit so the counter starts at 1. The previous digit is stored in $p.

Jelly, 5 bytes
nƝÄŻ‘

Try it online!
I initially aimed for a 4-byter (the same program but without the Ż) but then quickly realized that a 1 had to be prepended every time due to an oversight... Even though there is another 5-byter in Jelly, I'll actually keep this because it uses a different method.
For each pair of neighbouring items of the input list \$L\$, test if \$L_i\ne L_{i+1}, \forall 1\le i<|L|\$ and save these results in a list. Then take the cumulative sum of this list and increment them by 1 to match the chunk indexing system. TL;DR. Whenever we encounter different neighbouring items, we increment the chunk index by 1.

I don't think so?

Haskell, 46 43 bytes
scanl(+)1.map fromEnum.(zipWith(/=)=<<tail)

Try it online!
Anonymous pointfree function that takes a list and returns a list

C (gcc), 62 61 bytes
This is one of the few entries I've done where a complete program is shorter than a function submission!
On the first pass, I don't care about the previous value, so I get to rely on the fact that argv is a pointer to somewhere and is extremely unlikely to be between [0..9]!
s;main(i,j){for(;~scanf("%d,",&i);j=i)printf("%d ",s+=j!=i);}

Try it online!

R, 37 bytes
function(x,r=rle(x)$l)rep(seq(a=r),r)

Try it online!
Not as golfy as this answer, but an alternative method using rep.

Desmos, 65 bytes
L=join(1,1-0^{(l[2...]-l)^2})
f(l)=∑_{n=1}^{[1...L.length]}L[n]

Try It On Desmos!
Try It On Desmos! - Prettified

Factor, 45 bytes
[ 0 f rot [ tuck = rot dup 1 + ? tuck ] map ]

Try it online!

Ly, 29 bytes
1sp&nry[pluy,[',o!]p=!l+spy]p

Try it online!
This one keeps a counter with the chunk number in the backup cell.  That's incremented anytime the current codepoint doesn't match the next one on the list.  The only other trick is the code to conditionally add the , delimiter if there's at least one more codepoint on the stack.
1sp                           - init the chunk number to 1, pop from stack
   &nr                        - read in list of digits as codepoints
      y[p                 y]p - loop as long as the stack isn't empty
         lu                   - load/print the chunk counter
           y,[   !]p          - if/then, true if there's 2+ digits left
              ',o             - print a comma delimiter
                    =!        - push "1" if the top 2 entries are not equal
                      l+sp    - increment chunk counter is digits differ

BQN, 7 bytesSBCS
+`⊢≠π⊸»

Run online!

Arturo, 40 bytes
$[a][p:10i:0map a'x[if p<>x[i:i+1p:x]i]]

Try it
$[a][                  ; a function taking an argument a
    p: 10              ; assign 10 to p
    i: 0               ; assign 0 to i
    map a 'x [         ; map over a; assign current element to x
        if p <> x [    ; if p doesn't equal x...
            i: i + 1   ; increment i
            p: x       ; assign x to p
        ]              ; end if
        i              ; map the current element to i
    ]                  ; end map
]                      ; end function

Zsh, 38 bytes
Hat-tip to @pxeger. Try it online!
n=1;>$1;for i {mv * $i&&((n++));<<<$n}

First we write a file, >$1. Then for every argument $i:
* attempt to rename that file to $i
* if the rename succeeds, increment the chunk number $n
* print $n

50 bytes (old approach)
Compares arguments. Try it online!
  53 bytes
  57 bytes
n=1;set $@ $@[#];for i;echo $[$2==$1?n:n++]&&shift

Thunno 2, 4 bytes
ƒ€ġḷ

Try it online!
Explanation
ƒ€ġḷ  # Implicit input
ƒ     # Prefixes
 €    # To each:
  ġ   #  Group consecutive
   ḷ  # Length of each
      # Implicit output

Nekomata, 4 bytes
pNĉ#

Attempt This Online!
pNĉ#
pN      Nonempty prefix
  ĉ     Chunks of identical characters
   #    Length

Japt v2.0a0, 9 bytes
£T±A¦(A=X

Try it

Add++, 23 bytes
D,f,@*,BGd€bL$bLRz€¦XBF

Try it online!
How it works
D,f,@*,     - Define a function, f, that takes one argument:  [7 7 5 5 5 1]
       BG   - Group neighbouring elements together:           [[[7 7] [5 5 5] [1]]]
       d    - Duplicate:                                      [[[7 7] [5 5 5] [1]] [[7 7] [5 5 5] [1]]]
       €bL  - Get the length of each:                         [[[7 7] [5 5 5] [1]] [2 3 1]]
       $bLR - Length, then range of length:                   [[2 3 1] [1 2 3]]
       z    - Zip together:                                   [[2 1] [3 2] [1 3]]
       €¦X  - Reduce each by repetition:                      [[1 1] [2 2 2] [3]]
       BF   - Flatten:                                        [1 1 2 2 2 3]
            - Due to the * in the function definition,
                 return the whole stack:                      [1 1 2 2 2 3]

Japt, 8 7 bytes
ä¦Ug)åÄ

Try it

Retina 0.8.2, 34 bytes
\b\d+\b(?<=(\b(\3|(\d+))\D*)*)
$#3

Try it online! Explanation:
\b\d+\b

Match each number in turn.
(?<=(...)*)

Start looking backwards for as many matches as possible. (The next entries will be in right-to-left order as that's how lookbehind works.)
\D*

Skip the separators.
(\3|(\d+))

Try to match the same number as last time, but failing that, just match any number, but remember that we had to match a new number.
\b

Ensure the whole number is matched.
$#3

Count the number of new numbers.

Alice, 28 bytes
0wi.hn$@.?-..3&$!h0;./ O \K

Try it online!
Takes the input as a string with no separators, outputs a string separated by new line
Explanations
0                             Initialise the counter at 0 on the stack
 wi.hn$@                  K   Main loop, while there are characters to read on the input
        .?-    $   ;          If the number read is the same as the number on the tape, discard it
           ..3& !h0           Otherwise, store the new number on the tape and increment the counter
                    ./ O \    Print the counter and a new line


text:
An array battle with odd secret powers
Here is a relatively simple two dimensional array challenge.
Imagine a battlefield of 625 foot soldiers. You command the odd troops, but unfortunately the strength of the even troops overwhelms you. Thankfully, your soldiers have a secret power: If the power of each odd troop and the fellow odd allies surrounding them is divisible by a secret power number, they unleash their ultimate attack and win! You must honor each victorious soldier.
Rules
Given a 25 x 25 integer array where each element contains the product of its x and y position plus 1, return the coordinates of every "victorious" odd element that meets the following criteria:
The sum of the element's value and its adjacent odd elements (up, down, left, and right) is divisible by the input (secret power number). It must have elements adjacent to it on all four sides and not be on an edge.
Submissions can be either a function or full program that requires a single input. The output can be in any order.
Our 25 x 25 array, the battlefield, looks like this:
1, 1, 1, 1,...
1, 2, 3, 4,...
1, 3, 5, 7,...
1, 4, 7, 10,...
etc.

Example
Here is a 3 x 3 example:
43, 57, 71
46, 61, 76
49, 65, 81

To determine if an element (61, in the center) wins, we sum the values of it and the adjacent odd elements.
61 + 57 + 65 = 183

If the total is divisible by the input, the element's x and y position is printed. If our input is 3, because 183 is divisible by 3, "1, 1" is printed.
Output
If the input (secret power number) is 37, the elements returned (victorious soldiers to be commended) must be:
2, 18
3, 12
4, 9
5, 22
6, 6
8, 23
9, 4
10, 11
11, 10
12, 3
18, 2
22, 5
23, 8

If the input is 191, the elements returned must be:
10, 19
19, 10

An input of 3:
1, 2
1, 4
1, 6
1, 8
1, 10
1, 12
1, 14
1, 16
1, 18
1, 20
1, 22
2, 1
2, 3
2, 4
2, 5
2, 7
2, 9
2, 10
2, 11
2, 13
2, 15
2, 16
2, 17
2, 19
2, 21
2, 22
2, 23
3, 2
3, 4
3, 6
3, 8
3, 10
3, 12
3, 14
3, 16
3, 18
3, 20
3, 22
4, 1
4, 2
4, 3
4, 5
4, 7
4, 8
4, 9
4, 11
4, 13
4, 14
4, 15
4, 17
4, 19
4, 20
4, 21
4, 23
5, 2
5, 4
5, 6
5, 8
5, 10
5, 12
5, 14
5, 16
5, 18
5, 20
5, 22
6, 1
6, 3
6, 5
6, 7
6, 9
6, 11
6, 13
6, 15
6, 17
6, 19
6, 21
6, 23
7, 2
7, 4
7, 6
7, 8
7, 10
7, 12
7, 14
7, 16
7, 18
7, 20
7, 22
8, 1
8, 3
8, 4
8, 5
8, 7
8, 9
8, 10
8, 11
8, 13
8, 15
8, 16
8, 17
8, 19
8, 21
8, 22
8, 23
9, 2
9, 4
9, 6
9, 8
9, 10
9, 12
9, 14
9, 16
9, 18
9, 20
9, 22
10, 1
10, 2
10, 3
10, 5
10, 7
10, 8
10, 9
10, 11
10, 13
10, 14
10, 15
10, 17
10, 19
10, 20
10, 21
10, 23
11, 2
11, 4
11, 6
11, 8
11, 10
11, 12
11, 14
11, 16
11, 18
11, 20
11, 22
12, 1
12, 3
12, 5
12, 7
12, 9
12, 11
12, 13
12, 15
12, 17
12, 19
12, 21
12, 23
13, 2
13, 4
13, 6
13, 8
13, 10
13, 12
13, 14
13, 16
13, 18
13, 20
13, 22
14, 1
14, 3
14, 4
14, 5
14, 7
14, 9
14, 10
14, 11
14, 13
14, 15
14, 16
14, 17
14, 19
14, 21
14, 22
14, 23
15, 2
15, 4
15, 6
15, 8
15, 10
15, 12
15, 14
15, 16
15, 18
15, 20
15, 22
16, 1
16, 2
16, 3
16, 5
16, 7
16, 8
16, 9
16, 11
16, 13
16, 14
16, 15
16, 17
16, 19
16, 20
16, 21
16, 23
17, 2
17, 4
17, 6
17, 8
17, 10
17, 12
17, 14
17, 16
17, 18
17, 20
17, 22
18, 1
18, 3
18, 5
18, 7
18, 9
18, 11
18, 13
18, 15
18, 17
18, 19
18, 21
18, 23
19, 2
19, 4
19, 6
19, 8
19, 10
19, 12
19, 14
19, 16
19, 18
19, 20
19, 22
20, 1
20, 3
20, 4
20, 5
20, 7
20, 9
20, 10
20, 11
20, 13
20, 15
20, 16
20, 17
20, 19
20, 21
20, 22
20, 23
21, 2
21, 4
21, 6
21, 8
21, 10
21, 12
21, 14
21, 16
21, 18
21, 20
21, 22
22, 1
22, 2
22, 3
22, 5
22, 7
22, 8
22, 9
22, 11
22, 13
22, 14
22, 15
22, 17
22, 19
22, 20
22, 21
22, 23
23, 2
23, 4
23, 6
23, 8
23, 10
23, 12
23, 14
23, 16
23, 18
23, 20
23, 22

An input of 5:
1, 4
1, 14
2, 2
2, 4
2, 6
2, 7
2, 8
2, 10
2, 12
2, 14
2, 16
2, 17
2, 18
2, 20
2, 22
3, 8
3, 18
4, 1
4, 2
4, 4
4, 6
4, 8
4, 10
4, 11
4, 12
4, 14
4, 16
4, 18
4, 20
4, 21
4, 22
6, 2
6, 4
6, 6
6, 8
6, 9
6, 10
6, 12
6, 14
6, 16
6, 18
6, 19
6, 20
6, 22
7, 2
7, 12
7, 22
8, 2
8, 3
8, 4
8, 6
8, 8
8, 10
8, 12
8, 13
8, 14
8, 16
8, 18
8, 20
8, 22
8, 23
9, 6
9, 16
10, 2
10, 4
10, 6
10, 8
10, 10
10, 12
10, 14
10, 16
10, 18
10, 20
10, 22
11, 4
11, 14
12, 2
12, 4
12, 6
12, 7
12, 8
12, 10
12, 12
12, 14
12, 16
12, 17
12, 18
12, 20
12, 22
13, 8
13, 18
14, 1
14, 2
14, 4
14, 6
14, 8
14, 10
14, 11
14, 12
14, 14
14, 16
14, 18
14, 20
14, 21
14, 22
16, 2
16, 4
16, 6
16, 8
16, 9
16, 10
16, 12
16, 14
16, 16
16, 18
16, 19
16, 20
16, 22
17, 2
17, 12
17, 22
18, 2
18, 3
18, 4
18, 6
18, 8
18, 10
18, 12
18, 13
18, 14
18, 16
18, 18
18, 20
18, 22
18, 23
19, 6
19, 16
20, 2
20, 4
20, 6
20, 8
20, 10
20, 12
20, 14
20, 16
20, 18
20, 20
20, 22
21, 4
21, 14
22, 2
22, 4
22, 6
22, 7
22, 8
22, 10
22, 12
22, 14
22, 16
22, 17
22, 18
22, 20
22, 22
23, 8
23, 18

This is code-golf, the lowest byte-count code without using standard loopholes is the winner.
As this is my first submission, any advice is greatly appreciated. Thanks!

I'm a tad confused about Given a 25 x 25 integer array. Should our submissions generate this list or is it actually given on input?

Only the output matters. Generating the actual array is optional.

"Imagine a battlefield of 625 foot soldiers"  Right.  That's tall.  O_o

JavaScript (ES6),  83 81 80  76 bytes
The output is a space-delimited string of coordinates \$x,y\$.
f=(n,x=y=23,k=5,v=x*y)=>y?(v&1|~v*k%n?[]:[x,y]+' ')+f(n,--x||23|!y--,k^6):[]

Try it online!
How?
Let \$c_{x,y}=xy+1\$ be the value of the cell located at \$(x,y)\$.
Since the cells on the edge are not accounted, we assume \$0<x<24\$ and \$0<y<24\$.
\$c_{x,y}\$ is odd if either \$x\$ or \$y\$ is even (or both of them).
If \$x\$ is odd, then \$c_{x-1,y}\$ and \$c_{x+1,y}\$ are odd. But in that case, \$y\$ must be even, and so are \$c_{x,y-1}\$ and \$c_{x,y+1}\$. The sum of the cell and its odd surrounding neighbors is:
$$s_{x,y}=c_{x,y}+c_{x-1,y}+c_{x+1,y}=3c_{x,y}$$
Similarly, if \$y\$ is odd:
$$s_{x,y}=c_{x,y}+c_{x,y-1}+c_{x,y+1}=3c_{x,y}$$
If both \$x\$ and \$y\$ are even, all surrounding neighbors are odd:
$$s_{x,y}=c_{x,y}+c_{x-1,y}+c_{x+1,y}+c_{x,y-1}+c_{x,y+1}=5c_{x,y}$$
This multiplier (\$3\$ or \$5\$) is named \$k\$ in the JS code.
Commented
f = (                // f is a recursive function taking:
  n,                 //   n      = input
  x = y = 23,        //   (x, y) = current coordinates, starting at (23, 23)
  k = 5,             //   k      = multiplier (3 or 5)
  v = x * y          //   v      = x * y (value of the current cell - 1)
) =>                 //
  y ?                // if y is greater than 0:
    ( v & 1 |        //   if v is odd (meaning that v + 1 is not)
      ~v * k % n ?   //   or n is not a divisor of -(v + 1) * k:
        []           //     append nothing
      :              //   else:
        [x, y] + ' ' //     append the coordinates followed by a space
    ) +              //
    f(               //   append the result of a recursive call:
      n,             //     pass n unchanged
      --x ||         //     decrement x; if the result is 0:
        23 | !y--,   //       pass 23 instead and decrement y
      k ^ 6          //     update k (5 -> 3 -> 5 -> ...)
    )                //   end of recursive call
  :                  // else:
    []               //   stop recursion

Thanks for the insightful explanation. Clever using a bitwise XOR to flip between the multipliers.

C# (Visual C# Interactive Compiler), 97 93 91  90 bytes
x=>{for(int i=0,d=0,j;++i<24;d=5)for(j=0;++j<24;d^=6)if(i*j%2+(i*j+1)*d%x<1)Print((i,j));}

Saved 6 bytes thanks to @Kevin Cruijssen!
Try it online!

int i=0; ... int j=0; can be int i=0,j; ... j=0; and <1& can be + for -4 bytes.

@KevinCruijssen For the int declarations, originally I had it that way until I changed my function to a different method, then reverted it. The + one is nice though, thanks

Another -2 by replacing ((i+j)%2>0?3:5) with (5-(i+j)%2*2)

Suggest i*j%2<=~(i*j)*d%x instead of i*j%2+(i*j+1)*d%x<1

Python 2, 83 bytes
lambda n:[(x,y)for x in R for y in R if~(x*y)*[5,3][x+y&1]%n<1>x*y%2]
R=range(1,24)

Try it online!
Thanks to Arnauld for saving a byte.

Ah, basically the same program to my prepared js answer...

Stax, 25 bytes
âÖÅ{┼îÄï$εS╢,σδXú(Γ°#↑√nG

Run and debug it
This is mostly just brute force, with one marginally clever observation.  All odd troops have either 2 or 4 odd neighbors.  And the total sum of these plus the original solder is either 3p or 5p where p is the soldier's power.  The coefficient (3 or 5) can be determined by gcd(2, x, y) * 2 + 1) where x and y are the soldier's coordinates.

JavaScript (SpiderMonkey), 69 bytes
x=>{for(i=24;--i;)for(j=24,d=5;--j;d^=6)i*j%2+~(i*j)*d%x||print(j,i)}

Try it online!

Jelly, 22 bytes
23×þ`‘µḤḤÐeÐe+×Ḃ³ḍaƊŒṪ

Try it online!
A full program that takes a single argument, the secret power number, and implicitly prints a list of [x, y] pairs. Uses the observation others have made about multiples of 3 and 5.

Wolfram Language (Mathematica), 60 58 bytes
Position[If[2∣+##,5,3](1+1##)&~Array~{23,23},a_/;#∣a]&

Try it online!
Looked around after posting and realized I really needed to turn my brain on...


text:
Attacking the Hydra
Instead of being a skillful warrior capable of slaying Hydras (see here and here), this time you are a warrior that has no prior knowledge on how to kill one or which weapons to use against the creature.
In this problem, whenever you cut a single head off, two will grow in the same place. Since you don't have the mechanism to cut many heads off simultaneously, the number of heads will only grow. In this case, our Hydra can start with N (N ⩾ 1) heads. Let's call the first encounter a generation and we will represent the heads from the first generation as 0, the heads created after the first blow as 1, and so on.
Input
You will be given an integer N representing how many heads the Hydra initially have and a list of size N containing in which index (in the examples I will use 0-indexed format) you will cut a head off. You can always assume the indexes given are valid - remember that the list (i.e.: the heads) will grow as you cut heads off.
Example
Input: N = 4 and [0,4,2,5]
Generation 0 - Attack index 0
0 0 0 0     =>     1 1 0 0 0
^                  ^ ^

Generation 1 - Attack index 4
1 1 0 0 0     =>     1 1 0 0 2 2
        ^                    ^ ^

Generation 2 - Attack index 2
1 1 0 0 2 2     =>     1 1 3 3 0 2 2
    ^                      ^ ^

Generation 3 - Attack index 5
1 1 3 3 0 2 2     =>     1 1 3 3 0 4 4 2
          ^                        ^ ^

Last generation
1 1 3 3 0 4 4 2

As you can see, the indexes given are related to the list of the previous generation.
Output
You are required to output the last generation.
Test cases
N = 1 and [0] => [1,1]
N = 2 and [0,0] => [2,2,1,0]
N = 2 and [0,1] => [1,2,2,0]
N = 2 and [1,0] => [2,2,1,1]
N = 2 and [1,1] => [0,2,2,1]
N = 4 and [0,4,2,5] => [1,1,3,3,0,4,4,2]
N = 6 and [0,0,0,0,0,0] => [6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0]
N = 6 and [5,6,7,8,9,10] => [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 6]
N = 10 and [1,7,3,12,9,0,15,2,2,10] => [6, 6, 9, 9, 8, 1, 3, 3, 0, 0, 10, 10, 2, 5, 5, 0, 0, 4, 7, 7]

This is code-golf so shortest answer in bytes wins!

Sandbox link

Needs a test case where the initial number of heads is greater than the number of heads cut off.  I think I see at least one current answer which would fail that case.

@Xcali The number of heads to cut off is actually guaranteed to be equal to the initial number of heads: You will be given an integer N (...) and a list of size N (But I missed that part as well when I first read the challenge.) Therefore, N is simply useless.

Ah.  You're right, I missed it.

I thought about actually removing N from the input since it is "implicitly" given as the array's size. However, I thought   the solutions would save bytes by giving N instead of them relying on array.size() or similar.

Relevant Order of the Stick comic (+ next one).

Python 2, 59 bytes
H,a=input()
H*=[0]
for i in a:H[i:i+1]=[max(H)+1]*2
print H

Try it online!
Very clever -1 thanks to xnor.

Dang it. Beat me by 52 seconds...

@TFeld LOL you tried to avoid an extra variable for the generation too! :D

Python 2, 60 bytes
n,a=input()
h=[0]*n
for c in a:h[c:c+1]=[max(h)+1]*2
print h

Try it online!

Stax, 12 11 bytes
î╓≡╧▄#¥oWä)A

Run and debug it at staxlang.xyz!
Thanks to recursive for one byte of savings!
Unpacked (13 bytes) and explanation:
z),{i^c\&:fFm
z)               Push initial array of zeroes to stack
  ,              Push array of attacks to stack
   {       F     For each attack, push it and then:
    i^c\           Push [x,x], where x is the generation number
        &          Set the head at the attack index to this new array
         :f        Flatten
            m    Print the last generation

The challenge explicitly says "you are required to output the last generation," so my guess is this consensus doesn't hold here. If it does, though, ten bytes can be managed by leaving the result on an otherwise-empty stack:
z),Fi^c\&:f

0]* can be replaced with z).  Edit:  Apparently this is undocumented behavior, but pad-left takes its operands in either order.  (npm lol)

@recursive Undocumented behavior is the best kind of behavior :)

Haskell, 63 57 bytes
foldl(\y(x,n)->take n y++x:x:drop(n+1)y).(0<$)<*>zip[1..]

Try it online!

take and drop are shorter than splitAt. Turning g into a lambda saves another byte: foldl(\y(x,n)->take n y++x:x:drop(n+1)y).(0<$)<*>zip[1..].

Ahh nice - I tried both of these but for some reason I only attempted to make g pointfree, and it just got worse.

Oracle SQL, 325 bytes
select listagg(ascii(substr(l,level,1)),', ')within group(order by level)
from(select * from t
model dimension by(1 i)measures(l,r)
rules iterate(1e5)until(r[1]is null)
(l[1]=regexp_replace(l[1],'.',chr(:n-length(r[1])+1)||chr(:n-length(r[1])+1),1,ascii(substr(r[1],1,1))+1),r[1]=substr(r[1],2)))
connect by level<=length(l);

Test in SQL*Plus.
SQL> set heading off
SQL>
SQL> create table t(l varchar2(4000), r varchar2(4000));

Table created.

SQL>
SQL> var n number;
SQL> exec :n := 10;

PL/SQL procedure successfully completed.

SQL>
SQL> insert into t
  2  values(rpad(chr(0),:n,chr(0)), chr(1)||chr(7)||chr(3)||chr(12)||chr(9)||chr(0)||chr(15)||chr(2)||chr(2)||chr(10));

1 row created.

SQL>
SQL> select listagg(ascii(substr(l,level,1)),', ')within group(order by level)
  2  from(select * from t
  3  model dimension by(1 i)measures(l,r)
  4  rules iterate(1e5)until(r[1]is null)
  5  (l[1]=regexp_replace(l[1],'.',chr(:n-length(r[1])+1)||chr(:n-length(r[1])+1),1,ascii(substr(r[1],1,1))+1),r[1]=substr(r[1],2)))
  6  connect by level<=length(l);

6, 6, 9, 9, 8, 1, 3, 3, 0, 0, 10, 10, 2, 5, 5, 0, 0, 4, 7, 7

PS. Works for numbers up to 255.
Oracle SQL, 214 bytes, generic case
select l from t model dimension by(1i)measures(rpad('0',(n-1)*2+1,',0')l,r,n,1k)rules iterate(1e9)until(k[1]=n[1]+1)
(l[1]=regexp_replace(l[1],'\d+',k[1]||','||k[1],1,regexp_substr(r[1],'\d+',1,k[1])+1),k[1]=k[1]+1)

Test in SQL*Plus.
SQL> create table t(n,r) as
  2  select regexp_count(r,',')+1 n, r from
  3  (select cast('1,7,3,12,9,0,15,2,2,10' as varchar2(4000)) r from dual)
  4  /

Table created.

SQL> select l from t model dimension by(1i)measures(rpad('0',(n-1)*2+1,',0')l,r,n,1k)rules iterate(1e9)until(k[1]=n[1]+1)
  2  (l[1]=regexp_replace(l[1],'\d+',k[1]||','||k[1],1,regexp_substr(r[1],'\d+',1,k[1])+1),k[1]=k[1]+1)
  3  /

L
--------------------------------------------------------------------------------
6,6,9,9,8,1,3,3,0,0,10,10,2,5,5,0,0,4,7,7

JavaScript (ES6),  61 59  51 bytes
Thanks to @Shaggy for pointing out that n is always the length of the array, saving 8 bytes in both versions
Expects the array in 0-indexed format. Ignores n.
a=>a.map(i=>b.splice(i,1,++g,g),b=a.map(_=>g=0))&&b

Try it online!

JavaScript (Node.js),  64  56 bytes
Using reduce() and flat():
a=>a.reduce((b,i,g)=>b.flat(1,b[i]=[++g,g]),a.map(_=>0))

Try it online!

Would a=>a.map(i=>b.splice(i,1,++g,g),b=a.map(_=>g=0))&&b work, without taking n?

@Shaggy Oops. I missed that part: and a list of size N. So, yeah, it seems like n IS useless.

Zsh, 41 bytes
We ignore N, as stated by the rules.
for i;a+=(0)
for i;a[i]=($[++j] $j)
<<<$a

Try it online!
Pretty standard: Make an array of 0s to start, print it to finish.
The a[i]=(a b) method of both changing and inserting is new to me, happy I found a use for it.

OR, also 41 bytes:
a[#]=
for i;a[i]=($[++j] $j)
<<<${a/#%/0}

This one is less standard. We take advantage of a few neat tricks:

${a/#%/0}: This is replacement, but # and % tell zsh to anchor the match at the start and end. Since it's empty, we replace all empty elements with 0.
a[#]=: This effectively declares an empty array of size $# in Zsh. It's like char *a[argc] in C. If we don't do this, we won't get the trailing zeroes we need.

Try it online!

Scala, 104 bytes
def^(l:Seq[Int],r:Seq[Int]):Seq[Int]=if(r.size>0)^(l.patch(r(0),Seq.fill(2)(l.max+1),1),r.drop(1))else l

Try it online!
Seems to be the longest answer so far. :)
List.fill(2)(l.max+1) can be replaced with List(l.max+1,l.max+1) but length remains the same.

Japt, 14 bytes
rÈhY[°TT] c}Uî

Try it

PHP, 101 bytes
function h($n,$a){$h=array_fill(0,$n,0);foreach($a as$b)array_splice($h,$b,0,$h[$b]=++$x);return $h;}

Try it online!

Welcome! Consider adding an explanation and a link to an online interpreter, such as TIO. Code-only answers are usually automatically marked as low-quality. See existing answers for details.

I've added a TIO link

C# (Visual C# Interactive Compiler), 94 89 85 bytes
a=>b=>b.Aggregate(new int[a-(a-=a)].ToList(),(c,d)=>{c.Insert(d,c[d]=++a);return c;})

Saved 2 bytes thanks to Andrew Bauhmer
Try it online!

you can save 2 bytes by reusing a.  a=>b=>b.Aggregate(new int[a-(a-=a)].ToList(),(c,d)=>{c[d]=++a;c.Insert(d,a);return c;})<

Past 5 minutes, derp. you can test it here

@AndrewBaumher Thanks

Perl 5 -pal, 48 bytes
@h=($i=0)x@F;splice@h,$_,1,(++$i)x2for@F;$_="@h"

Try it online!
Takes array as space-separated list from STDIN. Doesn't input n.

In case anybody is wondering whether not taking an input is allowed: See https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods/12442#12442

Retina 0.8.2, 69 bytes
\d+
$*_
r`_\G
,0
+`^((,*)_)(_)*(.*,,(?<-3>\d+,)*)\d+
$2$4$.1,$.1
^,+

Try it online! Link includes test cases. 1-indexed. Takes input as ...list,N. Does not require the list to be of length N. Explanation:
\d+
$*_

Convert all of the inputs to unary, but using _, so that it doesn't get confused with later uses of the digit 1. (Retina 1 would do this automatically for a 2-byte saving.)
r`_\G
,0

Replace N with an array of N zeros, but don't alter the list.
+`

Process all elements of the list.
^((,*)_)(_)*(.*,,(?<-3>\d+,)*)\d+

Find the next element of the list and the equivalent position in the array. $1 = current generation (as a length), $2 = commas from previous generations, $3 = current index - 1, $4 = first $3 heads.
$2$4$.1,$.1

Replace the head at the current index with two copies of the current generation in decimal.

Pyth, 16 bytes
u.nXGH,=+Z1ZE*]0

Try it online!
Interestingly, it turns out I can't use s to flatten the list as it is actually shorthand for +F, which performs + on the leftmost two elements of the list until all elements have been processed. This means that the first few elements might simply be summed, depending on where the last replacement occurred.
u.nXGH,=+Z1ZE*]0Q   Implicit: Q=input 1 (N), E=input 2 (array), Z=0
                    Trailing Q inferred
              ]0    [0]
             *  Q   Repeat Q times
u           E       Reduce E, with current value G and next value H, starting with the above:
       =+Z1           Increment Z in-place
      ,  Z Z          Pair the updated Z with itself
   XGH                In G, replace the element with index H with the above
 .n                   Flatten
                    Implicit print

Jelly, 13 bytes
;`ɼṁœP@j‘ɼɗƒ@

Try it online!
Monadic link that takes the 1-indexed list of heads to cut as its argument and returns the final generation.

05AB1E, 10 bytes
-IvN>D‚yǝ˜

Try it online!
   -             # subtract the input from itself (yields a list of 0s)
    Iv           # for each number y in the input
      N          # push the 0-based loop count
       >         # add 1 to get the generation number
        D        # duplicate
         ‚       # wrap the two copies in a list
          yǝ     # replace the element at index y with that list
            ˜    # flatten