CJam(精度50016828/100000000,6字节)
{+1&!}
(对于非CJammers使用ALGOL样式的伪代码:)return ((x + y) & 1) == 0
。
这比我尝试过的其他两种简单的启发式方法中的任何一种都要好。它甚至比后两个最佳组合更好。
得分假设我的矩阵计算部分正确。欢迎独立验证。我将计算的奇偶校验位托管在http://cheddarmonk.org/codegolf/PPCG95604-parity.bz2(下载8MB,提取到50MB文本文件:由于矩阵关于主对角线是对称的,因此我只包括了每个线从主对角线开始,因此您必须进行偏移,转置和按位或以获得完整的正方形)。
我用来计算它的代码是Java。它非常直接地使用该定义,但是具有设置的数据结构,该数据结构对范围进行游程编码,以便快速跳至下一个允许的值。可能会进行进一步的优化,但是它可以在大约两个小时和1.5GB的堆空间中在我的老式桌面上运行。
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
是一个05AB1E,它随机输出true或false。假设0为true,1为false,理论上我的程序在大约50%的时间内都是正确的。这是有效的条目吗?