具有自定义标签的二面体D4组组成


14

二面体组D4是正方形的对称组,即通过旋转和反射将正方形变换为自身的移动。它由8个元素组成:旋转0、90、180和270度,以及在水平,垂直和两个对角线上的反射。

D4的8个元素作用于正方形。

图片全部来自Larry Riddle的可爱页面

挑战在于如何构成这些动作:给定两个动作,输出的动作等同于一个接一个地执行它们。例如,先执行第7步再执行第4步,与执行第5步相同。

构成示例

请注意,将顺序切换为移动4然后移动7将产生移动6。

结果列于下表;这是D 4组的Cayley表。因此,例如,输入端7 4应该产生输出5D47,45

12345678123456781234567823418756341265874123786557681324685731427685421385762431

挑战

您的目标是在尽可能少的字节中实现此操作,但是除了代码外,您还选择代表移动1到8的标签。标签必须是0到255之间的8个不同数字,或者8个数字代码点代表的3个字节字符。

您的代码将获得所选8个标签中的两个标签,并且必须输出对应于二面体组D4其组成的标签。

假设您已为1到8的动作分别选择了字符C,O,M,P,U,T,E,R。然后,您的代码应实现此表。

COMPUTERCOMPUTERCOMPUTEROMPCREUTMPCOTUREPCOMERTUUETRCMOPTRUEMCPOETRUPOCMRUETOPMC

给定输入E和P,您应该输出U。您的输入将始终是字母C,O,M,P,U,T,E,R中的两个,并且您的输出应始终是这些字母之一。

用于复制的文本表

1 2 3 4 5 6 7 8
2 3 4 1 8 7 5 6
3 4 1 2 6 5 8 7
4 1 2 3 7 8 6 5
5 7 6 8 1 3 2 4
6 8 5 7 3 1 4 2
7 6 8 5 4 2 1 3
8 5 7 6 2 4 3 1

Your choice of labels doesn't count against your code length.介意吗?就目前而言,我可以将矩阵硬编码到我的代码中,并声称它不计入我的分数。
本杰明·厄克特

2
@BenjaminUrquhart我试图说代码的长度就是代码的长度,并且说,选择多位数字标签不会花费任何额外费用。看起来该行更加有用,因此我将其删除。
xnor

Answers:


10

红宝石,18字节

->a,b{a+b*~0**a&7}

不打高尔夫球

->a,b{ (a+b*(-1)**a) % 8}  
# for operator precedence reasons, 
#-1 is represented as ~0 in the golfed version 

在线尝试!

使用以下编码数字0至7

为了本机代码:

Native     Effect                    Codes per
Code                                 Question
0          rotate 0 anticlockwise    1C
1 /        flip in y=x               7E
2 /|       rotate 90 anticlockwise   2O
3 /|/      flip in x axis            5U
4 /|/|     rotate 180 anticlockwise  3M
5 /|/|/    flip in y=-x              8R
6 /|/|/|   rotate 270 anticlockwise  4P
7 /|/|/|/  flip in y axis            6T

为了每个问题

Native     Effect                    Codes per
Code                                 Question
0          rotate 0 anticlockwise    1C
2 /|       rotate 90 anticlockwise   2O
4 /|/|     rotate 180 anticlockwise  3M
6 /|/|/|   rotate 270 anticlockwise  4P
3 /|/      flip in x axis            5U
7 /|/|/|/  flip in y axis            6T
1 /        flip in y=x               7E
5 /|/|/    flip in y=-x              8R

说明

/表示在线路翻转y=x|代表y轴的翻转。

可以通过交替翻转这两条线来生成组D4的任何对称性,例如,/随后|给出/|,即逆时针旋转90度。

连续翻转的总数非常方便地表示了算术运算。

如果第一步是旋转,我们可以简单地增加翻转次数:

Rotate 90 degrees   +  Rotate 180 degrees = Rotate 270 degrees
/|                     /|/|                 /|/|/|

Rotate 90 degress   +  Flip in y=x        = Flip in x axis   
/|                    /                     /|/

