dirReduc()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 14
nc 3
nop 1
dl 0
loc 19
rs 9.7998
c 0
b 0
f 0
1
<?php
2
/*
3
Once upon a time, on a way through the old wild west,…
4
5
… 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!
6
How I crossed the desert the smart way.
7
8
The directions given to the man are, for example, the following (depending on the language):
9
10
["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"].
11
12
or
13
14
{ "NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST" };
15
16
or
17
18
[North, South, South, East, West, North, West]
19
20
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:
21
22
["WEST"]
23
24
or
25
26
{ "WEST" }
27
28
or
29
30
[West]
31
32
Other examples:
33
34
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.
35
36
The path becomes ["EAST", "WEST"], now "EAST" and "WEST" annihilate each other, therefore, the final result is [] (nil in Clojure).
37
38
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"].
39
Task
40
41
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).
42
*/
43
44
function dirReduc($array)
45
{
46
    $stack = [];
47
    $opposite = array(
48
        "NORTH" => "SOUTH",
49
        "EAST" => "WEST",
50
        "SOUTH" => "NORTH",
51
        "WEST" => "EAST"
52
    );
53
    $array_count = count($array);
54
    $index = 0;
55
    while ($index < $array_count) {
56
        if ($opposite[$array[$index]] == end($stack)) {
57
            array_pop($stack);
58
        }
59
        array_push($stack, $array[$index]);
60
        $index++;
61
    }
62
    return $stack;
63
}
64
65
// Alternate solution:
66
67
function altdirReduc($array)
68
{
69
    $ops = ['NORTH' => 'SOUTH', 'SOUTH' => 'NORTH', 'EAST' => 'WEST', 'WEST' => 'EAST'];
70
    $stack = [];
71
    foreach ($array as $value) {
72
        if (end($stack) == $ops[$value]) {
73
            array_pop($stack);
74
        }
75
        $stack[] = $value;
76
    }
77
    return $stack;
78
}
79