| 1 | // Author: CCS & KeitoTobi1 |
| 2 | // Backtracking Supported. |
| 3 | fn main() { |
| 4 | // Adjacency matrix as a map |
| 5 | // Example 01 |
| 6 | graph_01 := { |
| 7 | 'A': ['B', 'C'] |
| 8 | 'B': ['A', 'D', 'E'] |
| 9 | 'C': ['A', 'F'] |
| 10 | 'D': ['B'] |
| 11 | 'E': ['F', 'B', 'F'] |
| 12 | 'F': ['C', 'E'] |
| 13 | } |
| 14 | |
| 15 | // Example 02 |
| 16 | graph_02 := { |
| 17 | 'A': ['B', 'C', 'D'] |
| 18 | 'B': ['E'] |
| 19 | 'C': ['F'] |
| 20 | 'D': ['E'] |
| 21 | 'E': ['H'] |
| 22 | 'F': ['H'] |
| 23 | 'G': ['H'] |
| 24 | 'H': ['E', 'F', 'G'] |
| 25 | } |
| 26 | |
| 27 | path_01 := depth_first_search_path(graph_01, 'A', 'F') |
| 28 | println('\n Graph_01: all path pattern from node A to node F is:') |
| 29 | print_pattern(path_01) |
| 30 | path_02 := depth_first_search_path(graph_02, 'A', 'H') |
| 31 | println('\n Graph_02: all path pattern from node A to node F is:') |
| 32 | print_pattern(path_02) |
| 33 | } |
| 34 | |
| 35 | fn depth_first_search_path(adj map[string][]string, start string, target string) [][]string { |
| 36 | mut sol := Solution{} |
| 37 | mut path := []string{} |
| 38 | mut visited := visited_init(adj) |
| 39 | |
| 40 | // false ... not visited yet: {'A': false, 'B': false, 'C': false, 'D': false, 'E': false} |
| 41 | sol.find_pattern(adj, mut visited, start, target, mut path) |
| 42 | return sol.pattern |
| 43 | } |
| 44 | |
| 45 | struct Solution { |
| 46 | pub mut: |
| 47 | pattern [][]string |
| 48 | } |
| 49 | |
| 50 | fn (mut s Solution) find_pattern(adj map[string][]string, mut visited map[string]bool, node string, target string, |
| 51 | mut path []string) { |
| 52 | path << node |
| 53 | visited[node] = true |
| 54 | if node == target { |
| 55 | print('\n Founded pattern: ${path}') |
| 56 | s.pattern << [path] |
| 57 | } |
| 58 | print('\n Exploring of node ${node} (true/false): ${adj[node]}') |
| 59 | for i, _ in adj[node] { |
| 60 | if !visited[adj[node][i]] { |
| 61 | mut temp := path.clone() |
| 62 | s.find_pattern(adj, mut visited, adj[node][i], target, mut temp) |
| 63 | } |
| 64 | } |
| 65 | visited[node] = false |
| 66 | print('\n Current: ${node} (only not visited) \n Visited: ${visited}') |
| 67 | } |
| 68 | |
| 69 | fn print_pattern(pat [][]string) { |
| 70 | for p in pat { |
| 71 | println(p) |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | // Creating aa map to initialize with of visited nodes .... all with false in the init |
| 76 | // so these nodes are NOT VISITED YET |
| 77 | fn visited_init(adj map[string][]string) map[string]bool { |
| 78 | mut temp := map[string]bool{} |
| 79 | for i, _ in adj { |
| 80 | temp[i] = false |
| 81 | } |
| 82 | return temp |
| 83 | } |
| 84 | |