240908

Regular Kim·2024년 9월 7일
0

회고

목록 보기
58/59

240908 회고 💬

살면서 가장 격렬한 감정 롤러코스터를 탔다. 그간 나와는 상관없다고 했던 부분들이 몇몇 있었다. 최대한 관심을 두지 않고 앞만 보려고 노력했다. 그리고 심리적으로 괜찮은 상태를 유지한다고 착각했다. 그런데 어느 순간 그 부분들이 스쳐 지나가더니, 그 찰나에 지금까지의 보상이라도 받으려는 듯 감정의 소용돌이가 됐다. 감히 바라선 안 되는 것들에도 욕심이 생겼다. 다행히 다시 단념하는 쪽으로 감정을 정리 중이다. 하지만 후유증은 좀 오래갈듯싶다. 나이 먹고 욕심만 많아졌음을 깨달은 1주였다. 불안과 노욕으로 얼룩진 1주를 되돌아본다.

Keep 👍

  • 알고리즘 문제풀이를 7일 연속으로 해냈다. 이번 주에는 골드 문제를 몇개 풀었다. 실버 문제도 쉬운걸로 골라 풀이했다.
    - 빙산 BFS 기본만 알면 쉽게 풀 수 있는 문제다. 중요한 포인트가 하나 있다. 턴마다 빙산이 녹아야하는데 한번에 모든 빙산을 녹여야 한다. 하나씩 녹이면 다음 빙산이 녹는 양에 영향을 줄 수 있기 때문이다. 그래서 처음에는 -1로 두고 계산이 끝나면 0으로 초기화하는 방식을 사용했다. 필드가 크지 않아서 이렇게 했지만 만약 필드가 더 크다면 리스트 녹은 빙산을 관리하는 등 최적화가 필요할지도 모르곘다.
    - 치즈 빙산 문제와 똑같은 문제다. 조건으로 필드의 가장자리는 무조건 비어있음이 보장되기 때문에 외부를 설정하는 로직을 쉽게 만들 수 있다. 여기서도 치즈를 하나씩 녹이지 말고 턴이 끝나면 모두 녹이는 식의 접근이 필요하다.
    - Java vs C++ 쉬어가는 느낌으로 실버 3 문제를 풀이했다. C to java, java to C 변환은 쉽게 할 수 있다. 생각하기 어려웠던 부분은 형식에 맞지 않는 문자열이 들어오는 경우의 수이다. C도 Java도 아닌 형식의 문자열이 들어오면 예외 처리를 해줘야 하는데 이 형식이 꽤 다양해서 모두 고려하기가 한번에는 쉽지 않다.
  • "함께 자라기 애자일로 가는 길"을 계속 읽고 있다.

Problem 🤢

토이 프로젝트에 하나도 진척이 없다. 의욕이 없기 때문이겠지... 빨리 정신 차리자 😴
위의 이런저런 연유로 번아웃마냥 요즘 공부에 손이 안 가서 진도 나가기가 쥐뿔만큼 뿐이다. 반성한다. 지금 중요한 시점에 있는데 본업에 집중하지 못하고 잠깐 한눈판 대가라고 생각하고 반성 중이다.

Try 🧚

  • 함께 자라기 마무리하기
  • 알고리즘 문제 풀이
  • 토이 프로젝트 완성하기
    - 인증 인가 로직 작성 (시큐리티)
    - 통계 로직 완성
    - 더미 데이터 삽입
    - 성능 테스트 진행

독서 목록

서평 완료 목록

서평 예정 목록 (읽는 중)

  • 프로그래머의 길, 멘토에게 묻다
  • 함께 자라기 애자일로 가는 길

독서 예정 목록

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

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

Extras 😀

빙산


import java.io.*;
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(getInput(br)));

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

    private static int[][] getInput(BufferedReader br) throws IOException {
        String[] dimension = br.readLine().split(" ");
        int x = Integer.parseInt(dimension[0]);
        int y = Integer.parseInt(dimension[1]);
        int[][] field = new int[x][y];

        for (int i = 0; i < field.length; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < field[i].length; j++) {
                field[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        return field;
    }
}

class Solution {

    public int solution(int[][] field) {
        Calculator c = new Calculator(field);
        return c.calculateYearsUntilSplit();
    }
}

class Calculator {

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

    private final int[][] field;
    private final Queue<int[]> q;
    private int yearsToSplit;
    private boolean isSplited;

    public Calculator(int[][] field) {
        this.field = field;
        this.q = new ArrayDeque<>();
        this.yearsToSplit = 0;
        this.isSplited = false;
    }

    public int calculateYearsUntilSplit() {
        initQueue();
        while (!q.isEmpty()) {
            if (isGlacierSplit()) {
                return yearsToSplit;
            }
            meltGlacier();
            yearsToSplit++;
        }
        return 0;
    }

    private void meltGlacier() {
        int len = q.size();
        for (int i = 0; i < len; i++) {
            int[] cur = q.poll();
            int glacierHeight = field[cur[0]][cur[1]];
            int meltAmount = getMeltAmount(cur);
            field[cur[0]][cur[1]] = glacierHeight - meltAmount;
            if (glacierHeight - meltAmount > 0) {
                q.offer(cur);
            } else {
                field[cur[0]][cur[1]] = -1;
            }
        }
        postProcess();
    }

    private void initQueue() {
        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
                if (field[i][j] == 0) continue;
                q.offer(new int[]{i, j});
            }
        }
    }

    private void postProcess() {
        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
                if (field[i][j] < 0) {
                    field[i][j] = 0;
                }
            }
        }
    }

    private int getMeltAmount(int[] cur) {
        int minus = 0;
        for (int[] direction : directions) {
            int nx = cur[0] + direction[0];
            int ny = cur[1] + direction[1];

            if (isWithinField(nx, ny) && field[nx][ny] == 0) {
                minus++;
            }
        }
        return minus;
    }

    private boolean isGlacierSplit() {
        int numOfGlacier = 0;
        boolean[][] isChecked = new boolean[field.length][field[0].length];
        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
                if (numOfGlacier > 1){
                    isSplited = true;
                    return isSplited;
                }
                if (field[i][j] != 0 && !isChecked[i][j]) {
                    numOfGlacier++;
                    explore(i, j, isChecked);
                }
            }
        }
        return false;
    }

    private void explore(int x, int y, boolean[][] isChecked) {
        Queue<int[]> exploreQ = new ArrayDeque<>();
        isChecked[x][y] = true;
        exploreQ.offer(new int[]{x, y});

        while (!exploreQ.isEmpty()) {
            int[] cur = exploreQ.poll();

            for (int[] direction : directions) {
                int nx = cur[0] + direction[0];
                int ny = cur[1] + direction[1];

                if (isWithinField(nx, ny) && !isChecked[nx][ny] && field[nx][ny] > 0) {
                    isChecked[nx][ny] = true;
                    exploreQ.offer(new int[]{nx, ny});
                }
            }
        }
    }

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

