241020

Regular Kim·2024년 10월 20일
0

회고

목록 보기
64/70

241020 회고 💬

길고 길었던 번아웃이 끝나고 드디어 공부할 맘이 점점 생겨가고 있다. 이제까지 집에서만 공부하려던 고집을 잠시 내려놓고 스터디카페, 카페 이곳저곳을 나돌아다니며 주변 환경을 바꿔보았다. 결과는 대성공이다. 환경이 변하니 그간의 번아웃이 사라지고 집중력이 아주 좋아졌다. 덕분에 평균 순공시간 7시간을 달성했다. 가끔은 지나가는 사람들 구경하느라 앞에 집중 못 할 적도 있었던 10월 셋째 주를 되돌아본다.

Keep 👍

  • 알고리즘 문제 풀이를 7일 연속으로 이번 주에도 해냈다. 241020 기준으로 연속 372일 풀이 중이다. 이번 주에는 그간 너무 쉬운 문제들만 푼듯 해서 골드 문제에 도전해봤다.
    - 상범 빌딩 3차원 BFS 문제다. BFS 문제 중 유명한 토마토 문제를 풀었다면 쉽게 풀 수 있는 문제이다. 사실 로직 부분이 아니라 인풋 받는 방식을 어떻게 구현할지가 풀이 중에 제일 어려웠던 부분이었다.
    - 유명한 2중 BFS 문제다. 2중이라고 하지만 크게 어렵진 않다. 불이 퍼지는 시뮬레이션을 먼저 하고나서 위치마다 불이 언제 도달하는지 저장한다. 그 후 사람을 시뮬레이션 하면서 해당 위치에 불보다 사람이 먼저 올 수 있는지 확인하면 된다.
  • 요즘은 노드 + 익스프레스 공부를 하고 있다. 최근(이라곤 하지만 번아웃으로 미적지근 했던) 스프링 공부만 했더니 뭔가 다른 웹 기술도 공부해 보고 싶었다. 그래서 프론트 서버도 같이 작업 할겸 시작했다.
    - 기초적인 프로젝트 구성 방법
    - 라우터 구성
    - 로그인(세션)
    - 깃허브 OAuth
    - 템플릿 엔진(Pug)
    - mongoDB & mongoose
  • 객체지향의 사실과 오해를 계속 읽고 있다. 이번 주에는 독서 시간이 길지는 않았다. 반성한다.

Try 🧚

  • 객체지향의 사실과 오해 마무리하기
  • 알고리즘 문제 풀이
  • 프론트 서버 구축
    - webpack
    - scss
    - file
  • 백엔드 서버 개발
    - 인증, 인가
    - mvp 제작

독서 목록

서평 완료 목록

서평 예정 목록 (읽는 중)

  • 함께 자라기 애자일로 가는 길
  • 객체지향의 사실과 오해

독서 예정 목록

목록은 우선순위 큐이다. 상단에 있더라도 더 중요한 책이 들어온다면 순위가 뒤로 밀릴 수 있다.

  • 오브젝트
  • 파이브 라인스 오브 코드
  • HTTP 완벽 가이드
  • 자바/스프링 개발자를 위한 실용주의 프로그래밍
  • 모던 자바 인 액션
  • 자바 성능 튜닝 이야기
  • 자바 개발자와 시스템 운영자를 위한 트러블 슈팅 이야기 / scouter를 활용한 시스템 장애 진단 및 해결 노하우 자바 트러블슈팅
  • 헤드 퍼스트 서블릿
  • Hello Coding 그림으로 개념을 이해하는 알고리즘

Extras 😀

상범 빌딩


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

            Solution s = new Solution();
            System.out.println(s.solution(readInput(br)));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static List<String[][][]> readInput(BufferedReader br) throws IOException {
        List<String[][][]> result = new ArrayList<>();

        int idx = 0;
        while (true) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            int floors = Integer.parseInt(st.nextToken());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());

            if(floors == 0 && x == 0 && y == 0) break;

            result.add(new String[floors][x][y]);
            for (int i = 0; i < floors; i++) {
                for (int j = 0; j < x; j++) {
                    result.get(idx)[i][j] = br.readLine().split("");
                }
                br.readLine();
            }
            idx++;
        }
        return result;
    }
}

