[Question]
  [
A complete [deterministic finite automaton](https://en.wikipedia.org/wiki/Deterministic_finite_automaton) is a machine, with some states. Each state in the automaton has, for each character in the alphabet, a pointer to a state (not necessarily a different one). The automaton starts at some state, and then reads a string, character by character. For each character, the automaton moves to the pointer of its current state for the character.
For a given automaton, a [synchronizing word](https://en.wikipedia.org/wiki/Synchronizing_word) is a string which will bring the automaton to the same state, regardless of which state it started in.
For example, the following automaton:
[![enter image description here](https://i.stack.imgur.com/rJccR.png)](https://i.stack.imgur.com/rJccR.png)
Has `0100` as a synchronizing word, which synchronizes all states to 2.
Not all automata have a synchronizing word. For example, the following automaton:
[![enter image description here](https://i.stack.imgur.com/p8OZU.png)](https://i.stack.imgur.com/p8OZU.png)
Doesn't have any synchronizing word - if the length of the string is even then 0 will stay in 0 and 1 will stay in 1, and if it's odd they will swap - in any case, they won't go into the same state.
Your challenge is to write the shortest program you can that checks, given a complete automaton over an alphabet with two characters, if there exists a synchronizing word for it.
# Test cases
Using a 0-indexed, 2Xn array.
```
[[0, 1], [0, 1]] -> true
[[1, 1], [0, 0]] -> false
[[0, 0], [1, 1]] -> false
[[4, 1], [0, 3], [0, 0], [0, 1], [4, 3]] -> true
[[2, 1], [3, 4], [0, 4], [2, 1], [0, 3]] -> true
[[4, 4], [0, 4], [2, 1], [0, 3], [0, 0]] -> false
[[8, 5], [0, 8], [0, 0], [8, 2], [2, 6], [5, 2], [3, 8], [7, 3], [8, 4], [3, 0]] -> true
[[9, 2], [8, 4], [2, 5], [6, 9], [8, 9], [9, 5], [4, 0], [4, 2], [0, 7], [2, 1]] -> true
[[5, 0], [3, 7], [9, 2], [9, 0], [1, 8], [8, 4], [6, 5], [7, 1], [2, 4], [3, 6]] -> true
[[5, 1], [4, 9], [8, 1], [8, 6], [2, 3], [7, 0], [2, 3], [5, 6], [4, 9], [7, 0]] -> false
[[6, 3], [1, 1], [7, 5], [7, 1], [4, 5], [6, 6], [4, 6], [5, 1], [3, 4], [2, 4]] -> false
```
# Rules
* You can use any reasonable I/O format. In particular, any of the following input methods are allowed:
	+ A map, multidimensional array, or array of maps, denoting, for each state and character, to which state the automaton transitions. The states can be either 0-indexed or 1-indexed.
	+ Any builtin directed graph object which can support multiedges, self-loops, and labeled edges.
	+ Any builtin DFA object.
	+ You can choose any two characters to be the alphabet.
* You can output any two distinct values, or a truthy/falsey (or reversed) value in your language.
* You may **not** assume Černý's conjecture (which states that if there exists a synchronizing word, there must be one of length \$(n-1)^2\$).
* [Standard loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are disallowed.
  
[Answer]
# [Python](https://www.python.org), ~~92~~ 91 bytes
```
f=lambda a,s,n=0:n<len(s)**3and any(f(a,[a[t][d]for t in s],n+1)for d in"01")or len({*s})<2
```
[Attempt This Online!](https://ato.pxeger.com/run?1=fZG_asMwEIfpqqcQymI5V9AfD8HEa58gm_BwrWNqcJRgKUMwfpIuWdJ3ap-milyDwU0Xcfdx-vRD9_F5uvj3o71eb2dfP2--TF20eHitkCI4sIXI7bbd28TxNNVoK4r2ktQJgkHjS1OV9bGjnjaWuhLsWvJ7X4WeCcl4qO-X-9QNfKvGJ76f3lYv2Lo9aWhBjQBZEgxVTygVec8EyyUwGc4BApIjEhGJgQzk1DXWxwwN54Q81oilRj7UrHbd-Z9If7gmtHRNFlCgIVu41G-ImUtHlEWk5voR6Xl6FVE2n9KLEONfT2v9AQ)
Takes in an automaton `a` which is a dictionary of dictionaries where `a[x][c]` describes the state to travel to from state `x` given character `c`, and an array `s` which contains all of the states of the automaton. The characters in the alphabet are the strings `0` and `1`.
This code does a very inefficient brute force iteration over all possible words with length less than \$n^3\$ (where \$n\$ is number of states).
---
-1 byte from @Steffan
# [Python](https://www.python.org), 87 bytes
```
f=lambda a,s,q,n=0:n<q**3and any(f(a,{a[t][d]for t in s},q,n+1)for d in"01")or len(s)<2
```
[Attempt This Online!](https://ato.pxeger.com/run?1=fZFLasMwEIbpVqcYlI2VTEEPF4KJtz1BoQvjxRTH1NRVEltZBOOTdJNNe6f2NFXkGkzz2AzDx_DNP9LH1_bgXjf2ePzcu_J--f1cpjW9vxQEhC3u0KYysavdfG7IFkD2EJURYUeZy7MiLzcNOKgstP1pdqHEiRSecKm48H29tlErVnrQ_9y9zR6pbtesghQyiSpn5LuOAcik45InCrnytUeP1IBkQLJnPds2lXUhQoVaCMaui-S5SN0QzZ6a_Y1YF2wjumQbPajRYHxm039BJjYTUByQni4YkJleoAOKp1Pmf4wHIYY3H7_2Fw)
Same as above, except it also takes in a parameter `q` which describes the number of states in the automaton.
[Answer]
# [Haskell](https://www.haskell.org/), 73 bytes
```
r!w|let[_]%_=1>0;s%y=all(/=s)y&&or[[u|u<-w,elem u$k<$>s]%(s:y)|k<-r]=w%[]
```
[Try it online!](https://tio.run/##tY3BToQwFEX3fsWdBCZtQlFgJ5SNW92b1IZUqEoozKQdgkT8dStDTFzMxo2rl3vuyX1vynXaGO/tblqMPolKhhVPypvchTNXxpBr7ui83x@sEOMyFmyKtNE9xqArgtLJkLjbmS5dwazkUyik71U7gKM5XAG9Oj5UIDjadjghxjjUo7UzyI6CIlgNCBDRNjKCSOI4k/TMopU91cppfCRgJdIc1fkmn3/1IvzwdMs5tj7LkW3ef@68szK9xBv5jW2zLl@a0n/VL0a9Os8e71X/3Ki79fs3 "Haskell – Try It Online")
Takes input as a list of states, and a list of transitions as functions between states.
Not complicated, does a depth first search.
[Answer]
# Python3, 471 bytes:
```
E=enumerate
def f(n,m,c=[]):
 yield c,n
 for i,(I,a)in E(m[n]):M=eval(str(m));del M[n][i];yield from f(a,M,c+[(a,I)])
def M(m,B,p):
 if''==p:return B
 return M(m,dict(m[B])[int(p[0])],p[1:])
def F(m):
 r={}
 for i,_ in E(m):
  for c,n in f(i,m,[(i,-1)]):
   if c[-1][-1]!=-1 or c[-1][1]:r[n]=r.get(n,[])+[(i,c)]
 for n in r:
  if not(V:={i for i,_ in E(m)})-{a for a,_ in r[n]}:
   if any(all(M(m,B,''.join(str(K)for _,K in c[1:]))==n for B in V)for _,c in r[n]):return 1
```
[Try it online!](https://tio.run/##fVTLbtswEDxHX8H6IrKhDcuSnwF7MJAAQeAec2EJQ5WllIVECTRdIAjy7S5JLW01LWrAXmt2d2Z2Ral7NT9ala46fT7fs1KdmlLnpowOZYUqrGhDC8YF2UToVZb1ARVURahqNZIUP9KcSIXuccOVLdmx8lde46PRuCHk7lDWaGcTXIq7vrfSbWNJc7qjxS238ZEI4pV2uKFb2jkZWcUxY91Gl@akFdpGCP65moMsjFXbCsKlMrjjU0EE7XiyAaIHK21JNHt7Dzb3qPfocA/ZERxUYWmn4/Z3nBA/IbLiqODjRLjvJzZOkCv3QCI22g7D9OSlNHYvdie3rrcgohfynNqxWBLVGvy8YW/yo4d3Mn7LPZj3oCN9D9q5esV5XeN@HXE8@dlK5Rf6RFzPnj65nsLPSxhTnmnrsGcoKAIpCRtMzrLpWm1QfjR@R6bdv@BnO/ANVHD@@R5LInqznk1E0ZGNRiPOpxQlgqI@CjT@gow@lRHnyTUx7RNVXh9dxiM2k1xaQia79qSX3kBuY@bwocgMEilFGRT6OBsSDRuy/xX@0@2KojlkVkNPFp8Bw8LFOVynULcExhUopRdmsLKGhtXVihdaULQG3Mc14BkIZ9BnjSwvIwyJ51CYQkEQWl/3vhoKL0BgCbuYXR0vPhKH2xAcJhAX0JgC0XR4PYd86Fv@teQFVIZDs/xgKbvuJjCFpf9x/731AbM9otHl1FayNqXGX1tVUnScHLtaGhx/UzFxhz2n6DtiSAbckcQkuum0e5U8YP9Y2GdkYrP2HVjv/dssJ/Zz/g0)
A little longer than the other solutions, but solves all the test cases pretty quickly. Returns `1` when a synchronizing word exists and `None` when one does not exist.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 21 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
WZ€ị®ẎƊ⁸©L*3¤Ð¡ẎZ€ẎEƇ
```
A monadic Link that accepts a 1-indexed list of nodes, each of which is a pair of positive integers identifying the nodes pointed to by each of the two transition characters (i.e. like the test cases in the question but incremented by one) and yields an empty list (falsey) if no synchronising word exists or a non-empty list (truthy) if one does.
**[Try it online!](https://tio.run/##y0rNyan8/z886lHTmoe7uw@te7ir71jXo8Ydh1b6aBkfWnJ4wqGFQCGw9K4@12Pt////j4421FEwitVRgNCxAA "Jelly – Try It Online")**  
...Too slow for the length 5 and greater tests, but since all of those that do have synchronising words are much shorter [this](https://tio.run/##dVExS8QwGN3vV2RwESK0TZqmCDq5uYuGDg7nIJ1OHdyqy4HCIU4ddBBcBHHWc@vh/Y/mj9Q0fUl6gtP35eV97718OZ@W5XXXHZ3o2/f2@775aJeL9Z2@@WzeDnVVN6@rh@bFYPZ@uThYz7ufx/ar3tXVE9nZI7p67tvL2dXUtKY7K08vhrZezbf2t4@7TikVURIXlAy1mFCl4oBEA2I7g8SewwOHea5TMZX3uGUmQBglHAxbk7GC0/yfsZFHUpICkWN3gyeYFH1NcWbgZVCScGBeMQdTBm/rICjJgduaA@dw5JgzCTKf2SqmYDDcOIc87FKOHQWUM7w6CRmFV3S7dZliVIEJBoVofE5x7@Yy/2oBhvvx7E8GHrbgFNxeN/7UZi0mxS8), which searches only up to length \$n+2\$ gives the correct output for all test cases.
### How?
Full brute force - generates the list of nodes (by starting node) pointed to by all words from length one up to length \$n^3+1\$ (more than the current known upper bound) and keeps any that are all equal.
```
WZ€ị®ẎƊ⁸©L*3¤Ð¡ẎZ€ẎEƇ - Link: list of pairs of integers, A
W                     - wrap A in a list
             Ð¡       - collect and repeat... (includes the original wrapped A)
            ¤         - ...number of times: nilad followed by links as a nilad:
       ⁸              -                       chain's left argument = A
        ©             -                       (copy to the register)
         L            -                       length
          *3          -                       to the third power
      Ɗ               - ...action: last three links as a monad:
 Z€                   -              transpose each
   ị®                 -              index into the register
     Ẏ                -              tighten
               Ẏ      - tighten
                Z€    - transpose each
                  Ẏ   - tighten
                    Ƈ - keep those for which:
                   E  -   all equal? (i.e. all point to the same node)
```
---
**20 bytes** if a full program can output nothing if no synchronising word exists or a (not consistent) list representation if one does - uses the same method:
```
WZ€ị³ẎƊ³L*3¤Ð¡ẎZ€ẎEƇ 
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~100~~ 91 bytes
```
->s{a,*k=r=s.transpose;r|=k|=a.map{|i|s[i]}.transpose-r while a=k.pop;r.any?{|x|!(x|x)[1]}}
```
[Try it online!](https://tio.run/##dVLLasMwELz7K1QKJSmK8VOyCWo/ROigQkKN28TILXWw/O2urYwjp9DToNHs7OxK5vvtMh7FuHtpe02fa2FEG34ZfWqbc3vYGytqK3T4qZveVraVlRr89c6Qn/fq40C0qMPm3OxNqE@X19529mHT2W4rYzUMY0NkIGVESawouaKiE5N5JgVGN8WE2cw7ZQImpSSDwmGydnDKgpIcTLH2nPgEFWzGHOcUOo4MBZzTuc45llAWvqfrwCgpwTsswWfomKFuSsBvWSfHRzk3j9CEozQBOj5GqKUlgzXHuIkPyZQK1Pw8m6fjNgiuq479WjBE5J398v9f5V1t7p9jGTgGMlSmSBetzznulzp@c2RQLDn5n/kyv@LFYXm0u2/g9rCaf/wF "Ruby – Try It Online")
]