[Question]
  [
# Overview
Some of you might be aware of the [Kolakoski Sequence](https://en.wikipedia.org/wiki/Kolakoski_sequence) ([A000002](http://oeis.org/A000002)), a well know self-referential sequence that has the following property:
[![The coolio Kolakoski property, yo.](https://i.stack.imgur.com/KoIk7.jpg)](https://i.stack.imgur.com/KoIk7.jpg)
It is a sequence containing only 1's and 2's, and for each group of 1's and twos, if you add up the length of runs, it equals itself, only half the length. In other words, the Kolakoski sequence describes the length of runs in the sequence itself. It is the only sequence that does this except for the same sequence with the initial 1 deleted. (This is only true if you limit yourself to sequences made up of 1s and 2s - Martin Ender)
---
# The Challenge
The challenge is, given a list of integers:
* Output `-1` if the list is NOT a working prefix of the Kolakoski sequence.
* Output the number of iterations before the sequence becomes `[2]`.
---
# The Worked Out Example
Using the provided image as an example:
```
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1] # Iteration 0 (the input).
[1,2,2,1,1,2,1,2,2,1,2]             # Iteration 1.
[1,2,2,1,1,2,1,1]                   # Iteration 2.
[1,2,2,1,2]                         # Iteration 3.
[1,2,1,1]                           # Iteration 4.
[1,1,2]                             # Iteration 5.
[2,1]                               # Iteration 6.
[1,1]                               # Iteration 7.
[2]                                 # Iteration 8.
```
Therefore, the resultant number is `8` for an input of `[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1]`.
`9` is also fine if you are 1-indexing.
---
# The Test Suite (You can test with sub-iterations too)
```
------------------------------------------+---------
Truthy Scenarios                          | Output
------------------------------------------+---------
[1,1]                                     | 1 or 2
[1,2,2,1,1,2,1,2,2,1]                     | 6 or 7
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1]       | 8 or 9
[1,2]                                     | 2 or 3
------------------------------------------+---------
Falsy Scenarios                           | Output
------------------------------------------+---------
[4,2,-2,1,0,3928,102904]                  | -1 or a unique falsy output.
[1,1,1]                                   | -1
[2,2,1,1,2,1,2] (Results in [2,3] @ i3)   | -1 (Trickiest example)
[]                                        | -1
[1]                                       | -1
```
If you're confused:
**Truthy:** It will eventually reach two without any intermediate step having any elements other than `1` and `2`. – `Einkorn Enchanter 20 hours ago`
**Falsy:** Ending value is not `[2]`. Intermediate terms contain something other than something of the set `[1,2]`. A couple other things, see examples.
---
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), lowest byte-count will be the victor.
  
[Answer]
# [Haskell](https://www.haskell.org/), ~~126~~ ~~87~~ ~~79~~ ~~76~~ 75 bytes
*39 bytes saved thanks to Ørjan Johansen*
```
import Data.List
f[2]=0
f y@(_:_:_)|all(`elem`[1,2])y=1+f(length<$>group y)
```
[Try it online!](https://tio.run/##y0gszk7Nyfn/PzO3IL@oRMElsSRRzyezuIQrLdoo1taAK02h0kEj3goINWsSc3I0ElJzUnMTog11jGI1K20NtdM0clLz0ksybFTs0ovySwsUKjX/5yZm5llZefpraHKBmLYFRZl5JSppCtFGQF3/AQ "Haskell – Try It Online")
This errors on bad input.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 22 bytes
```
[Dg2‹#γ€gM2›iX]2QJiNë®
```
[Try it online!](https://tio.run/##MzBNTDJM/f8/2iXd6FHDTuVzmx81rUn3BbJ3ZUbEGgV6ZfodXn1oHVCBoY6hjhEQGoIxgg3jAclYAA "05AB1E – Try It Online")
**Explanation**
```
[                        # start a loop
 D                       # duplicate current list
  g2‹#                   # break if the length is less than 2
      γ                  # group into runs of consecutive equal elements
       €g                # get length of each run
         M2›iX           # if the maximum run-length is greater than 2, push 1
              ]          # end loop
               2QJi      # if the result is a list containing only 2
                   N     # push the iteration counter from the loop
                    ë®   # else, push -1
                         # implicitly output top of stack
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 17 bytes
```
ŒgL€$ÐĿµẎḟ1,2ȯL_2
```
[Try it online!](https://tio.run/##y0rNyan8///opHSfR01rVA5POLL/0NaHu/oe7phvqGN0Yr1PvNH///@jgWwgNNQxBJNGSCRExDAWAA "Jelly – Try It Online")
[Answer]
# SCALA, 290(282?) chars, 290(282?) bytes
It took me sooo loong ... But I'm finally done!
with this code :
```
var u=t
var v=Array[Int]()
var c= -1
var b=1
if(!u.isEmpty){while(u.forall(x=>x==1|x==2)){c+=1
if(u.size>1){var p=u.size-1
for(i<-0 to p){if(b==1){var k=u(i)
v:+=(if(i==p)1 else if(u(i+1)==k){b=0
if(p-i>1&&u(i+2)==k)return-1
2}else 1)} else b=1}
u=v
v=v.take(0)}else if(u(0)==2)return c}}
c
```
I don't know if I should count the `var u=t` into the bytes, considering I do not use `t` during the algorithm (the copy is just to get a modifyable `var` instead of the parameter `t` considered as `val` - thanks *ScaLa*).
Please tell me if I should count it.
Hard enough. [Try it online!](https://tio.run/##lZGxboMwEIbn@incDJEtAsJuhibqIWXo0KFPEGVwiKO6ULDA0KSUZ6cGhoSkpKqQDnP3/f@djzwUsWjS7bsMDX4VKsHyYGSyy/FK6wrd7eQeR2ksorTMI0XMcpVl4rh@ScyGLm2EqilFhgswqH2XcKoT2qVCwC7rTltgSO3JfeGp/PlDmyOtPt9ULEnh7dNMxDE5QHAAYN82cEqr0OkVhZerLxkwWrU2Gvpv62plRD25PjYp1rSy6NbKeyyCgig7wtIBYgsKQFOGZZxL3FoS5TAKENFqC37bRLsqYNNpW@BdIZOmyBLbhdeditG6l9t71KiAEpVQekZEkvi0Phn7tJ2@V@OwrlHY1AjpTCUmTshkzTfYDfDEOVtrtzRir0zPODZjY6QtXbJ8nL3y5faxFl3szje0l@ifXoPMf5yHwmGfuU26bd6fPSz444z5fOHPx8x/p6@2e3O/lxMMxh39g@fQUD8maam6@QE)
PS : I was thinking of doing it recursively, but I'll have to pass a counter as a parameter of the true recursive "subfunction" ; this fact makes me declare two functions, and these chars/bytes are nothing but lost.
EDIT : I had to change (?) because we're not sure we should take in count `[1]` case. So [here](https://tio.run/##lZHPjpswEMbP9VO4OUS2EiLs7mE36iDl0EMPfYIoqhyvo/VCAYGhSV0/ezrAShuyJasVkjEzv@@bP9RaZepc7J@NdvSHsjk1R2fyx5puytKTT4/mQNMiU2nR1qllbr2pKnXafs/djq/xBH9uVUUbcKR7t/CaZ7wPaaCR6G97EMQe2OdmZetvv0p34t5VJ@@Y4EErp5@8VrWhPyGpjGuqnCLsWMwBJI@pyTAXiUB@P9nMsGZ1KCqVZewIyRFA/D12GPd6MVRpVrX9YxLBfVe6hOEbO0EZs1@jmLqCltwjukf5gKXQMIttrxfAMGEBSi6Gyp0lswuB3aTc7yHuipSRTcR83iVknxgaxyoy9CqcbJDj7IE00JIW2pVTqcG5wqvxMOTL2DoEos@BkLKyuctyNtuKHY0SOltc/Ip@0bg6zi84OcXJMSeW045Lcc3KafaNr8QHLfqzv9/QXqPveo0iH3EeC8d17jAYdfF4@eVB3i9FLB/iuynz/9Nvtntzv9cdjNqd/IOX0Fg/JemocP4H) is the modified code :
```
var u=t
var v=Array[Int]()
var c= -1
var b=1
if(!u.isEmpty){try{t(1)}catch{case _=>return if(t(0)==2)0 else -1}
while(u.forall(x=>x==1|x==2)){c+=1
if(u.size>1){var p=u.size-1
for(i<-0 to p){if(b==1){var k=u(i)
v:+=(if(i==p)1 else if(u(i+1)==k){b=0
if(p-i>1&&u(i+2)==k)return-1
2}else 1)} else b=1}
u=v
v=v.take(0)}else if(u(0)==2)return c}}
c
```
It's not optimized (I have a duplicate "out" for the same conditions : when I get to `[2]` and when param is `[2]` is treated separatedly).
NEW COST = 342 (I didn't modify the title on purpose)
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~26~~ ~~25~~ ~~22~~ ~~21~~ 20 bytes
```
FQœ-2R¤
ŒgL€µÐĿṖ-LÇ?
```
[Try it online!](https://tio.run/##y0rNyan8/98t8OhkXaOgQ0u4jk5K93nUtObQ1sMTjux/uHOars/hdvv///9HG@oYAaGhjiGYNEIiISKGsQoKAA "Jelly – Try It Online")
This code actually wasn't working correctly until 20 bytes and I didn't even notice; it was failing on the `[2,2]` test case. Should work perfectly now.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 12 bytes
```
ŒɠƬµ2Wea’ỊȦƊ
```
[Try it online!](https://tio.run/##y0rNyan8///opJMLjq05tNUoPDXxUcPMh7u7Tiw71vX/cPujpjVHJz3cOeP//2hDHcNYHSBpBIRANpgEs7GLoohA1QBJEyBfFyRkoGNsaWShY2hgZGlgApaGKEMxCMgHScUCAA "Jelly – Try It Online")
## How it works
```
ŒɠƬµ2Wea’ỊȦƊ - Main link. Takes a list L on the left
  Ƭ          - Until reaching a fixed point, keeping each step:
Œɠ           -   Get the lengths of consectuively equal groups of elements
   µ         - Call this list S and use it as the argument
    2W       - Yield [2]
      e      - Is [2] in S?
           Ɗ - Last 3 links as a monad f(S):
        ’    -   Decrement every integer in S
         Ị   -   Insignificant? Replace 0 and 1 with 1, everything else 0
          Ȧ  -   Any and all? S is non-empty and has no zeros
       a     - Both are true?
```
[Answer]
# **JavaScript, ~~146~~ 142 bytes**
First try in code golfing, it seems that the "return" in the larger function is quite tedious...
Also, the checking of b=1 and b=2 takes up some bytes...
Here's the code:
```
f=y=>{i=t=!y[0];while(y[1]){r=[];c=j=0;y.map(b=>{t|=b-1&&b-2;if(b-c){if(j>0)r.push(j);c=b;j=0}j++});(y=r).push(j);i++}return t||y[0]-2?-1:0^i}
```
Explanation
```
f=y=>{/*1*/}                                        //function definition
//Inside /*1*/:
  i=t=!y[0];                                        //initialization
                                                    //if the first one is 0 or undefined, 
                                                    //set t=1 so that it will return -1   
                                                    //eventually, otherwise i=0
  while(y[1]){/*2*/}                                //if there are 2+ items, start the loop
  //Inside /*2*/:
    r=[];c=j=0;                                     //initialization
    y.map(b=>{/*3*/});                              //another function definition
    //Inside /*3*/:
      t|=b-1&&b-2;                                  //if b==1 or b==2, set t=1 so that the
                                                    //entire function returns -1
      if(b-c){if(j>0)r.push(j);c=b;j=0}             //if b!=c, and j!=0, then push the 
                                                    //count to the array and reset counter
      j++                                           //counting duplicate numbers
    (y=r).push(j);i++                               //push the remaining count to the array
                                                    //and proceed to another stage
  return t||y[0]-2?-1:0^i                           //if the remaining element is not 2, or
                                                    //t==1 (means falsy), return -1,
                                                    //otherwise return the counter i
```
Test data (using the given test data)
```
l=[[1,1],[1,2,2,1,1,2,1,2,2,1],[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1],[1,2],[4,2,-2,1,0,3928,102904],[1,1,1],[2,2,1,1,2,1,2],[]];
console.log(l.map(f));
//Output: (8) [1, 6, 8, 2, -1, -1, -1, -1]
```
Edit 1: 146 -> 142: Revoking my edit on reducing bytes, because this affects the output; and some edit on the last statement
[Answer]
## JavaScript (ES6), ~~127~~ ~~126~~ ~~95~~ 80 bytes
```
g=(a,i,p,b=[])=>a.map(x=>3>x&0<x?(x==p?b[0]++:b=[1,...b],p=x):H)==2?i:g(b,~~i+1)
```
0-indexed. Throws `"ReferenceError: X is not defined"` and `"InternalError: too much recursion"` on bad input.
### Test cases
```
g=(a,i,p,b=[])=>a.map(x=>3>x&0<x?(x==p?b[0]++:b=[1,...b],p=x):H)==2?i:g(b,~~i+1)
function wrapper(testcase) {
  try {console.log(g(testcase))} catch(e) {
    console.log("Error")
  }
}
wrapper([1,1])
wrapper([1,2,2,1,1,2,1,2,2,1])
wrapper([1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1])
wrapper([1,2])
wrapper([4,2,-2,1,0,3928,102904])
wrapper([1,1,1])
wrapper([2,2,1,1,2,1,2])
wrapper([])
wrapper([1])
```
[Answer]
# [Scala 3 (compile-time)](https://dotty.epfl.ch/docs/index.html), 460 bytes
This may be the longest answer here, but it's also the fastest one here...because it works at compile time.
```
import compiletime.ops.int._
type r[T,P]=T match{case h*:t=>r[t,h*:P]case E=>P}
type E=EmptyTuple
type F[K,R,L,S,P,I]=K match{case E=>L-S match{case 0=>R match{case E=>0 case _=>F[r[R,E],E,0,0,0,I+1]}case _=>0}case P*:_=>0
case 1*:1*:t=>F[t,2*:R,L+2,S+2,1,I]case 1*:t=>(t,R)match{case(E,E)=>0 case _=>F[t,1*:R,L+1,S+1,1,I]}case 2*:2*:t=>F[t,2*:R,L+2,S+2,2,I]case 2*:t=>(t,R)match{case(E,E)=>I+1 case _=>F[t,1*:R,L+1,S+1,2,I]}case _=>0}
type G[K]=F[K,E,0,0,0,0]
```
[Try it in online!](https://scastie.scala-lang.org/XnwSWKZ7STiR8iE6zsPW5w)
You can invoke it as `G[1 *: 2 *: EmptyTuple]` (actually, just `G[(1, 2)]` *should* also work, but for whatever reason, it's not working right now. I'll fix it later, though). It's 1-indexed, and it returns 0 for falsy inputs.
[Answer]
## Clojure, 110 bytes
```
#(if-not(#{[][1]}%)(loop[c % i 0](if(every? #{1 2}c)(if(=[2]c)i(recur(map count(partition-by + c))(inc i))))))
```
A basic `loop` with a pre-check on edge cases. Returns `nil` for invalid inputs. I did not know `(= [2] '(2))` is `true` :o
[Answer]
# Python 2, 146 bytes (function only)
```
f=lambda l,i=0:i if l==[1]else 0if max(l)>2or min(l)<1else f([len(x)+1for x in"".join(`v!=l[i+1]`[0]for i,v in enumerate(l[:-1])).split("T")],i+1)
```
Returns 0 on falsy input (ok since it's 1-indexed). Simply use it like this:
```
print(f([1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1]))
```
[Answer]
## Mathematica, 82 bytes
```
FixedPointList[#/.{{2}->T,{(1|2)..}:>Length/@Split@#,_->0}&,#]~FirstPosition~T-1&
```
`Function` which repeatedly replaces `{2}` with the undefined symbol `T`, a list of (one or more) `1`s and `2`s with the next iteration, and anything else with `0` until a fixed point is reached, then returns the `FirstPosition` of the symbol `T` in the resulting `FixedPointList` minus `1`. Output is `{n}` where `n` is the (`1`-indexed) number of iterations needed to reach `{2}` for the truthy case and `-1+Missing["NotFound"]` for the falsy case.
If the output must be `n` rather than `{n}`, it costs three more bytes:
```
Position[FixedPointList[#/.{{2}->T,{(1|2)..}:>Length/@Split@#,_->0}&,#],T][[1,1]]-1&
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~184 163~~ 156 bytes
* @Felipe Nardi Batista saved 21 bytes!!!! thanks a lot!!!!
* **Halvard Hummel saved 7 bytes!! thanks**
# [Python 2](https://docs.python.org/2/), 156 bytes
```
a,c=input(),0
t=a==[]
while 1<len(a)and~-t:
 r,i=[],0
 while i<len(a):
	j=i
	while[a[j]]==a[i:i+1]:i+=1
	r+=[i-j]
 a=r;c+=1;t=any(x>2for x in a)
print~c*t+c
```
[Try it online!](https://tio.run/##bY7BasMwDIbP0VP4lmRxIPZ6WNOqT7Gb8cG4HlUoTjAuSy999UxNcykMwY/06Uf6p3u@jFEvfjwHLMtycdIjxemWq1p2kNEhGgu/F7oGoY7XECtXu3h@tLkHkSTxln3iZaDN0EMxIEGxUuPMYC2iM9RToywLKihSg4bawYJwmA6e2YG/xXs1n/TPmMQsKApXw5Qo5of/yI1fOOAW5TvdAgcIc/DVM3u9GCWVBVbNxf2qa/8/fSObh3XHc/tEnfzc6y@pOr3vduv6ZXs7xLP9Aw "Python 2 – Try It Online")
Explanation:
```
a,c=input(),0                             #input and initialize main-counter 
t=a==[]                                   #set t to 1 if list's empty. 
while len(a)>1:                           #loop until list's length is 1.
 r,i=[],0                                 #Initialize temp. list and 
                                          #list-element-pointer 
 while i<len(a):                          #loop for the element in list 
  j=0                                     #set consecutive-item-counter to 0   
  while(i+j)<len(a)and a[i]==a[i+j]:j+=1  #increase the consec.-counter
  r+=[j];i+=j                             #add the value to a list, move the 
                                          #list-element-pointer 
 a=r;c+=1;t=any(x>2for x in a)            #update the main list, increase t 
                                          #the counter, check if any number 
 if t:break;                              #exceeds 2 (if yes, exit the loop)
print[c,-1][t]                            #print -1 if t or else the 
                                          #counter's 
                                          #value 
```
[Answer]
# R, 122 bytes
```
a=scan()
i=0
f=function(x)if(!all(x%in%c(1,2)))stop()
while(length(a)>1){f(a)
a=rle(a)$l
f(a)
i=i+1}
if(a==2)i else stop()
```
Passes all test cases. Throws one or more errors otherwise. I hate validity checks; this code could have been so golfed if the inputs were nice; it would be shorter even in case the input were a sequence of 1’s and 2’s, not necessarily a prefix of the Kolakoski sequence. Here, we have to check both the initial vector (otherwise the test case `[-2,1]`) would have passed) and the resulting vector (otherwise `[1,1,1]` would have passed).
[Answer]
# [Python 2](https://docs.python.org/2/), 122 bytes
```
def f(s,c=2,j=0):
 w=[1]
 for i in s[1:]:w+=[1]*(i!=s[j]);w[-1]+=i==s[j];j+=1
 return(w==[2])*c-({1,2}!=set(s))or f(w,c+1)
```
[Try it online!](https://tio.run/##hU29DoMgEN59CrqBYsJRh6q5JyFMVlIctBEa0jR9dopOxQ7NJZf7fu/@9LdlljFeR0MMdXxAyScUrCtIQAW6IGZZiSV2Jk5Bp7tQbXRJ7QmdmjTrg6pBV2hxx/1UIRRkHf1jnWlAVFKzcqjpC7h8p8zoqWMsdRoa@FABi/fVzp4aqoCDZqz4wjJNYve93//0jPlxZ7hJnnqzCX5u5YWDkK1oDpFjSfYwU/JgQvED "Python 2 – Try It Online")
# [Python 3](https://docs.python.org/3/), 120 bytes
```
def f(s,c=2,j=0):
 w=[1]
 for i in s[1:]:w+=[1]*(i!=s[j]);w[-1]+=i==s[j];j+=1
 return(w==[2])*c-({1,2}!={*s})or f(w,c+1)
```
[Try it online!](https://tio.run/##hU29DoMgEN55CrqBYuKhQ9XckxAmKykOaNSGNMZnt@hU7NBccrnv98b38hxcse@PzlDDZtGiFD3mvCbUowJNqBkmaql1dFZQ69qnB50we8NZ9Zo3XmWgU7R44qZPEQiduuU1OeYRldQ8aTO2gpDbDddk3nhoNMyLNgW@j5N1CzNMgQDNOfnCMkxgz33e//SI@XFHuAye7LDloqjkXUAuq7y8RK4l0cNIiYMB7R8 "Python 3 – Try It Online")
# Explanation
A new sequence (w) is initialized to store the next iteration of the reduction. A counter (c) is initalized to keep track of the number of iterations.
Every item in the original sequence (s) is compared to the previous value. If they are the same, the value of the last item of (w) is increased with 1. If they are different, the sequence (w) is extended with [1].
If w==[2], the counter (c) is returned. Else, if the original sequence (s) contains other items than 1 and 2, a value -1 is returned. If neither is the case, the function is called recursively with the new sequence (w) as (s) and the counter (c) increased by 1.
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 26 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
äE⌐+É7∩ΦΓyr╔ßΣ·φƒÇe►ef%I» 
```
[Run and debug it](https://staxlang.xyz/#p=8445a92b9037efe8e27972c9e1e4faed9f80651065662549af20&i=%5B1,1%5D%0A%5B1,2,2,1,1,2,1,2,2,1%5D%0A%5B1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1%5D%0A%5B1,2%5D%0A%5B4,2,-2,1,0,3928,102904%5D%0A%5B1,1,1%5D%0A%5B2,2,1,1,2,1,2%5D%0A%5B1%5D%0A%5B%5D&m=2)
Tried with a generator, but it seems like a while loop is shorter.
[Answer]
# [R](https://www.r-project.org/), ~~93~~ 92 bytes
*Edit: -1 byte thanks to Giuseppe*
```
f=function(x)`if`(sum(x|1)<2,(-1)^(sum(x)!=2),`if`(!all(x%in%1:2),-1,(y=f(rle(x)$l))+(y>0)))
```
[Try it online!](https://tio.run/##jY7tCoIwFIb/exVGCefQBM8UymhdSviBwkAN/ACF7n1tkyhDIQZj5zzPy7tWyb5o014@mk6oUpRDk5sBRkxkmUA31DA@Ca@cgU94nxe4ExyZFXZpVcHoycaji975xGASJbRVobVDhXiE6RYgokpFDsQI3b3LnU8rpOjMiOujBXvbt1FP/6mLjQ3G60GDwh/kZJpFOuqbdMDCmJ8ZBTwOIqP79O1naHV696zSxf82rGaoi1bmsF2xStQL "R – Try It Online")
Returns 1-based number of iterations for truthy input, and `-1` for all falsy inputs. This needed quite careful input testing, especially for the last two test cases...
**Commented:**
```
f=function(x)           # recursive function with argument x
`if`(sum(x|1)<2,        # if there's one (or less) element left
  (-1)^(sum(x)!=2),     # return 1 if it's equal to 2, -1 otherwise
  `if`(!all(x%in%1:2),  # if any element isn't 1 or 2
    -1,                 # return -1
    (y=f(               # otherwise recursively call self with
      rle(x)$l))        # lengths of groups of digits in x
      +(y>0)))          # if result is positive, return result +1
                        # otherwise return result (which must be -1)
```
---
# [R](https://www.r-project.org/), ~~74~~ 66 bytes
```
f=function(x)`if`(sum(x)==2&x==2,1,if(all(x%in%1:2))f(rle(x)$l)+1)
```
[Try it online!](https://tio.run/##lY7tCsIgFIb/7yqEtVAymG5QC7yXfaAgbDqcxrp600XUYkH9ORx9n@ecY7y03DRWajUxL5hwqosPOKNaihpObggtY3Q/h4IJlgI2fQ/nTKqMXChCApqeB2bXowNBvmEdJJggkAKavGbDBiWPiOI4hix16SN6@g1d/SxitS3GqPiIkjZkZVCP0c5xUdEzJjmt8jLiQGmgnR2dffdatGjkuc9w64yaAB9GewNX3lltNvjV5X94EeXGhCwFG1d8j/0d "R – Try It Online")
...but then I read the comments more carefully and realised that it's Ok to output nothing, or rubbish, or to error for falsy inputs. That makes it much easier!
[Answer]
# [Vyxal](https://github.com/Lyxal/Vyxal), 30 bytes
```
λĠvL&›Dƛ2>;A$Ḣ∧[x|u£];†h2=[¥|u
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=%CE%BB%C4%A0vL%26%E2%80%BAD%C6%9B2%3E%3BA%24%E1%B8%A2%E2%88%A7%5Bx%7Cu%C2%A3%5D%3B%E2%80%A0h2%3D%5B%C2%A5%7Cu&inputs=%5B2%2C2%2C1%2C1%2C2%2C1%2C2%5D&header=&footer=)
A big mess.
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~81~~ 77 bytes
```
f=->a,i=1{a[1]&&a-[1,2]==[]?f[a.chunk{|x|x}.map{|x,y|y.size},i+1]:a==[2]?i:0}
```
[Try it online!](https://tio.run/##ldHdaoMwFAfw@z3FAaFsLBFPlK0WbF9idyEXWYks9MuqAV312V2i7ebGWqwBCSG/cw7/5Oa97ro0oUtJdIInyVHMZpJyJEwkCRerlEt//WH2m1NTNVXr72Rmd6Ruar/Qn6ol@hnFQtq7TKz0Imi7DFJuPQoBUz4PEA45sIezY3ZZ3f/7/ZU6Hrw493rV/Tr5qeLB3Ln4202ekzkXDm6qci5wDs/ujn7jXG4l8deFzkWDi6yjLoCAhDGbEwxYHET/FfKA9g0lmL0@GgWp3BY1HEyZmdK/pIWTp6A4mvzyLjdtP8HjW67XG62KElQld9lWPQ11Jgc@6o13vBLF7gs "Ruby – Try It Online")
**Edit:** Saved 4 bytes by converting to recursive lambda.
Returns 1-indexed number of iterations or 0 as falsey.
Makes use of Ruby enumerable's chunk method, which does exactly what we need - grouping together consecutive runs of identical numbers. The lengths of the runs constitute the array for the next iteration. Keeps iterating while the array is longer than 1 element and no numbers other than 1 and 2 have been encountered.
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 45 bytes
```
L?||qb]1!lb-{b,1 2_1?q]2b1Z.V0IKy~QhMrQ8*KhbB
```
[Try it online!](https://tio.run/##K6gsyfj/38e@pqYwKdZQMSdJtzpJx1DBKN7QvjDWKMkwSi/MwNO7si4ww7co0ELLOyPJ6f//aEMdIyA01DEEk0ZIJETEMBYA "Pyth – Try It Online")
This is probably still golfable.
It's definitely golfable if `.?` worked the way I hoped it would (being an `else` for the innermost structure instead of the outermost)
```
L?||qb]1!lb-{b,1 2_1?q]2b1Z # A lambda function for testing an iteration of the shortening
L                           # y=lambda b:
 ?                          # if
    qb]1                    #    b == [1]
   |    !lb                 #      or !len(b)
  |         {b              #        or b.deduplicate()
           -  ,1 2          #             .difference([1,2]):
                  _1        #               return -1
                    ?q]2b1Z # else: return 1 if [2] == b else Z (=0)
.V0                         # for b in range(0,infinity):
   IKy~Q                    # if K:=y(Q :=        (applies y to old value of Q)
        hM                  #    map(_[0],
          rQ8               #               run_length_encode(Q)):
             *Khb           #    print(K*(b+1))
                 B          #    break
```
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, 71 bytes
```
$_.=$";s/(. )\1*/$&=~y|12||.$"/ge&$.++while/^([12] ){2,}$/;$_=/^2 $/*$.
```
[Try it online!](https://tio.run/##BcFbCsIwEAXQrYRyKX3YmUygXyFLcAVq@xW0UGxoBBGjS3c8J8V9HVUxU0DlMzdk2rN0jDp8X0VcKYSKr7EG9f3ztqyRp@Yk7mLatzt8wB5z4MkZcAdSjxysV2fkt6XHst2zDseRrFgd0h8 "Perl 5 – Try It Online")
`1`-indexed. Outputs `0` for falsy.
]