我参加了一个技术支持职位的面试测试。我想我做得不好,因为他们没有回电话。我不在乎这份工作,但其中一个问题困扰着我,因为我只能想一半。我有一个机器人,它能够读取每行包含一条指令的指令。"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数组,顺时针运动时将x值加10,逆时针运动时从x值减去10。廉价的bash数组(bash 3.2不支持数组)将x值与一个KEY匹配,该KEY是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坐标
这里有一个在没有关联数组的情况下实现这一点的方法,如果我读得正确,这是一个要求——实际上我最初根本不读数组;这就是为什么我使用了这么多变量。您可以使用关联数组,而不是我使用的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
采用另一种方法(使用相同的坐标),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.
带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