魔方争夺战


21

您的任务是创建随机移动序列,该序列可用于加扰魔方。这样的争夺是由25个动作组成的。每个动作都由字母组成,UDRLFB可选地后跟一个后缀'2

该表示法称为Singmaster表示法。UDRLFB表示6个面之一,可选的后缀'2表示转角。此信息对于解决任务绝对不是必需的。

为了确保争夺是“高质量”,必须遵循以下两个规则:

  • 两个连续的动作不能使用相同的字母。这禁止连续移动UUDDRRLLFFBB和使用可选的后缀像所有的组合U2UU'U'

    禁止使用这些移动对,因为它们很容易减少为1或0个移动。U2U具有相同的效果U'R'R相同的效果

  • 三个连续的动作不能属于同一字母组。该信集团是UDRLFB。这条规则还禁止连续移动UDUDUDRLRLRLFBFBFB和使用可选的后缀像所有的组合U2DURL'RB2FB'

    这些组按其移动轴对面进行排序。U并且D位于同一组中,因为它们都围绕相同的轴旋转。因此,U移动不会影响D面部,D也不会影响U面部。因此,两个动作可以互换,UDU并且具有与相同的效果UUD,并且可以减小为U2D

挑战

编写脚本或函数,以生成一个随机加扰。没有输入。脚本/功能必须打印25个动作,而不能分开或用一个空格隔开,或者返回相应的字符串。

您的程序必须能够创建满足上述规则的每个加扰。当然,假设随机数生成器是真实随机的,而不是伪随机的。

这是代码高尔夫球。最短的代码(以字节为单位)获胜。

示例输出:

调用脚本/函数3次应打印/返回如下内容:

R'B2R2F2R2FB'R2DR2ULFB2RB'U2B'FL'BR'U'RB'
U'DBR'B2U'B'U'RUF'B'RDR2U'B'LR'B'F2D2UF2L'
BR2F'B'R'D'R'U2B'F2D2R'F2D'F'D2R2B'L2R'UB'R2L'D

如果将每个动作分开一个空格:

R2 L' F2 U2 D' R2 L2 F L' D2 U R B D' U2 L B2 L U B2 D U2 R' D2 U'
B R D2 F U2 B' R2 F2 B' U' L' R2 B U2 R' D B' F' U2 R' B' L R D2 R2
B2 R2 U D' B R D' R L2 D2 L2 R B2 F U' F2 B2 U' F U' D F R2 U2 B'

请注意,由于可选的后缀,所有这些输出都包含25个动作,但长度不同。当2'用作后缀时,不允许打印空格。您必须打印L2UR2F'R'U2L2 U R2 F' R' U2L2U R2F'R'U2不允许。


UR 2是说不允许进入吗?我认为,U R2 应该允许这样做,因为动作之间的间隔是合理的。
mbomb007'3

@ mbomb007我的意思是L2U R2F'R'U2U没有可选的后缀,因此不应有空格。空格不能替代可选的后缀。
雅库布2015年

如果每一步之间都有空格怎么办?U F2 L D2 R'...例如,我们可以输出吗?在这种情况下,没有多余的空间,根据您的规则,我认为应该没有问题。
mbomb007'3

@ mbomb007是的,我将其放入描述中。
雅库布2015年

字母前的2不是吗?oO
Oliver Ni

Answers:


6

CJam,47个 45字节

该解决方案使用的方法与迄今为止发布的任何其他方法都不同。它利用CJam的简洁列表操作来生成可用的移动列表,并在每个迭代中随机选择一个。修饰符简单地独立生成。

在线尝试。

{BA^2/6,_B-?A:B-mr0=:A"UDRLFB"=3mr[L2'']=}25*

说明

{               "Loop...";
  BA^2/           "If the two previous moves were not from the same group, ...";
  6,              "... then produce the available move list [0 1 2 3 4 5], ...";
  _B-             "... else produce the available move list [0 1 2 3 4 5] with
                   the second previous move removed";
  ?
  A:B             "Save the previous move as the second previous move";
  -               "Remove the previous move from the available move list";
  mr0=            "Randomly select an available move";
  :A              "Save this move as the previous move";
  "UDRLFB"=       "Map this move to its character (implicitly printed)";
  3mr[L2'']=      "Randomly select a modifier (implicitly printed)";
}25*            "... 25 times";

9

C 129

f(){int i,n,m,r,s,t;for(i=26;i--;i<25&&printf("%c%c","URFDLB"[s%6],"'2"[r%3])){for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;s+=m;}}

内部循环生成一个m范围内的值,该值1..5在加s和取模6时可确保没有两个连续的移动在立方体的同一侧。的旧值m存储在中n,并且测试m*n==9可确保m永远不会两次生成值= 3(因此,不能连续两次选择相反的面孔;请注意字符串中面孔的顺序。)