如果第一步是反射,我们发现我们有一些相同的反射/|符号彼此相邻。由于反射是自我逆的,因此我们可以一张一张地抵消这些翻转。所以我们需要从另一步减去一个步

Flip in x axis     +  Flip in y=x        = Rotate 90 degrees
/|/                   /                    /|/ / (cancels to) /|

Flip in x axis     +  Rotate 90 degrees  = Flip in y=x
/|/                   /|                   /|/ /| (cancels to ) / 

1
你可以替换~0使用7,因为模运算。
NieDzejkob

很棒的方法和解释!翻转取消的方式非常清楚地说明了标签加或减的原因。
xnor

7

Wolfram语言(Mathematica),31个字节

0,5,2,7,1,3,6,4

BitXor[##,2Mod[#,2]⌊#2/4⌋]&

在线尝试!

说明:

D4F2

D4U(3,2):={(1ab01c001)a,b,cF2}.

我们有

(1a1b101c1001)(1a2b201c2001)=(1a1+a2b1+b2+a1c201c1+c2001),

可以很容易地按位操作编写。


一个相当的推论-我不知道这种同构。
xnor

5

Wolfram语言(Mathematica),51个字节

⌊#/4^IntegerDigits[#2,4,4]⌋~Mod~4~FromDigits~4&

在线尝试!

使用标签{228, 57, 78, 147, 27, 177, 198, 108}

这些{3210, 0321, 1032, 2103, 0123, 2301, 3012, 1230}以4 为底。幸运的是,256 = 4 ^ 4。


下层实现,也是51个字节

Sum[4^i⌊#/4^⌊#2/4^i⌋~Mod~4⌋~Mod~4,{i,0,3}]&

在线尝试!



4

Python 2中26个 23 21字节

lambda x,y:y+x*7**y&7

d3andxnor

 id | r1 | r2 | r3 | s0 | s1 | s2 | s3 
----+----+----+----+----+----+----+----
 0  | 2  | 4  | 6  | 1  | 3  | 5  | 7  

2
您可以替换(-1)使用7,因为模运算为-3个字节。
NieDzejkob,

@NieDzejkob谢谢!可耻的是,alephalpha将答案从28个字节降低到22个字节……
尼尔,

不错的解决方案!您可以通过更改运算符的优先级来削减括号:y+x*7**y&7
xnor19年

@xnor谢谢,我再次领先于alephalpha!
尼尔,

3

TI-BASIC,165字节

Ans→L₁:{.12345678,.23417865,.34126587,.41238756,.58671342,.67583124,.75862413,.86754231→L₂:For(I,1,8:10fPart(.1int(L₂(I)₁₀^(seq(X,X,1,8:List▶matr(Ans,[B]:If I=1:[B]→[A]:If I-1:augment([A],[B]→[A]:End:[A](L₁(1),L₁(2

输入是长度为2的列表Ans
输出是(row, column)表中索引处的数字。

可能有一种更好的压缩方法可以节省字节,但我必须对此进行研究。

例子:

{1,2
           {1 2}
prgmCDGF1B
               2
{7,4
           {7 4}
prgmCDGF1B
               5

说明:(
为便于阅读,添加了换行符。)

Ans→L₁                              ;store the input list into L₁
{.123456 ... →L₂                    ;store the compressed matrix into L₂
                                    ; (line shortened for brevity)
For(I,1,8                           ;loop 8 times
10fPart(.1int(L₂(I)₁₀^(seq(X,X,1,8  ;decompress the "I"-th column of the matrix
List▶matr(Ans,[B]                   ;convert the resulting list into a matrix column and
                                    ; then store it into the "[B]" matrix variable
If I=1                              ;if the loop has just started...
[B]→[A]                             ;then store this column into "[A]", another matrix
                                    ; variable
If I-1                              ;otherwise...
augment([A],[B]→[A]                 ;append this column onto "[A]"
End
[A](L₁(1),L₁(2                      ;get the index and keep it in "Ans"
                                    ;implicit print of "Ans"

这是一个155字节的解决方案,但是它只是对矩阵进行硬编码并获取索引。
我觉得它更无聊,所以我没有把它作为我的官方意见书:

Ans→L₁:[[1,2,3,4,5,6,7,8][2,3,4,1,8,7,5,6][3,4,1,2,6,5,8,7][4,1,2,3,7,8,6,5][5,7,6,8,1,3,2,4][6,8,5,7,3,1,4,2][7,6,8,5,4,2,1,3][8,5,7,6,2,4,3,1:Ans(L₁(1),L₁(2

注意: TI-BASIC是一种标记化语言。字符数不等于字节数。


您不能使用以下方式0-7来剃掉一个字节吗?1-8
ASCII码,仅ASCII

我可以,但是然后我必须再使用两个,以向矩阵的每个元素添加一个。好主意!
Tau

错误,您可以使用任何字符集大声笑,因此您不必再使用两个字符
ASCII-仅

可能是正确的,但是TI-BASIC的矩阵是1索引的。此提交依赖于此来获取想要的值(如果这就是您的意思,如果我错了,请纠正我)
Tau

啊,忘记了这一点
仅ASCII的

3

果冻,6 个字节

N⁹¡+%8

双向链接在右侧接受第一个变换,在左侧接受第二个变换,从而产生复合变换。

转换在哪里:

as in question:  1    2    3    4    5    6    7    8
transformation: id  90a  180  90c  hor  ver  +ve  -ve
  code's label:  0    2    4    6    1    5    7    3

在线尝试!...或查看映射回问题中标签的表格

(可以使用6 byter以其他顺序采用参数_+Ḃ?%8

怎么样?

每个标签是交替的序列的长度hor+ve变换其等同于所述变换(例如180等效于hor, +ve, hor, +ve)。

组成A,B等效于两个等效序列的串联,并允许简化为减法或加法模八。

使用问题的7, 4示例,我们有+ve, 90c
hor, +ve, hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve, hor, +ve

......但既然hor, horid我们有:
hor, +ve, hor, +ve, hor, +ve , +ve, hor, +ve, hor, +ve

...由于 +ve, +ve是,id我们有:
hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve

...我们可以重复这些取消操作以:
hor
..等同于减去长度(7-6=1)。

如果无法取消,我们只添加长度(例如 90a, 180 2+4=6 90c)。

最后,请注意,长度为8的序列是,id因此我们可以将结果序列的长度取模8。

N⁹¡+%8 - Link: B, A
  ¡    - repeat (applied to chain's left argument, B)...
 ⁹     - ...times: chain's right argument, A
N      - ...action: negate  ...i.e. B if A is even, otherwise -B
   +   - add (A)
    %8 - modulo eight

也比此实现短1个字节使用字典排列索引的:

œ?@ƒ4Œ¿

...接受[first, second]标签的单子链接:

as in question:  1    2    3    4    5    6    7    8
transformation: id  90a  180  90c  hor  ver  +ve  -ve
  code's label:  1   10   17   19   24    8   15    6

3

JavaScript(Node.js)22 17字节

(x,y)=>y+x*7**y&7

在线尝试!对Dihedral集团的Cayley Table的答复的港口d3但是使用我的Python答案中的建议打了高尔夫。使用以下映射:

 id | r1 | r2 | r3 | s0 | s1 | s2 | s3 
----+----+----+----+----+----+----+----
 0  | 2  | 4  | 6  | 1  | 3  | 5  | 7  

较旧版本的JavaScript可以通过多种方式支持22个字节:

(x,y)=>(y&1?y-x:y+x)&7
(x,y)=>y-x*(y&1||-1)&7
(x,y)=>y+x*(y<<31|1)&7

小改进-通过增加输入来节省一个字节,x=>y=>(y&1?y-x:y+x)&7然后使用调用函数f(x)(y)
丹娜


2

榆木42字节 19字节

\a b->and 7<|b+a*7^b

尼尔的港口 Node.js版本的

在线尝试

先前版本:

\a b->and 7<|if and 1 a>0 then a-b else a+b

1
不错的第一答案!我不知道如何在Elm中编程,但是可以删除空格吗?
MilkyWay19年

@ MilkyWay90不,这是基于ML的语言的主要区别之一,f x是函数调用,就像f(x)在C语言一样。而且你无能为力。但是在许多非高尔夫场景中,它可能确实不错,而且不会造成混乱。Elm没有按位运算符(例如&),因此and x y这里只是一个普通的函数调用。
Evgeniy Malyutin

我明白了,谢谢您的解释!
MilkyWay19年

@ MilkyWay90实际上,我设法使用管道运算符<|而不是括号来减少一个空间(和一个字节)。感谢您的提问!
Evgeniy Malyutin

别客气!如果您有兴趣提出新的解决方案,可以在第十九字节(我们的SE聊天室)上寻求帮助。如果您要创建编码挑战,则可以每天将其发布到The Sandbox(在meta上),然后在第十九个字节上发布指向该问题的链接。
MilkyWay90

1

蟒蛇, 82 71字节

0-7

-11字节(仅ASCII)

lambda a,b:int("27pwpxvfcobhkyqu1wrun3nu1fih0x8svriq0",36)>>3*(a*8+b)&7

蒂奥



也为76和-2,因为f=它不是递归的,因此可以删除
仅限ASCII

等待撕裂,它不起作用
仅使用ASCII


似乎您可以使用int.from_bytes非UTF编码更好地进行编码,但是...不确定如何在TIO上执行此操作
仅使用ASCII

0

斯卡拉,161字节

选择COMPUTER作为标签。

val m="0123456712307645230154763012675446570213574620316574310274651320"
val s="COMPUTER"
val l=s.zipWithIndex.toMap
def f(a: Char, b: Char)=s(m(l(a)*8+l(b))-48)

在线尝试!


1
这是代码高尔夫球:| 您应该将其设置得尽可能短
ASCII码,仅适用


是的,我挑战自己要使用scala和真实标签,而不仅仅是原生0-7。尝试击败它。
彼得



0

Scala,70个字节

选择0-7个本机整数作为标签。

将矩阵压缩为32个字节的ASCII字符串,每对数字n0,n1转换为1个字符c = n0 + 8 * n1 +49。从49开始,我们在编码的字符串中没有\。

(a:Int,b:Int)=>"9K]oB4h]K9Vh4BoVenAJne3<_X<AX_J3"(a*4+b/2)-49>>b%2*3&7

在线尝试!




-3

Wolfram语言(Mathematica),7个字节(UTF-8编码)

#⊙#2&

一个带有两个参数的纯函数。此处呈现的符号实际上是Mathematica的专用Unicode符号F3DE(3字节),表示功能PermutationProduct

Mathematica知道二面体组,它使用Cycles命令将各种组的元素表示为排列。例如,运行命令

GroupElements[DihedralGroup[4]]

产生输出:

{Cycles[{}], Cycles[{{2, 4}}], Cycles[{{1, 2}, {3, 4}}], 
 Cycles[{{1, 2, 3, 4}}], Cycles[{{1, 3}}], Cycles[{{1, 3}, {2, 4}}], 
 Cycles[{{1, 4, 3, 2}}], Cycles[{{1, 4}, {2, 3}}]}

PermutationProduct 是以这种形式编写的用于将组元素相乘的函数。

由于允许我们选择自己的标签,因此此函数假定这些标签为组元素;这些标签与问题帖中的标签之间的关联关系如下:

Cycles[{}] -> 1
Cycles[{{1, 2, 3, 4}}] -> 2
Cycles[{{1, 3}, {2, 4}}] -> 3
Cycles[{{1, 4, 3, 2}}] -> 4
Cycles[{{2, 4}}] -> 5
Cycles[{{1, 3}}] -> 6
Cycles[{{1, 2}, {3, 4}}] -> 7
Cycles[{{1, 4}, {2, 3}}] -> 8

tl; dr有一个内置函数。


8
标签必须是0到255的数字或单个字节。
xnor19年

足够公平(无论如何我都很高兴发现了此功能)。您能否在OP中进行澄清?现在,它读起来像是“选择您自己的标签”(强调),然后是几个可能的选择(“您可能...”)。
格雷格·马丁

1
哦,我知道你在看它。很抱歉在这里不清楚并导致您走错了路。让我尝试改写它。
xnor19年
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.