我编写了一个“著名”火星车模拟 (关于这个的另一个问题)的实现,其问题陈述如下:
输入的第一行是平台的右上坐标,左下角的坐标假定为0,0。其余的输入是与已部署的漫游者有关的信息。每个漫游者有两条输入线。第一行给出了火星车的位置,第二行是一系列指示,告诉探测器如何探索高原。该位置由两个整数和一个由空格分隔的字母组成,它们对应于x和y坐标以及漫游者的方位。每个漫游者将按顺序完成,这意味着第二个漫游者将不会开始移动,直到第一个已经完成移动。输出:每个漫游者的输出应该是其最后的协调和航向.测试输入:5 5 1 2 N LMLMLMLMM 3 3 E MMRMMRMRRM预期输出:1 3 N5 1 E
这是我的工作解决方案:
dirs =: 'NESW'
input =. _4]\ 2 }. '' cut (' ',LF) charsub fread '~/Desktop/marsrover.txt'
NB. State transitions are the directions rotated forward and backwards
st =. 0,."1~ (] ,. 1 |. ] ,. _2 |. ]) i. # dirs
NB. R = 1, L = 2, anything else = 0
a =. ('R'=a.) + (2 * 'L'=a.)
NB. Run the state machine against the input, initial facing on left
facing =: dirs {~ 4 {"1 ] ;:~ 5 ; st; a; 0 _1 , _1 ,~ dirs i. [
NB. Detect motion in each direction
moves =: ] #~ 1 - 'M' i. [
simulate =: monad define "1
'x0 y0 dir commands' =. y
pos =. ". x0, ' ', y0
f =. dir facing commands
dest =. pos + (+/ (dirs i. commands moves f) { 4 2 $ 0 1 1 0 0 _1 _1 0)
(": dest), ' ', {: f
)
echo simulate input
exit ''我的计划基本上是这样的:
facing计算出来的。M命令的对应面我想回顾一下,看看这段代码是否是惯用的J,是否有更直接的方法来完成我在这里要做的事情,特别是在simulate动词中,是否有更好的方法来处理拆分输入并将其传递给其他动词。我很高兴我找到了如何使用顺序机,但总的来说,这个解决方案让我感到有点气馁。但我还没有找到另一个可以与之相比的实现。
发布于 2019-06-05 03:26:53
我为任何使用顺序机器而鼓掌。模拟状态机的原语..。只有J树才能产生..。为什么要反抗?
因此,在这种情况下,;:是典型的J,而状态机则是思维方式上的过程。相比之下,习语J倾向于把问题概括为一个整体来解决,而不是一步一步地解决问题。
在这种情况下我们怎么能做到呢?
最大的窍门是将方向编码成复数。L只将当前方向乘以i,在J中乘以0j1,R乘以0j_1。然后,在任何时间点上,你的方向只是你的起始位置的扫描产品*/\,以及编码的L和R序列。对于这个步骤,M被编码为1,因为它不会改变方向。
让我们来看看第一个例子是什么样子。编码的命令(顶部)及其扫描产品(底部):
┌───┬───┬──┬────┬────┬───┬─┬───┬───┬───┐
│0j1│0j1│1 │0j1 │1 │0j1│1│0j1│1 │1 │
├───┼───┼──┼────┼────┼───┼─┼───┼───┼───┤
│0j1│_1 │_1│0j_1│0j_1│1 │1│0j1│0j1│0j1│
└───┴───┴──┴────┴────┴───┴─┴───┴───┴───┘我们最终将面对N,正如我们所希望的那样。
同样地,将复数作为向量加法,最后的位置就是初始位置之和和与M对应的每个方向向量的总和。后一和只是上面底部行的元素积之和,以及MS的布尔掩码:
┌───┬──┬──┬────┬────┬─┬─┬───┬───┬───┐
│0j1│_1│_1│0j_1│0j_1│1│1│0j1│0j1│0j1│
├───┼──┼──┼────┼────┼─┼─┼───┼───┼───┤
│0 │0 │1 │0 │1 │0│1│0 │1 │1 │
└───┴──┴──┴────┴────┴─┴─┴───┴───┴───┘使用您的代码进行参数解析,并将所有这些放在一起,我们得到:
NB. convert direction to complex number
j =: 0j1 ^ 'ENWS' i. ]
NB. full solution
final =. 3 : 0
'a b dir cmds' =. y
dirs=. */\ (j dir) , 0j1 ^ 'ML.R' i. cmds NB. all directions
pos =. (a j.&". b) + +/ dirs * 0 , 'M' = cmds NB. all positions
(+. pos) ; j inv {: dirs
)并运行它:
f=. 0 : 0
5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM
)
input =. _4]\ 2 }. '' cut (' ',LF) charsub f
echo input
echo final"1 input生产:
┌─┬─┬─┬──────────┐
│1│2│N│LMLMLMLMM │
├─┼─┼─┼──────────┤
│3│3│E│MMRMMRMRRM│
└─┴─┴─┴──────────┘
┌───┬─┐
│1 3│N│
├───┼─┤
│5 1│E│
└───┴─┘https://codereview.stackexchange.com/questions/180169
复制相似问题