class Solution {

    public String solution(List<String[][][]> testCases) {
        StringBuilder answer = new StringBuilder();
        for (String[][][] testCase : testCases) {
            Calculator c = new Calculator(testCase);
            answer.append(c.getResult()).append("\n");
        }
        return answer.toString();
    }
}

class Calculator {

    private static final int[][] DIRECTIONS = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, -1}, {0, 0, 1}};

    private final String[][][] map;
    private final boolean[][][] isVisited;
    private int[] startPoint;
    private int[] endPoint;
    private int time = 0;

    public Calculator(String[][][] map) {
        this.map = map;
        this.isVisited = new boolean[map.length][map[0].length][map[0][0].length];

        int floors = map.length;
        int x = map[0].length;
        int y = map[0][0].length;

        for (int i = 0; i < floors; i++) {
            for (int j = 0; j < x; j++) {
                for (int k = 0; k < y; k++) {
                    if(map[i][j][k].equals("S")) startPoint = new int[]{i, j, k};
                    if(map[i][j][k].equals("E")) endPoint = new int[]{i, j, k};
                    if(startPoint != null && endPoint != null) return;
                }
            }
        }
    }

    public String getResult() {
        simulateEscape();
        if(isFail()) return "Trapped!";
        return "Escaped in " + time + " minute(s).";
    }

    private void simulateEscape() {
        Queue<Location> q = new ArrayDeque<>();
        Location startLocation = new Location(startPoint[0], startPoint[1], startPoint[2], 0);
        q.offer(startLocation);
        visit(startLocation);

        while (!q.isEmpty()) {
            Location cur = q.poll();

            if (cur.isTargetLocation(endPoint)) {
                this.time = cur.getTime();
                return;
            }

            for (int[] direction : DIRECTIONS) {
                int nfloor = cur.getFloor() + direction[0];
                int nx = cur.getX() + direction[1];
                int ny = cur.getY() + direction[2];

                if (isWithinBuilding(nfloor, nx, ny) && isReachable(nfloor, nx, ny) && !isVisited[nfloor][nx][ny]) {
                    Location nextLocation = new Location(nfloor, nx, ny, cur.getTime() + 1);
                    visit(nextLocation);
                    q.offer(nextLocation);
                }
            }
        }
    }

    private void visit(Location location) {
        int floor = location.getFloor();
        int x = location.getX();
        int y = location.getY();
        isVisited[floor][x][y] = true;
    }

    private boolean isFail() {
        return time == 0;
    }

    private boolean isWithinBuilding(int z, int x, int y) {
        return 0 <= z && z < map.length && 0 <= x && x < map[z].length && 0 <= y && y < map[z][x].length;
    }

    private boolean isReachable(int z, int x, int y) {
        return map[z][x][y].equals(".") || map[z][x][y].equals("E");
    }

    private static class Location {

        private final int floor;
        private final int x;
        private final int y;
        private final int time;

        public Location(int floor, int x, int y, int time) {
            this.floor = floor;
            this.x = x;
            this.y = y;
            this.time = time;
        }

        public boolean isTargetLocation(int[] targetPoint) {
            return floor == targetPoint[0] && x == targetPoint[1] && y == targetPoint[2];
        }

        public int getFloor() {
            return floor;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public int getTime() {
            return time;
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

            Solution s = new Solution();
            System.out.println(s.solution(readInput(br)));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static List<char[][]> readInput(BufferedReader br) throws IOException {
        int len = Integer.parseInt(br.readLine());
        List<char[][]> result = new ArrayList<>();

        for (int i = 0; i < len; i++) {
            String[] tokens = br.readLine().split(" ");
            int x = Integer.parseInt(tokens[1]);
            int y = Integer.parseInt(tokens[0]);
            char[][] field = new char[x][y];
            for (int j = 0; j < x; j++) {
                field[j] = br.readLine().toCharArray();
            }
            result.add(field);
        }
        return result;
    }
}

class Solution {

    public String solution(List<char[][]> testCases) {
        StringBuilder answer = new StringBuilder();
        for (char[][] testCase : testCases) {
            EscapeSimulator es = new EscapeSimulator(testCase);
            answer.append(es.getResult()).append("\n");
        }
        return answer.toString();
    }
}

class EscapeSimulator {

    private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

    private final char[][] building;
    private final boolean[][] isVisited;
    private final int[][] fireBoard;

    private final Queue<int[]> humanLocation = new ArrayDeque<>();
    private final Queue<int[]> fireLocation = new ArrayDeque<>();

    private int result = Integer.MAX_VALUE;

    public EscapeSimulator(char[][] building) {
        this.building = building;
        this.isVisited = new boolean[building.length][building[0].length];
        this.fireBoard = new int[building.length][building[0].length];
        for (int[] ints : fireBoard) {
            Arrays.fill(ints, -1);
        }
    }

    public String getResult() {
        simulateEscape(init());
        if(result == Integer.MAX_VALUE) return "IMPOSSIBLE";
        return result + "";
    }

    private int[] init() {
        int x = building.length;
        int y = building[0].length;

        int[] startPosition = new int[3];
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                if (building[i][j] == '@') {
                    isVisited[i][j] = true;
                    startPosition = new int[]{i, j, 0};
                } else if (building[i][j] == '*') {
                    fireBoard[i][j] = 0;
                    fireLocation.add(new int[]{i, j, 0});
                }
            }
        }
        return startPosition;
    }

    private void simulateEscape(int[] startPosition) {
        fireSimulate();
        humanSimulate(startPosition);
    }

    private void fireSimulate() {
        while (!fireLocation.isEmpty()) {
            int[] cur = fireLocation.poll();
            int x = cur[0];
            int y = cur[1];
            int time = cur[2];

            for (int[] direction : DIRECTIONS) {
                int nx = x + direction[0];
                int ny = y + direction[1];
                int ntime = time + 1;
                if (isWithinBuilding(nx, ny) && (building[nx][ny] == '.' || building[nx][ny] == '@') && fireBoard[nx][ny] == -1) {
                    fireBoard[nx][ny] = ntime;
                    fireLocation.offer(new int[]{nx, ny, ntime});
                }
            }
        }
    }

    private void humanSimulate(int[] startPosition) {
        int startX = startPosition[0];
        int startY = startPosition[1];
        humanLocation.offer(startPosition);
        isVisited[startX][startY] = true;

        while (!humanLocation.isEmpty()) {
            int[] cur = humanLocation.poll();
            int x = cur[0];
            int y = cur[1];
            int time = cur[2];

            for (int[] direction : DIRECTIONS) {
                int nx = x + direction[0];
                int ny = y + direction[1];
                int ntime = time + 1;

                if (isOutOfBuilding(nx, ny)) {
                    result = Math.min(result, ntime);
                    return;
                }

                if (isWithinBuilding(nx, ny) && building[nx][ny] == '.' && (fireBoard[nx][ny] > ntime || fireBoard[nx][ny] == -1) && !isVisited[nx][ny]) {
                    isVisited[nx][ny] = true;
                    humanLocation.offer(new int[]{nx, ny, ntime});
                }
            }
        }
    }

    private boolean isOutOfBuilding(int x, int y) {
        return x < 0 || x >= building.length || y < 0 || y >= building[x].length;
    }

    private boolean isWithinBuilding(int x, int y) {
        return 0 <= x && x < building.length && 0 <= y && y < building[x].length;
    }
}

profile
What doesn't kill you, makes you stronger

0개의 댓글