43亿个排列


16

我们可以按如下方式将Rubik's Cube表示为网络(求解时):

   WWW
   WWW
   WWW
GGGRRRBBBOOO
GGGRRRBBBOOO
GGGRRRBBBOOO
   YYY
   YYY
   YYY

每个字母代表相应的颜色(W白色,G绿色等)

已被证明有恰好43252003274489856000(〜43百万的三次方)不同的排列,一个魔方可以英寸

你的任务是把一个整数之间1个43252003274489856000和输出对应的置换,在上述所示的方式。您可以选择排列的顺序,但是必须显示您使用的算法为每个可能的输入生成唯一且正确的排列。

无效的排列规则

取自页面

首先,每个3x3面的中心必须保持相同,因为魔方立方体上的中心正方形无法旋转。可以旋转整个多维数据集,更改面的显示位置,但这不会影响多维数据集的网格。

如果我们说每个置换都有一个奇偶校验,那么根据达到该置换的交换次数的奇偶校验,我们可以说

  • 每个角件都有三个可能的方向。可以正确地设置其方向(0),顺时针(1)或逆时针(2)。拐角方向的总和始终保持为3的整数倍

  • 魔方上的每次合法旋转都总是翻转偶数个边,因此不会只有一个方向错误。

  • 考虑到所有拐角和边缘的排列,整体奇偶校验必须为偶数,这意味着每个合法举动始终执行相等数量的互换(忽略方向)

例如,以下三个网是无效的输出:

   WWW
   WWW
   WWW
GGGWWWBBBOOO
GGGRRRBBBOOO
GGGRRRBBBOOO
   YYY
   YYY
   YYY

(Too many whites/not enough reds)

   WRW
   WRW
   WRW
GGGRWRBBBOOO
GGGWRRBBBOOO
YYGRWROOOBBB
   YYY
   GGY
   YYY

(There are two red/green center squares and no white/yellow center squares.
 In all valid permutations, the center squares are all different colours)

   WWW
   WWW
   WWW
GGGRRRBBBOOO
GGGRRRBBBOOO
GGGRRRBBOYOO
   YYY
   YYY
   YYB

(The yellow/orange/blue corner is rotated into an impossible permutation)

规则

  • 您必须以自己希望的方式证明该算法有效。只要证明算法的有效性,就不必枚举每个排列。
  • 1个43252003274489856000
    • 253-1个253-1个
    • 27946105037114827095
  • 您的答案中必须包含某种形式的有效性证明。除列举所有可能性外,该证明可以任何公认的证明方法证明其有效性。
  • 您可以根据需要选择使用其他输入法,只要:
    • 输入是有界的
    • 每个输入对应一个唯一的输出
    • 您清楚地解释了输入格式及其与每个输出的对应关系
  • 您可以更改用于使用6个不同ASCII字符(在33(!)和126(~)之间)的字符,而不是WGRBOY
  • 您可以以任何希望的方式输出,只要它可以清晰显示多维数据集,就能显示所有6个面,包括任何有效的多维数据集网,单行字符串或3D渲染。如果您不确定特定格式,请随时在评论中提问。

这是一个因此每种语言中以字节为单位的最短代码胜出。

有效输出示例

   YYY
   YYY
   YYY
GGGRRRBBBOOO
GGGRRRBBBOOO
GGGRRRBBBOOO
   WWW
   WWW
   WWW

(The `W` and `Y` faces have been swapped)

   ZZZ
   +++
   +}}
