<p>There are <code>8</code> prison cells in a row and each cell is either occupied or vacant.</p>

<p>Each day, whether the cell is occupied or vacant changes according to the following rules:</p>

<ul>
	<li>If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied.</li>
	<li>Otherwise, it becomes vacant.</li>
</ul>

<p><strong>Note</strong> that because the prison is a row, the first and the last cells in the row can&#39;t have two adjacent neighbors.</p>

<p>You are given an integer array <code>cells</code> where <code>cells[i] == 1</code> if the <code>i<sup>th</sup></code> cell is occupied and <code>cells[i] == 0</code> if the <code>i<sup>th</sup></code> cell is vacant, and you are given an integer <code>n</code>.</p>

<p>Return the state of the prison after <code>n</code> days (i.e., <code>n</code> such changes described above).</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> cells = [0,1,0,1,1,0,0,1], n = 7
<strong>Output:</strong> [0,0,1,1,0,0,0,0]
<strong>Explanation:</strong> The following table summarizes the state of the prison on each day:
Day 0: [0, 1, 0, 1, 1, 0, 0, 1]
Day 1: [0, 1, 1, 0, 0, 0, 0, 0]
Day 2: [0, 0, 0, 0, 1, 1, 1, 0]
Day 3: [0, 1, 1, 0, 0, 1, 0, 0]
Day 4: [0, 0, 0, 0, 0, 1, 0, 0]
Day 5: [0, 1, 1, 1, 0, 1, 0, 0]
Day 6: [0, 0, 1, 0, 1, 1, 0, 0]
Day 7: [0, 0, 1, 1, 0, 0, 0, 0]
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> cells = [1,0,0,1,0,0,1,0], n = 1000000000
<strong>Output:</strong> [0,0,1,1,1,1,1,0]
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>cells.length == 8</code></li>
	<li><code>cells[i]</code>&nbsp;is either <code>0</code> or <code>1</code>.</li>
	<li><code>1 &lt;= n &lt;= 10<sup>9</sup></code></li>
</ul>

class Solution {
public:
    string ConvertCellsToString(vector<int>& cells){
        string ans;
        for(auto& cell:cells){
            ans.push_back(cell + '0');
        }
        
        return ans;
    }
    
    vector<int> ConvertStringToCell(string input){
        vector<int> ans;
        
        for(char c:input){
            ans.push_back(c - '0');
        }
        
        return ans;
    }
    
    string FindNext(string cur){
        string ans = "00000000";
        for(int i = 1; i <= 6; i++){
            ans[i] = (cur[i-1]==cur[i+1])?'1':'0';
        }
        return ans;
    }
    vector<int> prisonAfterNDays(vector<int>& cells, int n) {
        unordered_set<string> hm;
        vector<string> sequences;
        string pre = ConvertCellsToString(cells);
        
        while(hm.find(pre) == hm.end()){
            hm.insert(pre);
            sequences.push_back(pre);
            pre = FindNext(pre);
        }
        
        int cycle_entry = -1;
        for(int i = 0; i < sequences.size();i++){
            if (sequences[i] == pre){
                cycle_entry = i;
            }
        }
        
        int cycle_size = sequences.size() - 1;
        int residual = sequences.size() - cycle_size;
        
        if (cycle_entry ==  0){
            // n++;
            cycle_size++;
        }
        
        
        int ans_idx = n % cycle_size;
        
        // for(auto& sequence:sequences){
        //     cout<<sequence<<endl;
        // }
        
        // cout<<ans_idx<<endl;
        
        if (cycle_entry == 0){
            return ConvertStringToCell(sequences[ans_idx]);
        }
        
        return ConvertStringToCell(ans_idx == 0? sequences.back():sequences[ans_idx]);
    }
};


// can't do simulation. 
16400