Загрузка данных


using System;
using System.Linq;

class Program {
    static uint lfsr(uint s, int n, int[] t) {
        uint b = 0;
        foreach (int p in t) if (p != n) b ^= (s >> (p - 1)) & 1;
        return (s >> 1) | (b << (n - 1));
    }

    static bool g(bool a, bool b, bool c) => (a & b) ^ (a & c) ^ (b & c);

    static void Main() {
        var r1 = 1U; var r2 = 1U; var r3 = 0xAAAAAAAAU;
        int n = 1000000;
        bool[] s = new bool[n];
        for (int i = 0; i < n; i++) {
            r1 = lfsr(r1, 16, new[]{16,5,3,2,0});
            r2 = lfsr(r2, 8, new[]{8,4,3,2,0});
            r3 = lfsr(r3, 32, new[]{32,7,6,2,0});
            s[i] = g((r1 & 1)==1, (r2 & 1)==1, (r3 & 1)==1);
        }

        // Тест 1: частотный
        int n0 = s.Count(x => !x), n1 = n - n0;
        double x1 = (n0 - n1) * (n0 - n1) / (double)n;
        Console.WriteLine("1: " + (x1 <= 3.8415 ? "OK" : "FAIL") + " X1=" + x1);

        // Тест 2: серии
        int n00=0,n01=0,n10=0,n11=0;
        for (int i=0;i<n-1;i++) {
            if (!s[i]&&!s[i+1]) n00++; else if(!s[i]&&s[i+1]) n01++;
            else if(s[i]&&!s[i+1]) n10++; else if(s[i]&&s[i+1]) n11++;
        }
        double x2 = 4.0/(n-1)*(n00*n00+n01*n01+n10*n10+n11*n11) - 2.0/n*(n0*n0+n1*n1) + 1;
        Console.WriteLine("2: " + (x2 <= 5.9915 ? "OK" : "FAIL") + " X2=" + x2);

        // Тест 3: обобщенный (m=3)
        int m=3, k=n/m; int[] c=new int[8];
        for(int i=0;i<k;i++){ int idx=0; for(int j=0;j<m;j++) idx=(idx<<1)|(s[i*m+j]?1:0); c[idx]++; }
        double x3 = 8.0/k * c.Sum(x=>x*x) - k;
        Console.WriteLine("3: " + (x3 <= 14.0671 ? "OK" : "FAIL") + " X3=" + x3);

        // Тест 4: последовательности
        double x4=0; int K=4;
        for(int i=1;i<=K;i++){ double e=(n-i+3)/Math.Pow(2,i+2); int b=0,g=0,l=0;
            for(int j=0;j<n;j++){ if(s[j]) l++; else { if(l==i) b++; l=0; } } if(l==i) b++;
            l=0; for(int j=0;j<n;j++){ if(!s[j]) l++; else { if(l==i) g++; l=0; } } if(l==i) g++;
            x4 += (b-e)*(b-e)/e + (g-e)*(g-e)/e;
        }
        Console.WriteLine("4: " + (x4 <= 9.4877 ? "OK" : "FAIL") + " X4=" + x4);

        // Тест 5: автокорреляция
        int d=n/4, A=0; for(int i=0;i<n-d;i++) if(s[i]!=s[i+d]) A++;
        double x5 = 2*(A - (n-d)/2.0)/Math.Sqrt(n-d);
        Console.WriteLine("5: " + (Math.Abs(x5) <= 1.96 ? "OK" : "FAIL") + " X5=" + x5);
    }
}