public class Solution
{
public bool ValidUtf8(int[] data)
{
var itor = new IntArrItor(data);
while (itor.MoveNext())
{
var type = Foo(itor);
if (type < 0) return false;
for (var i = 0; i < type; i++)
if (!itor.MoveNext() || (itor >> 6 ^ 0b10) != 0) return false;
}
return true;
}
static int Foo(int num)
{
if ((num >> 3 ^ 0b11110) == 0) return 3;
if ((num >> 4 ^ 0b1110) == 0) return 2;
if ((num >> 5 ^ 0b110) == 0) return 1;
if ((num >> 7 ^ 0b0) == 0) return 0;
return -1;
}
class IntArrItor : IEnumerator<int>
{
int[] arr;
int curr = -1;
public IntArrItor(int[] arr) => this.arr = arr;
public int Current => arr[curr];
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext() => ++curr < arr.Length;
public void Reset() => curr = -1;
public static implicit operator int(IntArrItor itor) => itor.Current;
}
}