我接受了技术支持职位的面试测试。我认为我没有做好,因为他们没有回电话。我不关心这份工作,但其中一个问题困扰着我,因为我只能把它弄清楚。 我有一个机器人能够读取每行包含一条指令的指令。左转为“L”,右转为“R”,向前移动的数字为#n。 机器人朝北,坐标为(0,0) 这些是说明:
R
L
L
9
4
1
7
9
R
2
所以指示说 - 向右转90度(使其朝向东方),然后再次向左和向左转(使其朝向西)向前走30步,然后顺时针转90度(使其朝北)并向前迈出两步。 他们希望我写一个可以计算最大距离和坐标对(x和y值)的脚本 他们在上面的说明中给了我答案,机器人从开始走的最大距离是30.07,坐标对是(-30,2)
我理解机器人在视觉上的运动并写了一个bash数组,它为顺时针运动增加了10的x值,并从x的值中减去了10,用于逆时针方向运动。廉价的bash数组(bash 3.2没有数组支持)将x VALUE与一个360位置或四个箭头键之一匹配。脚本在向前移动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
在bash中找到x和y坐标
答案 0 :(得分: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
答案 1 :(得分: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.
答案 2 :(得分:0)
用awk:
awk -f script.awk文件
<强> script.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