找到x和y轴上的坐标对

  • 本文关键字:坐标 找到 bash
  • 更新时间 :
  • 英文 :


我参加了一个技术支持职位的面试测试。我想我做得不好,因为他们没有回电话。我不在乎这份工作,但其中一个问题困扰着我,因为我只能想一半。我有一个机器人,它能够读取每行包含一条指令的指令。"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

相关内容

  • 没有找到相关文章

最新更新