Skip to content

Commit b9235b0

Browse files
authored
Add the maze problem (#112)
1 parent d072d00 commit b9235b0

File tree

6 files changed

+95
-11
lines changed

6 files changed

+95
-11
lines changed

README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,25 @@ Welcome to **Data Structures and Algorithms in Go**! 🎉 This project is design
8585
* [Exponentiation](./recursion/exponentiation_test.go)
8686
* [Regular Expressions Matching](./recursion/regular_expressions_test.go)
8787
* [Expression Operators](./recursion/expression_operators_test.go)
88-
* [Divide and Conquer](./dnc//README.md)
88+
* [Divide and Conquer](./dnc/README.md)
8989
* [Binary Search](./dnc/binary_search_test.go)
9090
* [Square Root with Binary Search](./dnc/square_root_test.go)
9191
* [Rate Limit](./dnc/rate_limit_test.go)
9292
* [Towers of Hanoi](./dnc/towers_of_hanoi_test.go)
9393
* [Merge Sort](./dnc/merge_sort_test.go)
9494
* [Quick Sort](./dnc/quick_sort_test.go)
95-
* [Bit Manipulation](./bit//README.md)
95+
* [Bit Manipulation](./bit/README.md)
9696
* [Division without multiplication or division operators](./bit/division_without_operators_test.go)
9797
* [Middle without division](./bit/middle_without_division_test.go)
9898
* [Addition without using plus (+) or any other arithmetic operators](./bit/addition_without_operators_test.go)
9999
* [Power of Two](./bit/is_power_of_two_test.go)
100100
* [Maximum without if conditions](./bit/max_function_without_conditions_test.go)
101101
* [Oddly Repeated Number](./bit/oddly_repeated_number_test.go)
102-
* [Backtracking](./backtracking//README.md)
102+
* [Backtracking](./backtracking/README.md)
103103
* [Permutations](./backtracking/permutations_test.go)
104104
* [Generate Parentheses](./backtracking/generate_parentheses_test.go)
105105
* [Phone Letter Combinations](./backtracking/phone_letter_combinations_test.go)
106+
* [Maze](./backtracking/maze_test.go),
106107
* [Sudoku](./backtracking/sudoku_test.go)
107108
* [N Queens](./backtracking/n_queens_test.go)
108109
* [Graphs](./graph/README.md)

backtracking/README.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ Backtracking is widely used to solve board games and computers use it to select
2525

2626
## Permutations
2727

28-
* [Permutations](permutations_test.go), [Solution](permutations.go)
29-
* [Generate Parentheses](./generate_parentheses_test.go), [Solution](generate_parentheses.go)
30-
* [Phone Letter Combinations](phone_letter_combinations_test.go), [Solution](phone_letter_combinations.go)
31-
* [Sudoku](sudoku_test.go), [Solution](sudoku.go)
32-
* [N Queens](n_queens_test.go), [Solution](n_queens.go)
28+
* [Permutations](./permutations_test.go), [Solution](./permutations.go)
29+
* [Generate Parentheses](./generate_parentheses_test.go), [Solution](./generate_parentheses.go)
30+
* [Phone Letter Combinations](./phone_letter_combinations_test.go), [Solution](./phone_letter_combinations.go)
31+
* [Maze](./maze_test.go), [Solution](./maze.go)
32+
* [Sudoku](./sudoku_test.go), [Solution](./sudoku.go)
33+
* [N Queens](./n_queens_test.go), [Solution](./n_queens.go)

backtracking/maze.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package backtracking
2+
3+
var (
4+
directions = [4][2]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}
5+
directionLetter = map[int]string{0: "r", 1: "l", 2: "d", 3: "u"}
6+
)
7+
8+
// Maze solves the problem in O(mn) time and O(mn) space complexity.
9+
func Maze(m, n int, walls [][2]int, start, finish [2]int) string {
10+
wallMap := make(map[[2]int]bool)
11+
for _, wall := range walls {
12+
wallMap[wall] = true
13+
}
14+
15+
visited := make([][]bool, m)
16+
for i := range visited {
17+
visited[i] = make([]bool, n)
18+
}
19+
20+
return mazeRecursive(start[0], start[1], "", wallMap, visited, finish)
21+
}
22+
23+
func mazeRecursive(x, y int, path string, wallMap map[[2]int]bool, visited [][]bool, finish [2]int) string {
24+
if x == finish[0] && y == finish[1] {
25+
return path
26+
}
27+
28+
visited[x][y] = true
29+
for i := 0; i < 4; i++ {
30+
nx, ny := x+directions[i][0], y+directions[i][1]
31+
if nx >= 0 && nx < len(visited) && ny >= 0 && ny < len(visited[0]) && !visited[nx][ny] && !wallMap[[2]int{nx, ny}] {
32+
if result := mazeRecursive(nx, ny, path+directionLetter[i], wallMap, visited, finish); result != "" {
33+
return result
34+
}
35+
}
36+
}
37+
return ""
38+
}

backtracking/maze_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package backtracking
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
/*
9+
TestMaze tests solution(s) with the following signature and problem description:
10+
11+
func Maze(walls [][2]int, start, finish [2]int,m,n int) string
12+
13+
Given the coordinates of walls in a m x n maze in tuples of {row, col} format, and start
14+
and finish coordinates in the same format, find a path from start to finish. return
15+
a string of directions like `lrud` (left, right, up, down) to get a robot from
16+
start to finish.
17+
18+
The robot can only move in the four left, right, down and up directions and not
19+
through walls. The robot does not know where the finish line is so it has to
20+
explore every possible cell in the order of directions given.
21+
*/
22+
func TestMaze(t *testing.T) {
23+
tests := []struct {
24+
m int
25+
n int
26+
walls [][2]int
27+
start [2]int
28+
finish [2]int
29+
moves string
30+
}{
31+
{1, 1, [][2]int{}, [2]int{0, 0}, [2]int{0, 1}, ""},
32+
{5, 5, [][2]int{}, [2]int{0, 0}, [2]int{0, 1}, "r"},
33+
{10, 10, [][2]int{}, [2]int{0, 0}, [2]int{0, 1}, "r"},
34+
{5, 5, [][2]int{}, [2]int{0, 0}, [2]int{4, 4}, "rrrrdlllldrrrrdlllldrrrr"},
35+
{5, 5, [][2]int{{1, 1}, {1, 2}, {1, 3}, {2, 3}, {3, 3}, {3, 4}}, [2]int{0, 0}, [2]int{2, 4}, "rrrrdd"},
36+
{5, 5, [][2]int{{0, 0}, {0, 1}, {0, 2}, {0, 3}, {1, 3}, {2, 1}, {2, 2}, {2, 3}, {3, 1}, {4, 1}}, [2]int{4, 0}, [2]int{1, 2}, "uuurr"},
37+
{5, 5, [][2]int{{1, 0}, {1, 1}, {1, 2}, {1, 3}, {3, 1}, {3, 2}, {3, 3}, {3, 4}}, [2]int{0, 0}, [2]int{4, 4}, "rrrrddllllddrrrr"},
38+
{5, 5, [][2]int{{1, 0}, {1, 1}, {1, 4}, {1, 3}, {3, 1}, {3, 2}, {3, 3}, {3, 4}}, [2]int{0, 0}, [2]int{4, 4}, "rrddllddrrrr"},
39+
}
40+
41+
for i, test := range tests {
42+
if got := Maze(test.m, test.n, test.walls, test.start, test.finish); !reflect.DeepEqual(test.moves, got) {
43+
t.Fatalf("Failed test case #%d. Want %s got %s", i, test.moves, got)
44+
}
45+
}
46+
}

heap/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A heap must satisfy two conditions:
77
1. The structure property requires that the heap be a complete binary search [tree](../tree), where each level is filled from left to right, and all levels except the bottom are full.
88
2. The heap property requires that the children of a node be larger than or equal to the parent node in a min heap and smaller than or equal to the parent in a max heap, meaning that the root is the minimum in a min heap and the maximum in a max heap.
99

10-
As a result, if all elements are pushed to the min or max heap and then popped one by one, a sorted list in ascending or descending order is attained. This sorting technique known as [heap sort](./heap_sort_test.go) works in O(n*Logn) time. While other sorting algorithms are available, none are more efficient than O(n*Log n).
10+
As a result, if all elements are pushed to the min or max heap and then popped one by one, a sorted list in ascending or descending order is attained. This sorting technique known as [heap sort](./heap_sort_test.go) works in O(n*Logn) time. While other comparison based sorting algorithms are available, none can be more efficient than O(n*Log n).
1111

1212
When pushing an element to a heap, because of the structure property, the new element is always added to the first available position on the lowest level of the heap, filling from left to right. Then to maintain the heap property, if the newly inserted element is smaller than its parent in a min heap (larger in a max heap), the newly added element is percolated up by being swapped with its parent. The child and parents are swapped until the heap property is achieved.
1313

recursion/expression_operators.go

-2
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@ func expressionOperatorsHelper(list []int, current int, operators string, target
1616
return ""
1717
}
1818

19-
// Try with the + operator
2019
result := expressionOperatorsHelper(list[1:], current+list[0], operators+"+", target)
2120
if result != "" {
2221
return result
2322
}
2423

25-
// Try with the - operator
2624
result = expressionOperatorsHelper(list[1:], current-list[0], operators+"-", target)
2725
if result != "" {
2826
return result

0 commit comments

Comments
 (0)