CJam(精度50016828 / 100000000、6バイト)
{+1&!}
(CJammer以外のALGOLスタイルの擬似コード:)return ((x + y) & 1) == 0。
これは、私が試した他の20個の単純なヒューリスティックのいずれよりも優れたパフォーマンスを発揮します。次の2つの最高の組み合わせとの組み合わせよりも優れています。
スコアは、マトリックスの計算されたセクションが正しいと想定しています。独立した検証を歓迎します。計算されたパリティビットをhttp://cheddarmonk.org/codegolf/PPCG95604-parity.bz2でホストしています(8MBのダウンロード、50MBのテキストファイルへの抽出:マトリックスは主対角線に関して対称であるため、それぞれを含めました)メインの対角線から始まる線なので、完全な正方形を得るにはオフセット、転置、ビット単位のORを行う必要があります)。
計算に使用したコードはJavaです。定義はかなり簡単に使用されますが、ランレングスが範囲をエンコードするデータ構造を設定しているため、次の許可された値にすばやくスキップできます。さらに最適化することも可能ですが、適度に古いデスクトップで約2時間、1.5 GBのヒープ領域で実行されます。
import java.util.*;
public class PPCG95604Analysis
{
    static final int N = 30000;
    public static void main(String[] args) {
        Indicator[] cols = new Indicator[N];
        Indicator[] diag = new Indicator[N];
        for (int i = 0; i < N; i++) {
            cols[i] = new Indicator();
            diag[i] = new Indicator();
        }
        int maxVal = 0;
        for (int y = 0; y < N; y++) {
            Indicator row = new Indicator(cols[y]);
            for (int x = y; x < N; x++) {
                Indicator col = cols[x];
                Indicator dia = diag[x - y];
                Indicator.Result rr = row.firstCandidate();
                Indicator.Result rc = col.firstCandidate();
                Indicator.Result rd = dia.firstCandidate();
                while (true) {
                    int max = Math.max(Math.max(rr.candidateValue(), rc.candidateValue()), rd.candidateValue());
                    if (rr.candidateValue() == max && rc.candidateValue() == max && rd.candidateValue() == max) break;
                    if (rr.candidateValue() != max) rr = rr.firstCandidateGreaterThan(max - 1);
                    if (rc.candidateValue() != max) rc = rc.firstCandidateGreaterThan(max - 1);
                    if (rd.candidateValue() != max) rd = rd.firstCandidateGreaterThan(max - 1);
                }
                if (y >= 20000 && x >= 20000) System.out.format("%d", rr.candidateValue() & 1);
                maxVal = Math.max(maxVal, rr.candidateValue());
                rr.markUsed();
                rc.markUsed();
                rd.markUsed();
            }
            if (y >= 20000) System.out.println();
        }
    }
    static class Indicator
    {
        private final int INFINITY = (short)0xffff;
        private final int MEMBOUND = 10000;
        private short[] runLengths = new short[MEMBOUND];
        public Indicator() { runLengths[1] = INFINITY; }
        public Indicator(Indicator clone) { System.arraycopy(clone.runLengths, 0, runLengths, 0, MEMBOUND); }
        public Result firstCandidate() {
            // We have a run of used values, followed by a run of unused ones.
            return new Result(1, 0xffff & runLengths[0], 0xffff & runLengths[0]);
        }
        class Result
        {
            private final int runIdx;
            private final int runStart;
            private final int candidateValue;
            Result(int runIdx, int runStart, int candidateValue) {
                this.runIdx = runIdx;
                this.runStart = runStart;
                this.candidateValue = candidateValue;
            }
            public int candidateValue() {
                return candidateValue;
            }
            public Result firstCandidateGreaterThan(int x) {
                if (x < candidateValue) throw new IndexOutOfBoundsException();
                int idx = runIdx;
                int start = runStart;
                while (true) {
                    int end = start + (0xffff & runLengths[idx]) - 1;
                    if (end > x) return new Result(idx, start, x + 1);
                    // Run of excluded
                    start += 0xffff & runLengths[idx];
                    idx++;
                    // Run of included
                    start += 0xffff & runLengths[idx];
                    idx++;
                    if (start > x) return new Result(idx, start, start);
                }
            }
            public void markUsed() {
                if (candidateValue == runStart) {
                    // Transfer one from the start of the run to the previous run
                    runLengths[runIdx - 1]++;
                    if (runLengths[runIdx] != INFINITY) runLengths[runIdx]--;
                    // May need to merge runs
                    if (runLengths[runIdx] == 0) {
                        runLengths[runIdx - 1] += runLengths[runIdx + 1];
                        for (int idx = runIdx; idx < MEMBOUND - 2; idx++) {
                            runLengths[idx] = runLengths[idx + 2];
                            if (runLengths[idx] == INFINITY) break;
                        }
                    }
                    return;
                }
                if (candidateValue == runStart + (0xffff & runLengths[runIdx]) - 1) {
                    // Transfer one from the end of the run to the following run.
                    if (runLengths[runIdx + 1] != INFINITY) runLengths[runIdx + 1]++;
                    if (runLengths[runIdx] != INFINITY) runLengths[runIdx]--;
                    // We never need to merge runs, because if we did we'd have hit the previous case instead
                    return;
                }
                // Need to split the run. From
                //   runIdx: a+1+b
                // to
                //   runIdx: a
                //   runIdx+1: 1
                //   runIdx+2: b
                //   runIdx+3: previous val at runIdx+1
                for (int idx = MEMBOUND - 1; idx > runIdx + 2; idx--) {
                    runLengths[idx] = runLengths[idx - 2];
                }
                runLengths[runIdx + 2] = runLengths[runIdx] == INFINITY ? INFINITY : (short)((0xffff & runLengths[runIdx]) + runStart - 1 - candidateValue);
                runLengths[runIdx + 1] = 1;
                runLengths[runIdx] = (short)(candidateValue - runStart);
            }
        }
    }
}
               
              
01.Rランダムにtrueまたはfalseを出力する05AB1Eです。0をtrue、1をfalseとすると、私のプログラムは理論的には50%の確率で正しいでしょう。これは有効なエントリですか?