旋转不变指纹


15

假设我们有一些多米诺骨牌,并且想唯一地标识它们,但是多米诺骨牌可以旋转,因此盲目地对它们进行散列将不会为我们提供相同的指纹及其旋转(通常)。

例如,如果我们有L-tetromino

x
x
xx

我们希望它具有与以下任何一个相同的指纹:

         xx
  x       x      xxx
xxx  ,    x  or  x

注意:我们只允许在平面上旋转(即,它们是单面的多米诺骨牌),因此以下多米诺骨牌将是不同的:

 x
 x
xx 

挑战

对于这一挑战的任务是实现一个指纹函数/程序,其需要一个m×n布尔/ 0,1列出/串-valued矩阵/列表/ ..编码四角并返回一个字符串-一个四角的指纹。对于所有可能的旋转,指纹必须相等(通常为4)。

输入输出

  • m1n1(即没有空四角)
  • 您可以确保m,n尽可能小(即将所有0修剪为适合mn
  • 您可以确保输入为
    • 只需连接
    • 没有孔
  • 输出必须是一个字符串,该字符串对于多米诺骨牌的每次可能旋转都相同

例子

这是一些等效类,对于每个类,指纹必须相同;对于来自两个不同类的任何两个多胺,它们必须不同。

示例中的左旋四聚体的旋转:

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

J-tetromino:

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

单位多胺:

[[1]]

5×1栏:

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

2×2角:

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

W-戊胺

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


如果我始终输出""(空字符串),是否满足所有要求?
丹尼尔·瓦格纳

@DanielWagner:“ [..] 对于来自两个不同类的任何两个多氨基酸[指纹] 必须不同 ”-所以不,那将是无效的。
ბიმო

输出一致排序的数组的所有可能旋转是否有效?示例
Shaggy

1
@Shaggy:是的,这将符合所有条件。
ბიმო

Answers:


7

Python 2,48个字节

f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))

在线尝试!

就列表比较而言,采用四个轮换中的最大轮换。基于FlipTack的解决方案

该代码使用Python 2的能力来比较不同类型的对象。的基本案例值0是无害的,max因为它小于任何列表。同样,zip生成元组列表,而输入是列表列表,但是元组比列表大,因此输入列表列表从不竞争。这就是为什么我们旋转5次而不是4次的原因,因此我们返回到初始列表的简化版本。(如果这是允许的输入形式,则也可以使用元组列表)。


4

Python 3,63字节

def f(m):M=[];exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)

在线尝试!

查找具有最小词典序号的旋转,并进行打印。

一个lambda形式以相同的字节数出现:

lambda m,M=[]:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])

在线尝试!


重写为a lambda可以使您达到58 lambda m,M=[]:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M)。之所以有效是因为exec总是返回None
nedla2004

@ nedla2004只能运行一次,然后由于M已经填充而变得
躲藏起来

@ nedla2004 ...但是考虑到问题M[-4:]可以使您达到相同的字节数。
FlipTack

我知道,我使用的测试只是检查带有相同“哈希”的输入,因此我从没有碰到过这种情况。那讲得通。
nedla2004 '18

2

果冻,5字节

ZU$ƬṂ

在线尝试!

完整程序。

只需生成所有可能的旋转并选择字典最小。

请注意,单例列表没有包装在[]输出中。没关系,因为输入中将存在单例列表的唯一情况是一条垂直线(包括单位多米诺骨牌),这与具有相同大小的水平线相同(其中的那些线没有包裹) )。外部[]元素也不存在的唯一情况是单位多胺基。


当我阅读挑战时,我知道会发生这种情况:)
ngn

2

干净,136字节

import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]

在线尝试!

包括测试验证器。


2

K(ngn / k),16个字节

{a@*<a:3{+|x}\x}

在线尝试!

最小转数

{ } 带参数的功能 x

{+|x}旋转,即反转(|)和转置(+

3{ }\应用3次保存中间结果;这将返回4个旋转的列表

a: 分配给 a

< 升序(计算升序排列)

* 第一

a@a用那个索引


1

Japt -g,6个字节

4Æ=zÃñ

尝试一下

           :Implicit input of 2d-array U
4Æ         :Map the range [0,4)
   z       :  Rotate U 90 degrees
  =        :  Reassign to U
    Ã      :End map
     ñ     :Sort
           :Implicit output of first element

-g标志有必要吗?排序应该意味着所有初始轮换都以相同的列表结尾,因此完整的列表应该可以像指纹一样正常工作,除非我遗漏了一些东西。
卡米尔·德拉卡里

@KamilDrakari,您完全可能是对的-就像我说的那样,我不确定我是否完全理解挑战。保留它无害,但是它不花费任何字节。
毛茸茸的

@KamilDrakari:没必要,但这也没有害处,因为它不计入字节数。
ბიმო


0

05AB1E10 8 字节

3FÂø})Σ˜

-2个字节,感谢@Shaggy

在线尝试验证所有测试用例

说明:

3F  }       # Loop 3 times
  Â         #  Bifurcate (short for Duplicate & Reverse) the top of the stack
            #  (which is the input-matrix implicitly the first iteration)
   ø        #  Transpose: swap rows/columns
     )      # After the loop, wrap everything on the stack in a list
      Σ˜    # Sort this list of matrices by their flattened array (and output implicitly)

注意:用ß或取最小值,W将隐含地变平,所以output 也会变平0。排序{似乎不适用于矩阵列表,这就是为什么我使用它的原因Σ˜


1
@粗野的谢谢!:)在这种情况下,可以删除最后两个字节,因为}如果后面没有任何内容,则隐式地完成。
凯文·克鲁伊森

1
今天我学到了一些关于05AB1E的知识!:)在Japt中是相同的。
毛茸茸的
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.