치즈


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;

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(getInput(br)));

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

    private static int[][] getInput(BufferedReader br) throws IOException {
        String[] dimension = br.readLine().split(" ");
        int x = Integer.parseInt(dimension[0]);
        int y = Integer.parseInt(dimension[1]);

        int[][] field = new int[x][y];

        for (int i = 0; i < field.length; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < field[i].length; j++) {
                field[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        return field;
    }
}


class Solution {

    public int solution(int[][] field) {
        Calculator c = new Calculator(field);
        return c.getResult();
    }
}

class Calculator {

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

    private final int[][] field;
    private boolean[][] outSide;
    private final Queue<int[]> q;
    private int result;

    public Calculator(int[][] field) {
        this.field = field;
        this.outSide = new boolean[field.length][field[0].length];
        this.q = new ArrayDeque<>();
        this.result = 0;
    }

    public int getResult() {
        init();
        while (!q.isEmpty()) {
            checkOutSide();
            meltCheese();
            postProcess();
            result++;
        }
        return result;
    }

    private void init() {
        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
                if(field[i][j] == 1) q.offer(new int[]{i, j});
            }
        }
    }


    private void checkOutSide() {
        outSide = new boolean[field.length][field[0].length];
        outSide[0][0] = true;
        Queue<int[]> outSideQ = new ArrayDeque<>();
        outSideQ.offer(new int[]{0, 0});

        while (!outSideQ.isEmpty()) {
            int[] cur = outSideQ.poll();

            for (int[] direction : DIRECTIONS) {
                int nx = cur[0] + direction[0];
                int ny = cur[1] + direction[1];

                if (isWithinField(nx, ny) && field[nx][ny] == 0 && !outSide[nx][ny]) {
                    outSide[nx][ny] = true;
                    outSideQ.offer(new int[]{nx, ny});
                }
            }
        }
    }

    private void meltCheese() {
        int len = q.size();
        for (int i = 0; i < len; i++) {
            int[] cur = q.poll();

            int heat = 0;
            for (int[] direction : DIRECTIONS) {
                int nx = cur[0] + direction[0];
                int ny = cur[1] + direction[1];

                if (isWithinField(nx, ny) && outSide[nx][ny]) {
                    heat++;
                }
            }
            if(heat > 1) field[cur[0]][cur[1]] = -1;
            else q.offer(cur);
        }
    }

    private void postProcess() {
        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
                if(field[i][j] == -1) field[i][j] = 0;
            }
        }
    }

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

Java vs C++


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

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(getInput(br)));

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

    private static String getInput(BufferedReader br) throws IOException {
        return br.readLine();
    }
}

class Solution {

    public String solution(String target) {
        if(isInvalidTarget(target)) return "Error!";
        return convert(target);
    }

    private String convert(String target) {
        if(hasUnderbar(target)) return cToJava(target);
        return javaToC(target);
    }

    private String cToJava(String target) {
        StringTokenizer st = new StringTokenizer(target, "_");
        StringBuilder result = new StringBuilder();
        result.append(st.nextToken());
        while (st.hasMoreTokens()) {
            char[] word = st.nextToken().toCharArray();
            word[0] -= 32;
            result.append(word);
        }
        return result.toString();
    }

    private String javaToC(String target) {
        StringBuilder result = new StringBuilder();
        for (char c : target.toCharArray()) {
            if ('A' <= c && c <= 'Z') {
                result.append("_").append((char) (c + 32));
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }

    private boolean isInvalidTarget(String target) {
        if(target.endsWith("_")) return true;
        if(target.startsWith("_")) return true;
        if(target.contains("__")) return true;
        if(hasBigAtFront(target)) return true;
        if(hasBigAndUnderbar(target)) return true;
        return false;
    }

    private boolean hasBigAtFront(String target) {
        char front = target.charAt(0);
        return 'A' <= front && front <= 'Z';
    }

    private boolean hasBigAndUnderbar(String target) {
        return hasBig(target) && hasUnderbar(target);
    }

    private boolean hasBig(String target) {
        for (char c : target.toCharArray()) {
            if('A' <= c && c <= 'Z') return true;
        }
        return false;
    }

    private boolean hasUnderbar(String target) {
        return target.contains("_");
    }
}
profile
What doesn't kill you, makes you stronger

0개의 댓글