首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >J中的火星漫游者问题

J中的火星漫游者问题
EN

Code Review用户
提问于 2017-11-11 16:35:00
回答 1查看 779关注 0票数 4

我编写了一个“著名”火星车模拟 (关于这个的另一个问题)的实现,其问题陈述如下:

输入的第一行是平台的右上坐标,左下角的坐标假定为0,0。其余的输入是与已部署的漫游者有关的信息。每个漫游者有两条输入线。第一行给出了火星车的位置,第二行是一系列指示,告诉探测器如何探索高原。该位置由两个整数和一个由空格分隔的字母组成,它们对应于x和y坐标以及漫游者的方位。每个漫游者将按顺序完成,这意味着第二个漫游者将不会开始移动,直到第一个已经完成移动。输出:每个漫游者的输出应该是其最后的协调和航向.测试输入:5 5 1 2 N LMLMLMLMM 3 3 E MMRMMRMRRM预期输出:1 3 N5 1 E

这是我的工作解决方案:

代码语言:javascript
运行
复制
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 ''

我的计划基本上是这样的:

  1. 运行一个当前面向输入的状态机,以确定每个命令执行时面对的是什么。这是facing计算出来的。
  2. 获取每个M命令的对应面
  3. 取“移动”向量之和,得到坐标的总变化。N=0. 1,所以面对N的三次移动是0.1+0.1+0.1=0.
  4. 解是坐标与初始坐标的总变化之和,再加上最终的面向状态。

我想回顾一下,看看这段代码是否是惯用的J,是否有更直接的方法来完成我在这里要做的事情,特别是在simulate动词中,是否有更好的方法来处理拆分输入并将其传递给其他动词。我很高兴我找到了如何使用顺序机,但总的来说,这个解决方案让我感到有点气馁。但我还没有找到另一个可以与之相比的实现。

EN

回答 1

Code Review用户

回答已采纳

发布于 2019-06-05 03:26:53

我为任何使用顺序机器而鼓掌。模拟状态机的原语..。只有J树才能产生..。为什么要反抗?

因此,在这种情况下,;:是典型的J,而状态机则是思维方式上的过程。相比之下,习语J倾向于把问题概括为一个整体来解决,而不是一步一步地解决问题。

在这种情况下我们怎么能做到呢?

最大的窍门是将方向编码成复数。L只将当前方向乘以i,在J中乘以0j1R乘以0j_1。然后,在任何时间点上,你的方向只是你的起始位置的扫描产品*/\,以及编码的LR序列。对于这个步骤,M被编码为1,因为它不会改变方向。

让我们来看看第一个例子是什么样子。编码的命令(顶部)及其扫描产品(底部):

代码语言:javascript
运行
复制
┌───┬───┬──┬────┬────┬───┬─┬───┬───┬───┐
│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的布尔掩码:

代码语言:javascript
运行
复制
┌───┬──┬──┬────┬────┬─┬─┬───┬───┬───┐
│0j1│_1│_1│0j_1│0j_1│1│1│0j1│0j1│0j1│
├───┼──┼──┼────┼────┼─┼─┼───┼───┼───┤
│0  │0 │1 │0   │1   │0│1│0  │1  │1  │
└───┴──┴──┴────┴────┴─┴─┴───┴───┴───┘

使用您的代码进行参数解析,并将所有这些放在一起,我们得到:

代码语言:javascript
运行
复制
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
)

并运行它:

代码语言:javascript
运行
复制
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

生产:

代码语言:javascript
运行
复制
┌─┬─┬─┬──────────┐
│1│2│N│LMLMLMLMM │
├─┼─┼─┼──────────┤
│3│3│E│MMRMMRMRRM│
└─┴─┴─┴──────────┘
┌───┬─┐
│1 3│N│
├───┼─┤
│5 1│E│
└───┴─┘

在网上试试!

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/180169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档