+[[}77ZZ7bbb
bb[}[[7}}+Z7
bb[}++[}}+Z7
   7bb
   [7Z
   [7Z

(To start with, the colours have been mapped W -> +, G -> b, R -> [, B -> }, O -> Z and Y -> 7.
 Then, the moves L, R, U and F' have been applied, in that order.
 Notice that each centre square is different, and corresponds to the same colour as in the mapping)

在第三个无效示例中,不仅仅是转角处于无效配置中,由于r和o彼此相对,r / y / o角是不可能的角
fəˈnˈtɪk

修复了第三个无效示例(CC @ fəˈnɛtɪk)
乔纳森·艾伦

第二个无效示例中也存在相同的问题,但我没有注意到。在那里无关紧要,因为无论如何颜色还是弄乱了
fəˈnɛtɪk

一种1个一种2一种3一种4一种1个8一种237一种312/2一种4211

1
@Shaggy是的,单行字符串就可以了
Caird coinheringaahing

Answers:


13

木炭334个 297字节

Nθ≔׳﹪θ²¹⁸⁷ε≧⁺﹪±Σ⍘峦³ε≧÷²¹⁸⁷θ≔⁴⁰³²⁰δ≔﹪θδζ≧÷δθ≔⊗﹪θ²⁰⁴⁸η≧⁺﹪Σ⍘粦²η≧÷²⁰⁴⁸θF⪪”B"↷:μêKO″KW#})”³«J⌕α§ι⁰I§ι¹§ι²»≔⁰ω≔⪪”A‽}y≔W⊞≦≦⧴!O×➙⟧ï!Y9⁺`↙1δQ1ξzT”⁶υ≔⪪”{➙∧⊙ηr⸿ξd⊕÷M→¡$≧”³δF²«Fδ«≔§υ⎇⁼Lυ⊗ιωζδ≧÷Lυζ≧⁺⌕υδω≔Φυ¬⁼λδυFLκ«J⌕α§δ⊗⁺λεI§δ⊕⊗⁺λε§κλ»≧÷Lκε»≔⪪”A‽}R›K<≡^μ≡⟦σD⎚+πη±t¿e∧L⸿~↑�w”⁴υ≔⪪”{➙∧⊙ηr⸿ξe'→↑Þ³№¹”²δ≔θζ≔ηε

在线尝试!链接是详细版本的代码。说明:

Nθ

将整数输入变量q

≔׳﹪θ²¹⁸⁷ε≧⁺﹪±Σ⍘峦³ε≧÷²¹⁸⁷θ

除以q3⁷,将余数放入e。然后,e在底数3中考虑一个数字,在e其后缀一个数字,以便其数字(在底数3中)加起来等于3 的倍数。这可以e定义角的旋转。

≔⁴⁰³²⁰δ≔﹪θδζ≧÷δθ

除以q8 !,将余数放入z。(8!临时存储在其中d以保存一个字节。)这允许z定义角的位置。

≔⊗﹪θ²⁰⁴⁸η≧⁺﹪Σ⍘粦²η≧÷²⁰⁴⁸θ

除以q2¹¹,将余数放入h。然后,h以2为底的数字作为后缀,h以使其数字(以2为底)加起来等于2 的倍数。这可以h定义边沿的翻转。

F⪪”B"↷:μêKO″KW#})”³

循环显示中心的字符串。

«J⌕α§ι⁰I§ι¹§ι²»

跳到每个中心的位置并打印。

≔⁰ω

跟踪变量中拐角位置的奇偶性w

≔⪪”A‽}y≔W⊞≦≦⧴!O×➙⟧ï!Y9⁺`↙1δQ1ξzT”⁶υ

创建一个角位置数组。

≔⪪”{➙∧⊙ηr⸿ξd⊕÷M→¡$≧”³δ

创建一系列角颜色。

F²«

循环两次,一次用于拐角,一次用于边缘,以下称为“立方体”。

Fδ«

循环播放多维数据集颜色。

≔§υ⎇⁼Lυ⊗ιωζδ≧÷Lυζ≧⁺⌕υδω≔Φυ¬⁼λδυ

从中提取下一个立方体位置z,更新中的奇偶校验w。对于最后一个边缘使用此奇偶校验。这样可以确保边缘和拐角的奇偶校验之和是偶数。

FLκ«J⌕α§δ⊗⁺λεI§δ⊕⊗⁺λε§κλ»

在该位置打印立方体,并根据需要进行下一轮旋转或翻转。

≧÷Lκε»

取消旋转或翻转e

≔⪪”A‽}R›K<≡^μ≡⟦σD⎚+πη±t¿e∧L⸿~↑�w”⁴υ

创建边缘位置数组。这将在循环中第二次使用。

≔⪪”{➙∧⊙ηr⸿ξe'→↑Þ³№¹”²δ

创建一系列边缘颜色。

≔θζ≔ηε

覆盖角变量ze相应的边缘变量qh以便在循环的第二遍过程中对边缘进行置换和翻转。


告诫我:如果用木炭打高尔夫球的东西是330字节,请不要在PHP中尝试!
2

@ Night2由于错误修正(错误的奇偶校验计算),现在可悲的是334。
尼尔,

8

红宝石570408字节

->g,h{z=[]
c=a="\x19)!$'%\x177\x1F495.)@7g~yp"
20.times{|i|z<<a[k=g%r=12+i/12*8-i];a[k]="";g/=r}
19.times{|i|z[0..i].map{|j|j>z[i+1]&&c=!c}}
c||(z[19],z[18]=z[18,2])
h+=h+("%b"%(h%2048)).sum%2
j=0
b="023451"
20.times{|i|b<<("%0*o"%[r=2+i/12,z[i].ord-20]*2)[h%r+i/19*j%3,r];j-=r/3*h;h/=r}
s=(t="...
"*3)+(?.*12+$/)*3+t
54.times{|i|s["<QTWZo;MP[ngD@RS^k=GVUpaJ8XYdsAFE?CN7LK9IHl_`jh]reftbc"[i].ord-55]=b[i]}
s}

