掷骰子


16

掷骰子

因此,前一段时间我在掷骰子,想到了一个挑战。

给定具有从输入中取出的网和移动列表的多维数据集,请在末尾的底部找到正方形。

立方体地图

我将在此处的示例中使用此图像。

输入值

您输入一个带有动作列表的字符串。该字符串仅包含大写ASCII字母N,S,W和E。这对应于将多维数据集向该方向滚动一步。

在图片中,一个N将使底面变成6。在此图片中,North远离相机,South朝向相机,East右侧,West左侧。

您还可以采用以下格式的字符串:1P 2P 3P 4P 5P 6P,其中每个P是N,S,W,E,T和B中的一个位置。T&B是底部和顶部。

数字是带有该数字的面部,字母代表面部所在的位置。如果不清楚,网将始终按该编号排序,因此1P 2P 3P 4P 5P 6P,而不是2B 1T 3N 4S 5W 6E。

图像中的位置是1S 2B 3E 4W 5T 6N。

输出量

您的程序应输出一个代表底部的数字。

测试用例

(nothing), 1S 2B 3E 4W 5T 6N -> 2
N, 1S 2B 3E 4W 5T 6N -> 6
NS, 1S 2B 3E 4W 5T 6N -> 2
NWS, 1S 2B 3E 4W 5T 6N -> 2
NWSNWS, 1S 2B 3E 4W 5T 6N -> 2
NWSS, 1S 2B 3E 4W 5T 6N -> 3
NNNNNN, 1S 2B 3E 4W 5T 6N -> 5
SNWEEWS, 1N 2T 3E 4W 5B 6S, 6
SNEEWS, 1N 2T 3W 4S 5B 6E, 4

其他规定

您可能还假设立方体处于无限平坦的平面上,可能存在某种摩擦。

即使我找不到任何漏洞,也不允许出现标准漏洞。

对于无效的输入,您的代码可以执行任何操作,但不能启动启示录。

由于此程序应适合我的骰子,因此应尽可能小。我以字节为单位,但Folders等语言除外。


2
第一个测试用例是否(nothing) -> 2意味着没有提供网,还是某个地方应该有网?
Sp3000

2
在图片中,一个N将使底面为2 ”不是底面已经为2了吗?
paulvs 2015年

@ Sp3000,已编辑,应该提供网络,但是您的代码应该不能处理任何移动命令。
Rɪᴋᴇʀ

1
您以字节为单位来衡量骰子的大小吗?
Cyoce

@Cyoce不,只是每张脸上的文字。因此带有🍄的脸将是4个字节。对于这个挑战,我希望能够适应您在骰子上编写的代码。为此,我需要小的代码。
Rɪᴋᴇʀ

Answers:


8

CJam,43 40 37 34字节

感谢Dennis帮助我节省了6个字节。

lW%3/$1f=q{i8%"ÉĔɠƂ!"=i\m!=}/c

在这里测试。

说明

lW%    e# Read the first line and reverse it.
S/     e# Split it around spaces.
$      e# Sort it. This puts the faces in order [B E N S T W].
1f=    e# Select the second character from each face, which is the number.
q      e# Read the remainder of the input (the instructions).
{      e# For each instruction...
  i8%  e#   Convert the character (NWSE) to an integer and take modulo 8.
  "ÉĔɠƂ!"=i
       e#   Use that to (cyclically) index this string and convert *that* character
       e#   to an integer.
  \    e#   Swap with the list of faces.
  m!   e#   Generate all permutations of the faces.
  =    e#   Select the permutation corresponding to the above integer.
}/     e# At the end of the loop, the bottom face will be the first character.
c      e# Convert the string to a character, which discards everything but the bottom face.

关于指令字符到排列的映射如何工作,这是一个方便的表:

   i   8%  5%  ""=   i   [0 1 2 3 4 5]m!=

N  78   6   1   Ĕ   276  [2 1 4 0 3 5]
W  87   7   2   ɠ   608  [5 0 2 3 1 4]
S  83   3   3   Ƃ   386  [3 1 0 4 2 5]
E  69   5   0   É   201  [1 4 2 3 5 0]

我之所以包含该5%列,是因为这是对字符串的循环索引隐式执行的操作。对于这四个排列,我们可以看到它们中的每一个都使两个(相反的)面保持不变,并循环排列另外四个。


