Sort by

recency

|

182 Discussions

|

  • + 0 comments

    By using a map of valid locations, you can avoid bounds checking.

    import java.io.*;
    import java.math.*;
    import java.security.*;
    import java.text.*;
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.function.*;
    import java.util.regex.*;
    import java.util.stream.*;
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toList;
    
    
    class Node {
        int x;
        int y;
        int choices;
        public Node(int x, int y, int c) {
            this.x = x;
            this.y = y;
            this.choices = c;
        }
        
        @Override
        public boolean equals(Object o) {
            Node n = (Node) o;
            return (n.x == x && n.y == y && n.choices == choices);
        }
        @Override
        public int hashCode() {
            return x * 129 + y * 47 + choices;
        }
    }
    
    
    class Result {
    
        /*
         * Complete the 'countLuck' function below.
         *
         * The function is expected to return a STRING.
         * The function accepts following parameters:
         *  1. STRING_ARRAY matrix
         *  2. INTEGER k
         */
    
        public static String getk(int x, int y) {
            return x + " " + y;
        }
        
    
        public static String countLuck(List<String> matrix, int k) {
        // Write your code here
        // BFS, count choices.
            int[] dx = {-1, 0, 0, 1};
            int[] dy = {0, 1, -1, 0};
            Queue<Node> todo = new LinkedList<>();
            int x = 0;
            int y = 0;
            int n = matrix.size();
            int m = matrix.get(0).length();
            Set<String> dots = new HashSet<>();
            int goalx = 0;
            int goaly = 0;
            for (int j = 0; j < n; j++) {
                String s = matrix.get(j);
                for (int i = 0; i < m; i++) {
                    char c = s.charAt(i);
                    if (c == 'M') {
                        x = i;
                        y = j;
                    }
                    if (c == '.' || c == '*') {
                        dots.add(getk(i, j));
                    }
                    if (c == '*') {
                        goalx = i;
                        goaly = j;
                    }
                }
            }
            Set<String> seen = new HashSet<>();
            todo.add(new Node(x, y, 0));
            System.err.println("dots:" + dots);
            while (true) {
                Node here = todo.remove();
                seen.add(getk(here.x, here.y));
                // count paths.
                x = here.x;
                y = here.y;
                if (x == goalx && y == goaly) {
                    if (here.choices == k) {
                        return "Impressed";
                    };
                    return "Oops!";
                }
                int count = 0;
                List<Node> addme = new ArrayList<>();
                for (int q = 0; q < 4; q++) {
                    int nx = x + dx[q];
                    int ny = y + dy[q];
                    String key = getk(nx, ny);
                    if (! seen.contains(key) && dots.contains(key)) {
                        count++;
                        addme.add(new Node(nx, ny, 0));
                    }
                }
                int bump = (count > 1)? 1 : 0;
                here.choices += bump;
                for (Node node : addme) {
                    node.choices = here.choices;
                }
                todo.addAll(addme);
            }
        }
    }
    
    public class Solution {
        public static void main(String[] args) throws IOException {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
    
            int t = Integer.parseInt(bufferedReader.readLine().trim());
    
            IntStream.range(0, t).forEach(tItr -> {
                try {
                    String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
                    int n = Integer.parseInt(firstMultipleInput[0]);
    
                    int m = Integer.parseInt(firstMultipleInput[1]);
    
                    List<String> matrix = IntStream.range(0, n).mapToObj(i -> {
                        try {
                            return bufferedReader.readLine();
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                    })
                        .collect(toList());
    
                    int k = Integer.parseInt(bufferedReader.readLine().trim());
    
                    String result = Result.countLuck(matrix, k);
    
                    bufferedWriter.write(result);
                    bufferedWriter.newLine();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });
    
            bufferedReader.close();
            bufferedWriter.close();
        }
    }
    
  • + 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