Minimum Penalty Path Discussions | Algorithms | HackerRank
  • + 0 comments

    Golang solution just in case someone is looking. NOTE: Dijkstra will not work as explained [here]https://www.hackerrank.com/challenges/beautiful-path/forum/comments/121506). We need to go with brute force as input size is small, so a simple dfs/bfs needed to check all possible distances of a vertex from starting vertex(in this case 'A').

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "os"
        "strconv"
        "strings"
        "math"
    )
    
    /*
     * Complete the 'beautifulPath' function below.
     *
     * The function is expected to return an INTEGER.
     * The function accepts following parameters:
     *  1. 2D_INTEGER_ARRAY edges
     *  2. INTEGER A
     *  3. INTEGER B
     */
    
    func beautifulPath(n int32, edges [][]int32, A int32, B int32) int32 {
        const INF = int32(1024)
        
        adjList := edgeListToAdjList(n, edges)
    
        var queue [][]int32
        queue = append(queue, []int32{A, 0})
        
        dist := initDist(n)
        dist[A][0] = true
        
        result := INF
        
        for len(queue) > 0 {
            front := queue[0]
            u := front[0]
            d := front[1]
            
            queue = queue[1:]
            
            for _, edge := range adjList[u] {
                v := edge[0]
                w := edge[1]
                
                newDistForV := d | w
                
                if !dist[v][newDistForV] {
                    dist[v][newDistForV] = true
                    
                    queue = append(queue, []int32{v, newDistForV})
                    
                    if v == B {
                        result = int32(math.Min(float64(result), float64(newDistForV)))
                    }
                }
            }
        }
        
        if result == INF {
            return -1
        }
        
        return result
    }
    
    func initDist(V int32) map[int32]map[int32]bool {
        dist := make(map[int32]map[int32]bool)
        
        for i := int32(0); i <= V; i++ {
            dist[i] = make(map[int32]bool)
        }
        
        return dist
    }
    
    func edgeListToAdjList(V int32, edgeList [][]int32) [][][]int32 {
        adjList := make([][][]int32, V+1)
        
        for _, edge := range edgeList {
            u := edge[0]
            v := edge[1]
            w := edge[2]
            
            adjList[u] = append(adjList[u], []int32{v, w})
            adjList[v] = append(adjList[v], []int32{u, w})
        }
        
        return adjList
    }
    
    func main() {
        reader := bufio.NewReaderSize(os.Stdin, 16 * 1024 * 1024)
    
        stdout, err := os.Create(os.Getenv("OUTPUT_PATH"))
        checkError(err)
    
        defer stdout.Close()
    
        writer := bufio.NewWriterSize(stdout, 16 * 1024 * 1024)
    
        firstMultipleInput := strings.Split(strings.TrimSpace(readLine(reader)), " ")
    
        nTemp, err := strconv.ParseInt(firstMultipleInput[0], 10, 64)
        checkError(err)
        n := int32(nTemp)
    
        mTemp, err := strconv.ParseInt(firstMultipleInput[1], 10, 64)
        checkError(err)
        m := int32(mTemp)
    
        var edges [][]int32
        for i := 0; i < int(m); i++ {
            edgesRowTemp := strings.Split(strings.TrimRight(readLine(reader)," \t\r\n"), " ")
    
            var edgesRow []int32
            for _, edgesRowItem := range edgesRowTemp {
                edgesItemTemp, err := strconv.ParseInt(edgesRowItem, 10, 64)
                checkError(err)
                edgesItem := int32(edgesItemTemp)
                edgesRow = append(edgesRow, edgesItem)
            }
    
            if len(edgesRow) != 3 {
                panic("Bad input")
            }
    
            edges = append(edges, edgesRow)
        }
    
        secondMultipleInput := strings.Split(strings.TrimSpace(readLine(reader)), " ")
    
        ATemp, err := strconv.ParseInt(secondMultipleInput[0], 10, 64)
        checkError(err)
        A := int32(ATemp)
    
        BTemp, err := strconv.ParseInt(secondMultipleInput[1], 10, 64)
        checkError(err)
        B := int32(BTemp)
    
        result := beautifulPath(n, edges, A, B)
    
        fmt.Fprintf(writer, "%d\n", result)
    
        writer.Flush()
    }
    
    func readLine(reader *bufio.Reader) string {
        str, _, err := reader.ReadLine()
        if err == io.EOF {
            return ""
        }
    
        return strings.TrimRight(string(str), "\r\n")
    }
    
    func checkError(err error) {
        if err != nil {
            panic(err)
        }
    }