CJam (정확도 50016828/100000000, 6 바이트)
{+1&!}
(CJammer 이외의 경우 ALGOL 스타일 의사 코드 :) return ((x + y) & 1) == 0
.
이것은 내가 시도한 다른 24 가지 간단한 휴리스틱 중 하나보다 우수합니다. 다음 두 가지 최고의 조합과 비교하면 훨씬 좋습니다.
점수는 계산 된 행렬 섹션이 정확하다고 가정합니다. 독립적 인 확인을 환영합니다. http://cheddarmonk.org/codegolf/PPCG95604-parity.bz2 에서 계산 된 패리티 비트를 호스팅하고 있습니다 . (8MB 다운로드, 50MB 텍스트 파일로 추출 : 매트릭스는 기본 대각선에 대해 대칭이므로 각 블록 만 포함했습니다 주 대각선에서 시작하므로 전체 정사각형을 얻으려면 오프셋, 조옮김 및 비트 OR을 사용해야합니다.
내가 계산하는 데 사용한 코드는 Java입니다. 정의를 매우 간단하게 사용하지만 실행 길이를 인코딩하는 세트 데이터 구조를 사용하여 다음 허용 값으로 빠르게 건너 뛸 수 있습니다. 추가 최적화가 가능하지만 약 2 시간 및 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
무작위로 true 또는 false를 출력하는 05AB1E입니다. 0은 true이고 1은 false입니다. 내 프로그램은 이론적으로 ~ 50 %의 시간이 정확합니다. 유효한 항목입니까?