您如何将排列表示为那些Unicode字符?Ĕ如何表示N [2 1 4 0 3 5]的排列?我一直盯着它看了好几个小时。
paulvs 2015年

1
@paulvs的字符代码Ĕ2766e!为您提供的所有 720个排列的列表[0 1 2 3 4 5]。并且276恰好是该[2 1 4 0 3 5]列表中的索引。
马丁·恩德

我希望会有更多的人来回答,但您最短。恭喜。
Rɪᴋᴇʀ

5

Perl中,166 158 154 144 139 135 134 132 116字节

包括+1 -p

s/(\d)(.)/$h{$2}=$1/eg;$N='NTSB',$S='STNB',$E='ETWB',$W='WTEB';map{@h{@l}=@h{(@l=$$_=~/./g)[1..3,0]}}/\w/g;$_=$h{B}

有评论:

                                    # example input: "NS, 1S 2B 3E 4W 5T 6N"
s/(\d)(.)/$h{$2}=$1/eg;             # construct %h ( S=>1, B=>2, E=>3, W=>4, B=>2, N=>6 )

                                    # = Transformations =
$N='NTSB',                          # N becomes T, T becomes S, S becomes B, B becomes N
$S='STNB',
$E='ETWB',
$W='WTEB';

map {                               # iterate the moves "NS"
    @h{ @l } =                      # LHS: bulk-assign new values; @l defined in RHS
      @h{                           # RHS: init @l, transform
          (@l=$$_=~/./g)            # get transform, put ('N','T','S','B') in @l for LHS
          [1..3,0]                  # construct a rotated slice for RHS
    }    
} /\w/g;                            # match the movements in list context

$_=$h{B}                            # assign the bottom face to output.


输入文件:

, 1S 2B 3E 4W 5T 6N
N, 1S 2B 3E 4W 5T 6N
NS, 1S 2B 3E 4W 5T 6N
NWS, 1S 2B 3E 4W 5T 6N
NWSNWS, 1S 2B 3E 4W 5T 6N
NWSS, 1S 2B 3E 4W 5T 6N
NNNNNN, 1S 2B 3E 4W 5T 6N
SNWEEWS, 1N 2T 3E 4W 5B 6S
SNEEWS, 1N 2T 3W 4S 5B 6E

与运行

perl -p dice.pl < input.txt

输出: 262223564


  • 更新158使用$N, $S, $E, $W全局变量而不是%t = {N=>, S=>, E=>, $W=>}节省8个字节。

  • 更新154由于要求程序输出数字,所以不打印换行符print "$h{B}\n"将节省4个字节:print $h{B}

  • 更新144通过执行以下操作节省10个字节

    ($s)=/^(\w+),/;            s/(\d)(.)/$h{$2}=$1/eg;
    

    代替

    ($s,@i)=split /,? |\n/;    %h=reverse map{split//}@i;
    
  • 更新139将命令的正则表达式移到末尾以消除变量,节省6个字节。

  • 更新135保存4个字节@l[0..3,0]而不是@l[1..3],$l[0]

  • 更新134通过使用分配@l=split//,$$_作为值保存1个字节。

  • 更新132通过执行/^\w+/ && $&而不是保存2个字节/^(\w+)/ && $1

  • 更新129通过使用-p代替-n$ _和分配$ _进行打印以节省3个字节。

  • 更新116通过重写split//, /^\w+/ && $&为节省13个字节/^\w+/g



4

Python 2,204字节

以为是时候回答我自己的问题了。

def x(p,m):
    d={p[3*i-2]:i for i in range(1,7)}
    for j in m:n=2if j in'NE'else-2;x='BSTN'if j in'NS'else'BETW';d[x[0]],d[x[1]],d[x[2]],d[x[3]]=d[x[1+n]],d[x[(2+n)%4]],d[x[(3+n)%4]],d[x[0+n]]
    print d['B']

不是很短,但是可以。

运行方式:

x('1B 2T 3N 4S 5W 6E','SNEEWS')
#Output: 4

编辑:计数字节错误。现在更长。:(


顺便说一句,感谢xnor的python宏。
Rɪᴋᴇʀ
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.