这个挑战部分是算法挑战,部分是优化挑战,部分是最快的代码挑战。
T矩阵由其第一行r
和第一列c
完全指定。矩阵中的每个剩余元素只是对角向上和左对角元素的一个副本。那是M[i,j] = M[i-1,j-1]
。我们将允许T矩阵不成正方形。但是,我们总是假设行数不超过列数。例如,考虑下面的3x5T矩阵。
10111
11011
11101
如果一个矩阵包含两个具有相同(向量)和的非相同索引的非空列集,则它具有X的性质。一个或多个列的向量和只是它们的列的按元素进行的求和。即包含x
元素的两个或多个列的总和,每个列都是包含x
元素的另一个列。一列的和与列本身无关。
上面的矩阵具有属性X,因为第一列和最后一列是相同的。恒等矩阵不具有性质X。
如果我们去掉上面矩阵的最后一列,我们就得到了一个例子,它没有属性X,会给出4/3的分数。
1011
1101
1110
其任务是编写代码,查找带有二进制条目且没有属性X的最高得分T矩阵。为了清楚起见,具有二进制条目的矩阵具有其每个条目都为0或1的属性。
您的分数将是数字列除以您的最佳评分矩阵中的行数。
如果两个答案有相同的分数,提交的第一个获胜。
在(非常)不可能的情况下,某人找到了一种获得无限分数的方法,这种解决方案的第一个有效证据将被接受。在更不可能的情况下,你可以找到一个有限矩阵的最优性的证明,我当然也会奖励胜利。
求无性质X的最高评分矩阵的所有答案在这里都是有效的,但它们不是最优的。这里有没有性质X的T矩阵,它们不是循环的。
例如,有一个7×12T矩阵没有性质X,但没有这样的循环矩阵。
对于Linux,您可以使用任何具有免费编译器/解释器/等的语言,也可以使用对Linux也可以免费使用的任何库。
奖励:第一个答案得分大于2分,立即获得200分赏金奖励。东·霍佩尔现在已经做到了这一点!
发布于 2015-04-29 21:18:16
这是一个有效的答案,而且比Haskell的记忆效率要高得多。不幸的是,我的电脑仍然太慢,无法在任何合理的时间内达到14/8以上。
尝试使用gcc -std=c99 -O2 -fopenmp -o matrices.exe matrices.c
进行编译,并使用matrices.exe width height
或类似的方法运行。输出是一个整数,其位数构成所述矩阵的基础,例如:
$ matrices.exe 8 14
...
valid i: 1650223
然后,自1650223 = 0b110010010111000101111
以来,所讨论的矩阵是:
0 0 1 1 1 0 1 0 0 1 0 0 1 1
0 ...
1 ...
0
1
1
1
1
如果一个拥有8个核心和时间的人想要运行一段时间,我认为会有一些好的结果:)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*
* BEGIN WIKIPEDIA CODE
*/
const long long m1 = 0x5555555555555555; //binary: 0101...
const long long m2 = 0x3333333333333333; //binary: 00110011..
const long long m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
const long long m8 = 0x00ff00ff00ff00ff; //binary: 8 zeros, 8 ones ...
const long long m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
const long long m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
const long long hff = 0xffffffffffffffff; //binary: all ones
const long long h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
//This uses fewer arithmetic operations than any other known
//implementation on machines with fast multiplication.
//It uses 12 arithmetic operations, one of which is a multiply.
long long hamming(long long x) {
x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
return (x * h01)>>56; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}
/*
* END WIKIPEDIA CODE
*/
int main ( int argc, char *argv[] ) {
int height;
int width;
sscanf(argv[1], "%d", &height);
sscanf(argv[2], "%d", &width);
#pragma omp parallel for
for (
/*
* We know that there are 2^(h+w-1) T-matrices, defined by the entries
* in the first row and first column. We'll let the long long i
* represent these entries, with 1s represented by set bits.
*
* The first (0) and last (1) matrix we will ignore.
*/
long long i = 1;
i < (1 << (height+width-1))-1;
i++
) {
// Flag for keeping track as we go along.
int isvalid = 1;
/*
* Start by representing the matrix as an array of columns, with each
* non-zero matrix entry as a bit. This allows us to construct them and
* check equality very quickly.
*/
long *cols = malloc(sizeof(long)*width);
long colmask = (1 << height)-1;
for (int j = 0; j < width; j++) {
cols[j] = (i >> j) & colmask;
if (cols[j] == 0) {
//check no zero rows
isvalid = 0;
} else {
//check no duplicate rows
for (int k = 0; k < j; k++) {
if (cols[j] == cols[k]) {
isvalid = 0;
}
}
}
}
if (isvalid == 1) {
/*
* We'll also represent the matrix as an array of rows, in a
* similar manner.
*/
long *rows = malloc(sizeof(long)*height);
long rowmask = (1 << width)-1;
for (int j = 0; j < height; j++) {
rows[j] = (i >> j) & rowmask;
}
int *sums[(1 << width)];
for (long j = 0; j < 1<<width; j++) {
sums[j] = (int*)malloc(sizeof(int)*height);
}
for (
/*
* The powerset of columns has size 2^width. Again with the
* long; this time each bit represents whether the
* corresponding row is a member of the subset. The nice thing
* about this is we can xor the permutation with each row,
* then take the hamming number of the resulting number to get
* the sum.
*/
long permutation = 1;
(isvalid == 1) && (permutation < (1 << width)-1);
permutation ++
) {
for (int j = 0; j < height; j++) {
sums[permutation][j] = hamming( rows[j] & permutation);
}
for (int j = permutation-1; (isvalid == 1) && (j > -1); j--) {
if (memcmp(sums[j], sums[permutation], sizeof(int)*height) == 0) {
isvalid = 0;
}
}
}
for (long j = 0; j < 1<<width; j++) {
free(sums[j]);
}
free(rows);
}
if (isvalid == 1) {
printf ("valid i: %ld\n", i);
}
free(cols);
}
return 0;
}
https://codegolf.stackexchange.com/questions/49218
复制相似问题