在线尝试!

原始版本,带有魔术数字数组,而不是魔术字符串

->g,h{z=[]
a=[05,025,015,020,023,021,03,043,013,040,045,041,   032,025,054,043,0123,0152,0145,0134]
#PERMUTE
20.times{|i|r=12+i/12*8-i;z<<a.delete_at(g%r);g/=r}
c=1
19.times{|i|z[0..i].map{|j|j>z[i+1]&&c=!c}}
c||(z[19],z[18]=z[18],z[19])
#ROTATE
h+=h+(h%2048).to_s(2).sum%2
j=0
b="023451"
20.times{|i|r=2+i/12;b<<("%0*o"%[r,z[i]]*2)[h%r+i/19*j%3,r];j-=r/3*h;h/=r}
#DISPLAY
s=(t="...
"*3)+(?.*12+$/)*3+t
54.times{|i|s[
[5,26,29,32,35,56,
4,22,25,36,55,48, 
13,9,27,28,39,52,
6,16,31,30,57,42,
19,1,33,34,45,60,
10,15,14,8,12,23,0,21,20,2,18,17,
53,40,41,51,49,38,59,46,47,61,43,44][i]]=b[i]}
s}

在线尝试!

一个匿名函数,目前的形式是接受两个整数的输入,这似乎是允许的:“您可以选择其他输入方法。” 第一个是0到范围内的排列,12!*8!/2 - 1第二个是0到范围内的块的方向2**11 * 3*7 - 1。处于已解决状态的输出为以下字符串:

000
000
000
222333444555
222333444555
222333444555
111
111
111

进一步打高尔夫球

通过将输出格式调整为以下形状,大约还可以保存10个字符。但这会降低可读性,所以我目前不会这样做

      #########
      #########
      #########
#########
#########
#########

说明

排列

在内部,已解决状态由数组中的一系列八进制数表示a。输入g除以数字12..1,并使用模数从中拾取和移除边缘a并将其放入中z。完成此操作后,仅保留了拐角a,因此g将其除以数字8..1,并使用模数从中移除拐角a并将其放置在中z

由于没有足够的信息来确定最后两个角的顺序,因此的值g会在到达它们的时间被除为零,因此它们将始终按z原始顺序添加到该角。然后进行检查以确定整体排列是偶数还是奇数,并且如有必要,交换最后两个角以使排列均匀。

取向

有多种不同的方法可以确定拐角或边缘是否处于正确的方向(如果它不在其求解的位置)。对于这个答案的目的,一个角在正确的方向,如果它显示考虑01在顶部或底部的脸。因此,旋转顶面或底面不会更改角方向。旋转其他面的确会更改方向,但以使整个奇偶校验和保持不变的方式进行。边是在正确的方向考虑,如果他们表现出24到前/后或35向左/右。这意味着顶部或底部旋转四分之一圈会翻转四个边缘,而其他面的旋转会使翻转状态保持不变。

输入包含除第一个边沿和最后一个角以外的所有内容的显式信息。将11个最低有效位h%2048相加,并将其模量用于确定第一条边的方向。h通过将其乘以2乘以2,然后将第一边沿方向的值添加为最低有效位。通过从中逐渐减去其他角的方向来找到最后一个角的方向j。对于最后一个拐角(其中i/19= 1),将的值j%3添加到h(将减少为零),这将确定最后一个拐角的方向。

字符串b预先用面部中心的文本进行了初始化。h除以2十二倍,再除以3八倍,并使用模数确定零件的方向。在每种情况下,in中的数字z都将转换为具有适当数字位数(2或3)的字符串,然后复制该字符串。这允许通过索引从字符串中提取由模数找到的数字的正确旋转,并将其附加到b

显示

最后,使用索引表中的幻数将原始贴纸复制b为更易于阅读的格式s

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.