首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >矩阵性质X的重温(或X的喜悦)

矩阵性质X的重温(或X的喜悦)
EN

Code Golf用户
提问于 2015-04-26 10:01:42
回答 1查看 1K关注 0票数 10

这个挑战部分是算法挑战,部分是优化挑战,部分是最快的代码挑战。

T矩阵由其第一行r和第一列c完全指定。矩阵中的每个剩余元素只是对角向上和左对角元素的一个副本。那是M[i,j] = M[i-1,j-1]。我们将允许T矩阵不成正方形。但是,我们总是假设行数不超过列数。例如,考虑下面的3x5T矩阵。

代码语言:javascript
运行
复制
10111
11011
11101

如果一个矩阵包含两个具有相同(向量)和的非相同索引的非空列集,则它具有X的性质。一个或多个列的向量和只是它们的列的按元素进行的求和。即包含x元素的两个或多个列的总和,每个列都是包含x元素的另一个列。一列的和与列本身无关。

上面的矩阵具有属性X,因为第一列和最后一列是相同的。恒等矩阵不具有性质X。

如果我们去掉上面矩阵的最后一列,我们就得到了一个例子,它没有属性X,会给出4/3的分数。

代码语言:javascript
运行
复制
1011
1101
1110

任务

其任务是编写代码,查找带有二进制条目且没有属性X的最高得分T矩阵。为了清楚起见,具有二进制条目的矩阵具有其每个条目都为0或1的属性。

评分

您的分数将是数字列除以您的最佳评分矩阵中的行数。

领带断路器

如果两个答案有相同的分数,提交的第一个获胜。

在(非常)不可能的情况下,某人找到了一种获得无限分数的方法,这种解决方案的第一个有效证据将被接受。在更不可能的情况下,你可以找到一个有限矩阵的最优性的证明,我当然也会奖励胜利。

提示

求无性质X的最高评分矩阵的所有答案在这里都是有效的,但它们不是最优的。这里有没有性质X的T矩阵,它们不是循环的。

例如,有一个7×12T矩阵没有性质X,但没有这样的循环矩阵。

21/11将击败这次和上一次挑战的所有当前答案。

语言和库

对于Linux,您可以使用任何具有免费编译器/解释器/等的语言,也可以使用对Linux也可以免费使用的任何库。

奖励:第一个答案得分大于2分,立即获得200分赏金奖励。东·霍佩尔现在已经做到了这一点!

当前领导板

  • C++。按吨医院评分31/15
  • Java语言。彼得·泰勒( Peter Taylor )得分36/19
  • 哈斯克尔。亚力山大-布雷特得分14/8
EN

回答 1

Code Golf用户

发布于 2015-04-29 21:18:16

C

这是一个有效的答案,而且比Haskell的记忆效率要高得多。不幸的是,我的电脑仍然太慢,无法在任何合理的时间内达到14/8以上。

尝试使用gcc -std=c99 -O2 -fopenmp -o matrices.exe matrices.c进行编译,并使用matrices.exe width height或类似的方法运行。输出是一个整数,其位数构成所述矩阵的基础,例如:

代码语言:javascript
运行
复制
$ matrices.exe 8 14
...
valid i: 1650223

然后,自1650223 = 0b110010010111000101111以来,所讨论的矩阵是:

代码语言:javascript
运行
复制
0 0 1 1 1 0 1 0 0 1 0 0 1 1
0 ...
1 ...
0
1
1
1
1

如果一个拥有8个核心和时间的人想要运行一段时间,我认为会有一些好的结果:)

代码语言:javascript
运行
复制
#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;
}
票数 1
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/49218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档