Sort by

recency

|

181 Discussions

|

  • + 0 comments

    Java using BFS

    class Result {
      
      public static String countLuck(List<String> matrix, int k) {
            int rows = matrix.size();
            int cols = matrix.get(0).length();
            char[][] matrixArr = new char[rows][cols];
            int startX = -1;
            int startY = -1;
    
            // Parse the input matrix into a 2D char array and locate the starting position 'M'
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    matrixArr[i][j] = matrix.get(i).charAt(j);
                    if (matrixArr[i][j] == 'M') {
                        startX = i;
                        startY = j;
                    }
                }
            }
    
            // Count the "waves" (decision points) to determine the path
            int waves = getWaves(matrixArr, startX, startY);
    
            // Return "Impressed" if the waves match k, otherwise "Oops!"
            return waves == k ? "Impressed" : "Oops!";
        }
    
        private static int getWaves(char[][] matrixArr, int startX, int startY) {
            int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
            Queue<int[]> cells = new LinkedList<>();
            boolean[][] visited = new boolean[matrixArr.length][matrixArr[0].length];
            cells.offer(new int[]{startX, startY, 0}); // Starting position and wave count
    
            while (!cells.isEmpty()) {
                int[] curCellPos = cells.poll();
                int curX = curCellPos[0];
                int curY = curCellPos[1];
                int waveCount = curCellPos[2];
    
                // If the current cell is the destination '*', return the wave count
                if (matrixArr[curX][curY] == '*') {
                    return waveCount;
                }
    
                // Mark the current cell as visited
                visited[curX][curY] = true;
    
                // Check if the current cell is a decision point and increase wave count if true
                if (isDecisionPoint(matrixArr, visited, curX, curY)) {
                    waveCount++;
                }
    
                // Add valid neighboring cells to the queue
                for (int[] dir : directions) {
                    int newX = curX + dir[0];
                    int newY = curY + dir[1];
                    if (isValid(matrixArr, newX, newY) &&
                            (matrixArr[newX][newY] == '.' || matrixArr[newX][newY] == '*') &&
                            !visited[newX][newY]) {
                        cells.offer(new int[]{newX, newY, waveCount});
                    }
                }
            }
    
            // Return 0 if the destination is unreachable (edge case)
            return 0;
        }
    
        private static boolean isDecisionPoint(char[][] matrixArr, boolean[][] visited, int x, int y) {
            int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
            int paths = 0;
    
            // Check all four directions for valid and unvisited paths
            for (int[] dir : directions) {
                int newX = x + dir[0];
                int newY = y + dir[1];
                if (isValid(matrixArr, newX, newY) &&
                        (matrixArr[newX][newY] == '.' || matrixArr[newX][newY] == '*') &&
                        !visited[newX][newY]) {
                    paths++;
                }
            }
    
            // A decision point occurs when there is more than one valid path
            return paths > 1;
        }
    
        private static boolean isValid(char[][] matrixArr, int x, int y) {
            int rows = matrixArr.length;
            int cols = matrixArr[0].length;
    
            // Check if the coordinates are within bounds
            return x >= 0 && x < rows && y >= 0 && y < cols;
        }
    }
    
  • + 0 comments
    <?php
    
    function findStartingPoint($matrix) {
        foreach ($matrix as $i => $row) {
            $col = strpos($row, 'M');
            if ($col !== false) {
                return [$i, $col];
            }
        }
        return [-1, -1];
    }
    
    function isWithinBounds($x, $y, $n, $m) {
        return $x >= 0 && $x < $n && $y >= 0 && $y < $m;
    }
    
    function countLuck($matrix, $k) {
        list($n, $m) = [count($matrix), strlen($matrix[0])];
        list($startX, $startY) = findStartingPoint($matrix);
        $dx = [-1, 1, 0, 0];
        $dy = [0, 0, -1, 1];
        $queue = [[$startX, $startY, 0]];
        $visited = array_fill(0, $n, array_fill(0, $m, false));
        $visited[$startX][$startY] = true;
    
        while (!empty($queue)) {
            list($x, $y, $waveCount) = array_shift($queue);
    
            if ($matrix[$x][$y] === '*') {
                return $waveCount === $k ? "Impressed" : "Oops!";
            }
    
            $possibleMoves = 0;
            foreach (range(0, 3) as $i) {
                $nx = $x + $dx[$i];
                $ny = $y + $dy[$i];
                if (isWithinBounds($nx, $ny, $n, $m) && !$visited[$nx][$ny] && $matrix[$nx][$ny] !== 'X') {
                    $possibleMoves++;
                }
            }
    
            foreach (range(0, 3) as $i) {
                $nx = $x + $dx[$i];
                $ny = $y + $dy[$i];
                if (isWithinBounds($nx, $ny, $n, $m) && !$visited[$nx][$ny] && $matrix[$nx][$ny] !== 'X') {
                    $visited[$nx][$ny] = true;
                    $queue[] = [$nx, $ny, $waveCount + ($possibleMoves > 1 ? 1 : 0)];
                }
            }
        }
    
        return "Oops!";
    }
    
    // Input reading
    $handle = fopen("php://stdin", "r");
    $testCases = intval(fgets($handle));
    for ($t = 0; $t < $testCases; $t++) {
        list($n, $m) = array_map('intval', explode(' ', fgets($handle)));
        $matrix = [];
        for ($i = 0; $i < $n; $i++) {
            $matrix[] = trim(fgets($handle));
        }
        $k = intval(fgets($handle));
        echo countLuck($matrix, $k) . "\n";
    }
    fclose($handle);
    
    ?>
    

    Explanation:

    1. Find Starting Point:

      • The function findStartingPoint scans the matrix to find the position of 'M' (start).
    2. Within Bounds Check:

      • The function isWithinBounds ensures the coordinates are within the grid.
    3. Breadth-First Search (BFS):

      • We use BFS to explore all possible paths.
      • Maintain a queue for BFS, starting from the 'M' position.
      • Keep track of visited positions to avoid revisiting them.
      • Count the number of decisions (wave counts) Hermione has to make using possibleMoves.
    4. Decision Points:

      • At each cell, determine the number of valid moves (cells that can be visited next).
      • If there is more than one valid move, increase the wave count.
    5. Result:

      • If the final wave count matches k, print "Impressed"; otherwise, print "Oops!".

    This code reads input directly from stdin, which is typical for competitive programming environments like HackerRank. Make sure to test this solution within the constraints of the problem to ensure it works correctly.

  • + 0 comments
    def search(g, m, n, i, j, c = 0):
        if g[i][j] == '*':
            return c
        g[i][j] = 0
        moves = getmoves(g, m, n, i, j)
        if len(moves) > 1:
            c += 1
        for mv in moves:
            res = search(g, m, n, mv[0], mv[1], c)
            if res != None:
                return res
        return None
    
    def getmoves(g, m, n, i, j):
        l, v = [], ('.', '*')
        if i > 0 and g[i - 1][j] in v:
            l.append((i - 1, j))
        if j > 0 and g[i][j - 1] in v:
            l.append((i, j - 1))
        if i < m - 1 and g[i + 1][j] in v:
            l.append((i + 1, j))
        if j < n - 1 and g[i][j + 1] in v:
            l.append((i, j + 1))
        return l
    
    for _ in range(int(input())):
        m, n = map(int, input().split())
        g = [list(input()) for _ in range(m)]
        k = int(input())
        for i in range(m):
            for j in range(n):
                if g[i][j] == 'M':
                    print('Impressed' if search(g, m, n, i, j) == k else 'Oops!')
                    break
    
  • + 0 comments

    Ruby

    def findPosition(matrix, token)
        matrix.length.times do |i|
            matrix[0].length.times do |j|
                return [i,j] if matrix[i][j] == token
            end
        end 
    end
    
    def countLuck(matrix, k)
        m,n = findPosition(matrix, 'M')
        p,q = findPosition(matrix, '*')
        queue = [[m,n]]
        visited = [[m,n]]
        father = Hash.new(-1)
        number_of_sons = Hash.new(-1)
        while not queue.empty?
            i,j = queue.shift
            break if matrix[i][j] == '*'
            valid_states = [ [i,j+1], [i,j-1], [i+1,j], [i-1,j]]
            valid_states = valid_states.select{ |i,j| i>=0 and i < matrix.length and j >=0 and j < matrix[0].length }
            valid_states = valid_states.select{ |i,j| matrix[i][j] != 'X' and not visited.include?([i,j])}
            valid_states.each { |k| father[k] = [i,j]}
            number_of_sons[[i,j]] = valid_states.length        
            queue += valid_states        
            visited += valid_states
        end
        counter = 0
        current_father = father[[p,q]]
        while current_father != -1 
            counter += 1 if number_of_sons[current_father] > 1
            current_father = father[current_father]
        end
        (counter == k) ? "Impressed" : "Oops!"
    end
    
  • + 0 comments

    C++ (more at https://github.com/IhorVodko/Hackerrank_solutions , feel free to give a star :) )

    namespace Forest{  
    
    using location_t = std::pair<size_t, size_t>;
    using locations_t = std::vector<location_t>;
    using path_t = locations_t;
    using paths_t = std::vector<path_t>;
    
    static constexpr char START = 'M'; 
    static constexpr char DESTINATION = '*'; 
    static constexpr char BLOCKED = 'X';
    static constexpr std::array<std::pair<int, int>, 4> directions = {
        std::make_pair(-1, 0), std::make_pair(0, 1),
        std::make_pair(1, 0), std::make_pair(0, -1)};
    
    location_t findLocation(
        std::vector<std::string>  const &,
        char const &
    );
    
    paths_t collectPathes(
        std::vector<std::string> &,
        location_t const &
    );
    
    size_t countHints(
        paths_t const & _pathes, 
        location_t const & _start
    );
    
    std::string countLuck(
        std::vector<std::string> & _forest,
        int const & _hints
    ){
        auto const start = findLocation(_forest, START);
        auto pathes = collectPathes(_forest, start);
        auto hintsUsed = countHints(pathes, start);
        std::cout << _hints << " " << hintsUsed << '\n';
        return _hints == static_cast<int>(hintsUsed) ? "Impressed" : "Oops!";
    }
    
    inline location_t findLocation(
        std::vector<std::string>  const & _forest,
        char const & _value
    ){
        auto const & szRows = _forest.size();
        auto const & szCols = _forest.front().size();
        auto destination = std::make_pair(std::numeric_limits<size_t>::max(),
            std::numeric_limits<size_t>::max());
        for(size_t r = 0; r < szRows; ++r){
            for(size_t c = 0; c < szCols; ++c){
                if(_forest.at(r).at(c) != _value){
                    continue;;
                }
                return {r, c};
            }
        }
        return destination; 
    }
    
    paths_t collectPathes(
        std::vector<std::string> & _forest,
        location_t const & _start
    ){
        auto const destination = findLocation(_forest, DESTINATION);
        _forest.at(_start.first).at(_start.second) = BLOCKED;
        auto nextLocationOptions = locations_t();
        nextLocationOptions.reserve(directions.size());
        size_t rowNext = std::numeric_limits<size_t>::max();
        size_t colNext = rowNext;
        auto pathes = paths_t();
        pathes.emplace_back(path_t({_start}));
        auto const & szRows = _forest.size();
        auto arrived = false;
        auto const & szCols = _forest.front().size();
        for(size_t pathIndx = 0, locationIndx = 0; pathIndx < pathes.size()
            && !arrived;
        ){
            auto & path = pathes.at(pathIndx);
            auto & location = path.at(locationIndx);
            for(auto const & direction : directions){
                rowNext = location.first + direction.first;
                colNext = location.second + direction.second;
                if( rowNext < 0 || szRows <= rowNext ||
                    colNext < 0 || szCols <= colNext ||
                    _forest.at(rowNext).at(colNext) == BLOCKED
                ){
                    continue;
                }
                _forest.at(rowNext).at(colNext) = BLOCKED;
                nextLocationOptions.emplace_back(rowNext, colNext);
            }
            if(nextLocationOptions.size() == 1){
                path.emplace_back(nextLocationOptions.back());
                ++locationIndx;
                if(nextLocationOptions.back() == destination){
                    arrived = true;
                }
                nextLocationOptions.clear();
                continue;
            }
            for(auto const & nextLocationOption: nextLocationOptions){
                pathes.emplace_back(path_t({location}));
                pathes.back().emplace_back(nextLocationOption);
                if(nextLocationOption == destination){
                    arrived = true;
                }
            }
            ++pathIndx;
            locationIndx = 1;
            nextLocationOptions.clear();
        }
        return pathes;
    }
    
    inline size_t countHints(
        paths_t const & _pathes, 
        location_t const & _start
    ){
        size_t hintsUsed = 0;
        for(auto path = std::rbegin(_pathes), pathPrev = path + 1;
            pathPrev != rend(_pathes);
            path = pathPrev,  pathPrev = path + 1
        ){
            ++hintsUsed;
            if(path->front() == _start){
                break;
            }
            while(path->front() != pathPrev->back()){
                ++pathPrev;
            }
        }
        return hintsUsed;
    }
    
    } // namespace Forest