1. 程式人生 > >入坑codewars第17天-Directions Reduction

入坑codewars第17天-Directions Reduction

題目:

Once upon a time, on a way through the old wild west,…

… a man was given directions to go from one point to another. The directions were "NORTH", "SOUTH", "WEST", "EAST". Clearly "NORTH" and "SOUTH" are opposite, "WEST" and "EAST" too. Going to one direction and coming back the opposite direction is a needless effort. Since this is the wild west, with dreadfull weather and not much water, it's important to save yourself some energy, otherwise you might die of thirst!

How I crossed the desert the smart way.

The directions given to the man are, for example, the following:

["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"].

or

{ "NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST" };

or (haskell)

[North, South, South, East, West, North, West]

You can immediatly see that going "NORTH" and then "SOUTH" is not reasonable, better stay to the same place! So the task is to give to the man a simplified version of the plan. A better plan in this case is simply:

["WEST"]

or

{ "WEST" }

or (haskell)

[West]

or (rust)

[WEST];

Other examples:

In ["NORTH", "SOUTH", "EAST", "WEST"], the direction "NORTH" + "SOUTH" is going north and coming back right away. What a waste of time! Better to do nothing.

The path becomes ["EAST", "WEST"], now "EAST" and "WEST"annihilate each other, therefore, the final result is [] (nil in Clojure).

In ["NORTH", "EAST", "WEST", "SOUTH", "WEST", "WEST"], "NORTH" and "SOUTH" are not directly opposite but they become directly opposite after the reduction of "EAST" and "WEST" so the whole path is reducible to ["WEST", "WEST"].

Task

Write a function dirReduc which will take an array of strings and returns an array of strings with the needless directions removed (W<->E or S<->N side by side).

The Haskell version takes a list of directions with data Direction = North | East | West | South. The Clojure version returns nil when the path is reduced to nothing. The Rust version takes a slice of enum Direction {NORTH, SOUTH, EAST, WEST}.

Examples

dirReduc(@[@"NORTH", @"SOUTH", @"SOUTH", @"EAST", @"WEST", @"NORTH", @"WEST"]); // => @[@"WEST"]
dirReduc(@[@"NORTH", @"SOUTH", @"SOUTH", @"EAST", @"WEST", @"NORTH"]); // => @[]

See more examples in "Example Tests"

Note

Not all paths can be made simpler. The path ["NORTH", "WEST", "SOUTH", "EAST"] is not reducible. "NORTH" and "WEST", "WEST" and "SOUTH", "SOUTH" and "EAST" are not directly opposite of each other and can't become such. Hence the result path is itself : ["NORTH", "WEST", "SOUTH", "EAST"].

題意:

題意就是
一個人被指示從一個地方去另一個地方。方向是“北”、“南”、“西”、“東”。顯然,“北”和“南”是對立的,“西”和“東”也是對立的。朝一個方向去,又朝相反的方向回來,這是一種不必要的努力。因為這是蠻荒的西部,天氣很糟糕,水也不多,所以一定要節約一些能量,否則你會渴死的!
你馬上就能看到,先“北”再“南”是不合理的,還是呆在原地好!所以任務是給這個人一個簡化版的計劃。


(“北”、“南”、“東”、“西”)中,“北”+“南”的方向是向北,然後馬上返回。真是浪費時間!最好什麼也不做。
路徑變成[東"、"西"],現在"東"和"西"相互湮滅,因此,最終結果是[](Clojure中為nil)。
在[北"、"東"、"西"、"南"、"西"]中,"北"和"南"不是直接對立的,而是經過"東"和"西"的還原而成為直接對立的,所以整個路徑可以還原為[西"、"西"]。

寫一個函式dirReduc,它將取一個字串陣列,並返回一個字串陣列,去掉不必要的方向(W<->E或S<->N並排)。
Haskell版本採用一個方向列表,資料方向=北|東|西|南。當路徑被還原為空時,Clojure版本返回nil。鏽版採用了一個切片列舉方向{北,南,東,西}。

並不是所有的路徑都可以簡化。這條路(“北”、“西”、“南”、“東”)是不可簡化的。“北”與“西”、“西”與“南”、“南”與“東”不是直接對立的,不可能成為對立的。因此,結果路徑本身就是:[“北”、“西”、“南”、“東”]。
樣例:
a = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
test.assert_equals(dirReduc(a), ['WEST'])
u=["NORTH", "WEST", "SOUTH", "EAST"]
test.assert_equals(dirReduc(u), ["NORTH", "WEST", "SOUTH", "EAST"])

 

思路:

思路很簡單就是找相鄰的兩個列表元素的值
如果是相反的就刪除;
返回最後的列表

程式碼如下:

這次一次就通過了,哈哈

def dirReduc(arr):
    length=len(arr)
    i=0
    while i<length-1:
        if (arr[i]=='NORTH'and arr[i+1]=='SOUTH') or (arr[i+1]=='NORTH'and arr[i]=='SOUTH') or (arr[i]=='EAST'and arr[i+1]=='WEST') or (arr[i+1]=='EAST'and arr[i]=='WEST'):
            del arr[i]
            del arr[i]
            length=length-2
            i=0
        else:
            i=i+1
    return arr

看看大神的精簡程式碼:

def dirReduc(arr):
    dir = " ".join(arr)
    dir2 = dir.replace("NORTH SOUTH",'').replace("SOUTH NORTH",'').replace("EAST WEST",'').replace("WEST EAST",'')
    dir3 = dir2.split()
    return dirReduc(dir3) if len(dir3) < len(arr) else dir3
opposite = {'NORTH': 'SOUTH', 'EAST': 'WEST', 'SOUTH': 'NORTH', 'WEST': 'EAST'}

def dirReduc(plan):
    new_plan = []
    for d in plan:
        if new_plan and new_plan[-1] == opposite[d]:
            new_plan.pop()
        else:
            new_plan.append(d)
    return new_plan