2016-05-31 78 views
2

我有一个技术支持职位的面试测试。我认为我做得不好,因为他们没有回电话。我不关心这个工作,但是其中一个问题困扰着我,因为我只能弄明白这一点。 我有一个机器人能够读取指令,每行包含一条指令。左转“L”,右转“R”,移动#n前进。 该机器人朝北,坐标为(0,0) 这些指令:bash - 在x和y轴上查找坐标对。

R 
L 
L 
9 
4 
1 
7 
9 
R 
2 

于是指示说 - 右转90度(这让它朝东),然后左转,离开再次(使其朝向西)向前走30步,然后顺时针旋转90度(使其朝北),并向前移动两步。 他们想让我编写一个脚本来计算最大距离和坐标对(x和y值)
他们给了我上面说明中的答案,机器人从一开始就走的最大距离是30.07,坐标对是(-30,2)

我知道机器人的运动是可视化的,并且写了一个bash数组,它为x的值顺时针移动增加10,从计数器计数器时钟的x减去10明智的运动。便宜的bash数组(bash 3.2没有数组支持)与一个360位置的KEY或四个箭头键中的一个匹配x VALUE。该脚本在向前移动n#个步骤之前保存最后的指令。我不知道如何在最大距离和坐标对中编写脚本。它是一个代数x和y轴函数 - 但无法弄清楚如何将它添加到bash中。

#!/bin/bash 
#set -x 


dial_map=("up_1:10" "right_1:20" "down_1:30" "left_1:40" 
     "up_2:50" "right_2:60" "down_2:70" "left_2:80" 
     "up_3:90" "right_3:100" "down_3:110" "left_3:120") 
x=50 # the robot starts at the up or north position 
    # once clockwise click adds ten, one counter clockwise minus 10 from x value. 

IFS=$'\n' read -d"" -r -a directives < directions.txt 

for i in "${directives[@]}" 
    do 
    if [ "$i" == "R" ] ; then 
     #echo "R is clockwise" 
     x=$(($x + 10)) 
     #echo "x is $x" 
     for click in "${dial_map[@]}" ; do 
      KEY=${click%%:*} 
      VALUE=${click#*:} 
      if [ "$x" -eq "$VALUE" ] ; then 
       keytab=$KEY 
       #echo "the keyboard command is $keytab" 
     fi 
     #sleep 1 
     done 
    elif [ "$i" == "L" ] ; then 
     #echo "L is counterclock" 
     x=$(($x - 10)) 
     #echo "x is $x" 
     for click in "${dial_map[@]}" ; do 
      KEY=${click%%:*} 
      VALUE=${click#*:} 
      if [ "$x" -eq "$VALUE" ] ; then 
       keytab=$KEY 
       #echo "the keyboard command is $keytab" 
     fi 
     #sleep 1 
     done 
    else 
     echo "Please move the cursor $i times $keytab" 
     sleep 1 
    fi 
done 

寻找x和y坐标在bash

回答

2

这里是做无关联数组的方法,该如果我正确读取是一个要求 - 其实我最初读完全没有阵列;这就是我使用这么多变量的原因。您可以使用关联数组而不是我使用的case语句。我对指令进行了硬编码,但是从文件中读取它们并不重要。在评论和回声声明之间,希望自我解释。

#!/bin/bash - 

inst=(R L L 9 4 1 7 9 R 2) 
# compass to cartesian translation 
#    x = 1 : N 
#    ^
#     | 
# y = -1 : W <---------> y = 1 : E 
#     | 
#     v 
#    x = -1 : S 

startloc_x=0 
startloc_y=0 
newloc_x=0 
newloc_y=0 
dir_x=1 
dir_y=0 
a=0; 
for i in ${inst[@]}; do 
    ((a++)) 
    echo "[$a] Next Instruction: $i" 
    slct="${i}${dir_x}${dir_y}" 

# lookup table for case statement 
# 
# X Y  turning Right  turning left 
# 1 0   0 1    0 -1 
# 0 1  -1 0    1 0 
# -1 0   0 -1    0 1 
# 0 -1   1 0    -1 0 
    case $slct in 
    R10|L-10) 
      dir_x=0 
      dir_y=1 
      ;; 
    R01|L0-1) 
      dir_x=-1 
      dir_y=0 
      ;; 
    R-10|L10) 
      dir_x=0 
      dir_y=-1 
      ;; 
    R0-1|L01) 
      dir_x=1 
      dir_y=0 
      ;; 
      *) 
      ((newloc_x += $i * dir_x)) 
      ((newloc_y += $i * dir_y)) 
      ;; 
    esac 
    echo "[$a] Current location (x,y) = ($newloc_x, $newloc_y)" 
    echo "[$a] Current direction (x,y) = ($dir_x, $dir_y)" 
    echo 
