2016-05-31 80 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