的至少显著部分r被用来决定哪个后缀('2或空)的用途,利用空字符的的结束"'2"

外循环运行26次。第一次,U永远都不会被拾取,因此printf在第一次迭代中被抑制。

测试程序中的非代码

所述ungolfed代码放每次移动,为了清楚起见之间的空间(golfed代码不,在为了节省一个字节)。此外,该golfed代码通过重新定位的保存分号printf的内for支架。

f(){
  int i,n,m,r,s,t;
  for(i=26;i--;){
    for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;
    s+=m;
    i<25&&printf("%c%c ","URFDLB"[s%6],"'2"[r%3]);
  }
}

main(){
  int j;
  srand(time(0));
  for(j=0;j<5;j++)f(), puts("");
}

典型输出

U' B D2 B' R' L F' D2 B D2 B2 R' B2 U D2 F' R U R' L B' L R2 B2 F'
U B U B F L2 D2 B' U' L B L R' D B U' D R D' B' F2 D' B D R
L D F2 B2 R' U F B' D2 L U R' L' U2 F' R F D U2 B L' B' U L2 F'
R2 B' F2 R2 L2 F' U2 L U' B' F R' D' F2 D F' L2 U2 R' D' B2 D F R2 L'
U2 F2 B2 D' F D F R L2 U' B D2 L' R D R F2 R' F2 U2 D R' D2 L F2



4

Pyth, 65岁 66

我从来没有真正在Pyth打高尔夫球,也许写过一两个程序。这基本上是@ steveverrill的解决方案翻译为Pyth的。欢迎提出改进建议。

更新:添加1个字节以使加扰也以开头U。也许C解决方案依靠未定义的行为来使其工作...

=YO6V25JZK1WK=GO15=Z/+3G3=Kq9*ZJ)~YZpd+@"URFDLB"%Y6?@"'2"%G3>2%G3k

我相信应该用更少的分配完成这项工作,但这将需要我大量修改算法。(嗯,可以尝试。)

这是基于C代码的说明:

=YO6           s = random.choice(range(6))
V25            for i in range(25):
  JZ               n = m
  K1               t = 1
  WK               while t:
    =GO15              r = random.choice(range(15))
    =Z/+3G3            m = (r + 3) / 3
    =Kq9*ZJ            t = 9 == m * n
  )
  ~YZ              s += m
  pd               print(..., end = " ")
  +                ... + ...
  @"URFDLB"%Y6     "URFDLB"[s % 6]
  ?@"'2"%G3>2%G3k  "'2"[G % 3] if 2 > G % 3 else ""

切换变量YZZ用0预先初始化,因此您保存了前3个字符。
2015年

@Jakube但后来我需要设置n = m(第三解释线),这必然意味着n = 0第一次,这反过来会要求Y为0
PurkkaKoodari

Y用空列表预先初始化[]。而且我不认为n第一次迭代中问题的价值。
雅库布2015年

顺便说一句,您的代码不会产生以开头的加扰U
雅库布2015年

@Jakube谢谢,固定。
PurkkaKoodari'3

4

JavaScript的(ES6)175 178 204

编辑 3个字节,更改代码1个,更改字节计数的方式2个(不计数F=

避免重复的代码来自@stevemiller。他管理信件组的方式甚至更好,但我不会偷它。

奖励:您可以选择指定移动次数。

(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

少打高尔夫球

(n = 25) => 
{
  R = n => Math.random()*n | 0;
  N = _ => 'UDRLFB'[(r += 1+R(5)) % 6];
  r = 0;
  b = N();
  a = N();
  for(s = '' ; n; )
     c = N(),
     ~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')
       ? 0
       : s += (--n, a=b, b=c) + ["","'",2][R(3)];
  return s
}

测试

var F=
(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

function go() {
  console.log(F(+M.value))
}

go()
Moves <input type=number min=1 id=M value=25 max=999>
<button onclick='go()'>Test</button>


2

Javascript-112

for(c=b=j=25,r=Math.random;j;c+b-5|c-m&&b-m?document.write("URFBLD"[j--,c=b,b=m]+" 2'"[0|r()*3]+" "):0)m=0|r()*6

2

Java的8,189个 183字节

v->{for(int i=26,n,m=0,r=0,s=0,t;i-->0;){for(n=m,t=1;t>0;t=m*n==9?1:0)m=(r=(int)(Math.random()*15))/3+1;s+=m;if(i<25)System.out.print("URFDLB".charAt(s%6)+(r%3<1?"'":r%3<2?"2":""));}}

@LevelRiverSt的C答案的端口。我自己尝试了一些东西,但是比我尝试的要短。

在线尝试。



1

Clojure,223个字节

(let[R(range)F(fn[f p c](apply concat(filter f(partition-by p c))))](apply str(map str(take 25(F(fn[p](<(count p)3))(zipmap"UDLF""1122")(F(fn[p](=(count p)1))int(for[_ R](rand-nth"UDRLFB")))))(for[_ R](rand-nth[""\'\2])))))

这在很大程度上依赖于“序列->按分区->过滤->结合”模式,用于过滤掉“非法”的面部序列。然后将该序列与随机后缀(包括空字符串)一起映射到字符串。

空洞的起点:

(->> (for[_(range)](rand-nth"UDRLFB"))
     (partition-by int)           ; "identity" would be the correct fn to use here
     (filter(fn[p](=(count p)1))) ; Only one identical value in partition
     (apply concat)
     (partition-by(zipmap"UDLF""1122")) ; R & B are in the implicit nil group
     (filter(fn[p](<(count p)3)))       ; Only 1 or 2 consecutive faces from a group
     (apply concat)
     (take 25))
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.