done 
echo;echo "---" 
echo "Finished processing $a instructions" 
echo "Starting Location: (x,y) ($startloc_x, $startloc_y)" 
echo "Ending Location: (x,y) ($newloc_x, $newloc_y)" 
echo "Final Direction: (x,y) ($dir_x, $dir_y)"    
delta_x=0 
delta_y=0 
((delta_x = $newloc_x - $startloc_x)) 
((delta_y = $newloc_y - $startloc_y)) 
distance=`echo "sqrt((${delta_x}.000)^2 + (${delta_y}.000)^2)" | bc` 
echo "Distance traveled = $distance" 
echo 

最终输出:

Finished processing 10 instructions 
Starting Location: (x,y) (0, 0) 
Ending Location: (x,y) (2, -30) 
Final Direction: (x,y) (1, 0) 
Distance traveled = 30.066 
2

采取另一种方法,(使用相同的坐标),在case声明和bc基本上都是你的需要:

#!/bin/bash 

dir=${1:-n}    ## (n) north (s) south (e) east (w) west 
fn=${2:-/dev/stdin}  ## input file name (stdin default) 

declare -i posx=0 
declare -i posy=0 

while read -r cmd || [ -n "$cmd" ]; do 
    case "$cmd" in 
     [0-9]*) 
      case "$dir" in 
       n) ((posy += cmd)) ;; 
       w) ((posx -= cmd)) ;; 
       s) ((posy -= cmd)) ;; 
       e) ((posy += cmd)) ;; 
      esac 
      ;; 
     R) 
      case "$dir" in 
       n) dir='e' ;; 
       w) dir='n' ;; 
       s) dir='w' ;; 
       e) dir='s' ;; 
      esac 
      ;; 
     L) 
      case "$dir" in 
       n) dir='w' ;; 
       w) dir='s' ;; 
       s) dir='e' ;; 
       e) dir='n' ;; 
      esac 
      ;; 
    esac 
done <"$fn" 

dist=$(printf "scale=2; sqrt($posx*$posx+$posy*$posy)\n" | bc) 

printf "final coordinates (%d, %d)\n" "$posx" "$posy" 
printf "distance traveled: %s units.\n" "$dist" 

示例使用/输出

$ bash robotstat.sh <dat/robot.txt 
final coordinates (-30, 2) 
distance traveled: 30.06 units. 
0

使用awk:

的awk -f script.awk文件

脚本。AWK

#! /bin/awk -f 
BEGIN{ 
    codX=0; 
    codY=1; 
    X=0; 
    Y=0 
} 
$1~"R"{ 
    tmp = codX; 
    codX = codY; 
    codY = tmp*-1 
} 
$1~"L"{ 
    tmp=codX; 
    codX=codY*-1; 
    codY=tmp 
} 
$1 ~ /[[:digit:]]/{ 
    X += codX*$1; 
    Y += codY*$1 
} 
END{ 
    print "Co-ordinate(X,Y) : ("X","Y")"; 
    print "Distance : " sqrt(X^2+Y^2) 
} 

输出

Co-ordinate(X,Y) : (-30,2) 
Distance : 30.0666