살면서 가장 격렬한 감정 롤러코스터를 탔다. 그간 나와는 상관없다고 했던 부분들이 몇몇 있었다. 최대한 관심을 두지 않고 앞만 보려고 노력했다. 그리고 심리적으로 괜찮은 상태를 유지한다고 착각했다. 그런데 어느 순간 그 부분들이 스쳐 지나가더니, 그 찰나에 지금까지의 보상이라도 받으려는 듯 감정의 소용돌이가 됐다. 감히 바라선 안 되는 것들에도 욕심이 생겼다. 다행히 다시 단념하는 쪽으로 감정을 정리 중이다. 하지만 후유증은 좀 오래갈듯싶다. 나이 먹고 욕심만 많아졌음을 깨달은 1주였다. 불안과 노욕으로 얼룩진 1주를 되돌아본다.
토이 프로젝트에 하나도 진척이 없다. 의욕이 없기 때문이겠지... 빨리 정신 차리자 😴
위의 이런저런 연유로 번아웃마냥 요즘 공부에 손이 안 가서 진도 나가기가 쥐뿔만큼 뿐이다. 반성한다. 지금 중요한 시점에 있는데 본업에 집중하지 못하고 잠깐 한눈판 대가라고 생각하고 반성 중이다.
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;
}
}
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("_");
}
}