在超立方体的边缘


12

您的工作将是编写一个函数或程序,该函数或程序将使用整数n>0作为输入并输出n三维超立方体的边缘列表。在图论中,边定义为连接的两个顶点(或顶点,如果愿意)。

例子1

一维超立方体是一条线,具有两个顶点,我们将其称为ab

在此处输入图片说明

因此,输出将是:

[[a, b]]

例子2

4维超立方体(或tesseract)由32条边组成,其图形如下所示

在此处输入图片说明

和输出看起来像这样

[[a, b], [a, c], [a, e], [a, i], [b, d], [b, f], [b, j], [c, d], [c, g], [c, k], [d, h], [d, l], [e, f], [e, g], [e, m], [f, h], [f, n], [g, h], [g, o], [h, p], [i, j], [i, k], [i, m], [j, l], [j, n], [k, l], [k, o], [l, p], [m, n], [m, o], [n, p], [o, p]]

规则

  • 您可以按照自己喜欢的方式命名顶点,只要该名称是唯一的即可。
  • 边缘被无向,即,[a, b][b, a]被认为是相同的边缘。
  • 您的输出不得包含重复的边。
  • 输出可以是任何明智的格式。
  • 禁止出现标准漏洞。

计分

最短的代码获胜。



所以[1,2],[2,3]等还可以吗?
Rɪᴋᴇʀ

@EasterlyIrk是的。
墨菲

边缘可以以任何顺序输出,对吗?
Luis Mendo

@DonMuesli对。
墨菲

Answers:


4

果冻,13个字节

ạ/S’
2ṗœc2ÇÐḟ

在这里尝试。对于input 3,输出为:

[[[1, 1, 1], [1, 1, 2]],
 [[1, 1, 1], [1, 2, 1]],
 [[1, 1, 1], [2, 1, 1]],
 [[1, 1, 2], [1, 2, 2]],
 [[1, 1, 2], [2, 1, 2]],
 [[1, 2, 1], [1, 2, 2]],
 [[1, 2, 1], [2, 2, 1]],
 [[1, 2, 2], [2, 2, 2]],
 [[2, 1, 1], [2, 1, 2]],
 [[2, 1, 1], [2, 2, 1]],
 [[2, 1, 2], [2, 2, 2]],
 [[2, 2, 1], [2, 2, 2]]]

我希望[1, 1, 1]等等是一个好的“名称”。

说明

第一行是在一对边的“谓词”:[A, B] ạ/S’是等于sum(abs(A - B)) - 1,这是零(假-Y)当且仅当AB在正好一个坐标不同。

第二行是主程序:

  • 2ṗ(的笛卡尔乘方[1, 2])生成所有边。
  • 使用œc2(所有大小为2的组合,无需替换)获取所有可能的对。
  • 仅保留满足先前(ÐḟÇ)谓词的元素。

1
ạ/S’2ṗœc2ÇÐḟ保存几个字节。
丹尼斯

c/P=22ṗṗ2ÇÐf也可以。
丹尼斯

聪明的“命名”方案!当然在规则之内。
墨菲

9

Python 2,54 56 62字节

lambda n:{tuple({k/n,k/n^1<<k%n})for k in range(n<<n)}

通过设置一组集合来删除重复的边,但Python要求set元素是可哈希的,因此它们会转换为元组。请注意,集合{a,b}{b,a}相等,并转换为相同的元组。xsot使用保存了2个字节n<<n

如果一组字符串为OK输出格式,则可以减少到49个字节

lambda n:{`{k/n,k/n^1<<k%n}`for k in range(n<<n)}

这给出了输出

set(['set([1, 3])', 'set([2, 3])', 'set([0, 2])', 'set([0, 1])'])

lambda n:[(k/n,k/n^1<<k%n)for k in range(n*2**n)if k/n&1<<k%n]

首先,让我们看一下该解决方案的旧版本。

lambda n:[(i,i^2**j)for i in range(2**n)for j in range(n)if i&2**j]

区间中的每个数字都[0,2^n)对应于一个顶点,该顶点的坐标由其n位二进制字符串给出。如果顶点在单个位中不同,则顶点相邻,即,如果通过对2的幂进行异或运算而从另一个顶点获得顶点。

该匿名函数通过获取每个顶点和每个位的位置来生成所有可能的边。为了避免在两个方向上都复制一条边,仅将1翻转为0。

在更golfed溶液,k用于编码既ij通过k=n*i+j,从中(i,j)可以提取为(k/n,k%n)。这节省了理解的循环。的权力2为完成1<<有正确的运算符优先级。

生成每对顶点并检查它们之间是否有点翻转的另一种方法似乎更长(70字节):

lambda n:[(i,x)for i in range(2**n)for x in range(i)if(i^x)&(i^x)-1<1] 

1
n*2**n只是n<<n
xsot

切换到Python 3.5,lambda n:{(*{k//n,k//n^1<<k%n},)for k in range(n<<n)}保存一个字节。(带星号的表达式保存三个,但除法语法丢失两个。)但是,我很确定您拥有的49字节解决方案很好。
林恩

4

Mathematica,48个 24字节

EdgeList@*HypercubeGraph

只是使用内置函数的匿名函数。


啊,内置的!由于您不必按字母顺序命名顶点,因此可以省略FromLetterNumber。我什至认为这EdgeList@*HypercubeGraph是一个有效的答案。
墨菲

3

JavaScript(SpiderMonkey 30+),69 64字节

n=>[for(i of Array(n<<n).keys())if(i/n&(j=1<<i%n))[i/n^j,i/n^0]]

它最初是@xnor的Python 2解决方案的端口,但是我能够通过重写代码以使用单个循环来节省9个字节。编辑:i按照@xnor的更新解决方案,通过拆分其他方式又节省了5个字节,该解决方案现在也使用单个循环。


2

MATL,20字节

2i^:qt!Z~Zltk=XR2#fh

这适用于语言/编译器的当前版本(14.0.0)

在线尝试!

说明

这几乎使用与@xnor的答案相同的想法。

2i^    % take input n and compute 2^n
:q     % range [0,1,...,2^n-1] (row vector)
t!     % duplicate, transpose into a column vector
Z~     % bitwise XOR with broadcast
Zl     % binary logarithm
tk     % duplicate and round down
=      % true if equal, i.e. for powers of 2
XR     % upper triangular part, above diagonal
2#f    % row and index columns of nonzero values
h      % concatenate vertically

2

Pyth,13个字节

fq1.aT.c^U2Q2

输入3上的输出

[[[0, 0, 0], [0, 0, 1]], [[0, 0, 0], [0, 1, 0]], [[0, 0, 0], [1, 0, 0]], [[0, 0, 1], [0, 1, 1]], [[0, 0, 1], [1, 0, 1]], [[0, 1, 0], [0, 1, 1]], [[0, 1, 0], [1, 1, 0]], [[0, 1, 1], [1, 1, 1]], [[1, 0, 0], [1, 0, 1]], [[1, 0, 0], [1, 1, 0]], [[1, 0, 1], [1, 1, 1]], [[1, 1, 0], [1, 1, 1]]]

说明:

fq1.aT.c^U2Q2
                  Implicit: input = Q
        ^U2Q      All Q entry lists made from [0, 1].
      .c    2     All 2 element combinations of them.
f                 Filter them on
   .aT            The length of the vector
 q1               Equaling 1.

1

Python 2:59个字节

lambda n:[(a,a|1<<l)for a in range(2**n)for l in range(n)if~a&1<<l]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.