오랜만에 MariaDB root 계정으로 로그인해야하는 일이 생겼는데,, 거의 2년만에 로그인 하는거라 비밀번호를 까먹었다. 나 말고도 많은 사람이 비밀번호를 자주 까먹는 것 같아서 어떻게 초기화 할 수 있는지 공유하고자 이 글을 쓴다. 일단, MariaDB를 종료시켜야 한다.
$ sudo systemctl stop mariadb $ sudo systemctl stop mysql
이후에 mysql을 안전모드로 시작해야 한다. 그 이유는 비밀번호를 사용하지 않고 접속하기 위해서임! (이때 뒤에 & 문자를 붙이는 이유는 프로세스를 백그라운드에서 mysql이 동작하게 하는 리눅스 명령어임. 그냥..ㅋㅋ 은근 모르는 사람 많길래..)
$ sudo mysqld_safe --skip-grant-tables &
실행했으면, root 계정으로 실행시켜주자.
$ mysql -u root
MariaDB가 정상적으로 실행되면 안전모드 진입에 성공했다! 와!(짝짝짝) 이제 계정 초기화를 해 주면 된다.
$ mysql > SET PASSWORD FOR 'root'@'localhost' = PASSWORD('PASSWORD');
만약 다음과 같은 오류가 발생하면, 다음 명령어를 실행해주고, 다시 비밀번호를 설정하면 된다.
The MariaDB server is running with the --skip-grant-tables option so it cannot execute this statement
$ mysql > flush privileges; $ mysql > SET PASSWORD FOR 'root'@'localhost' = PASSWORD('PASSWORD'); $ mysql > flush privileges;
이제 비밀번호 재설정이 완료됐다! 백그라운드에서 실행중인 mysqld_safe를 종료시키고, MariaDB를 재시작 하면 정상적으로 내가 설정한 비밀번호를 통해 로그인 할 수 있다. 간혹, SET PASSWORD ... 질의문으로 비밀번호 변경이 안된다면, 다음 질의를 실행해보라
$ mysql > ALTER USER 'root'@'localhost' IDENTIFIED BY 'PASSWORD';
다음은 사분면을 구분하는 문제인데, 사분면은 우리가 수학적 지식이 있으면 쉽게 알 수 있으니, 바로 정리하겠다.
x가 양수이면 1 또는 4사분면이다. y가 양수이면 1 또는 2사분면이다.
정리가 끝났다! 해당 문제를 풀기 위해 배열을 사용할 것이다. 조건문을 쓰면, 너무 중첩되어야 해서 귀찮다.
배열의 크기는 2며, x를 먼저 판별하여 0번에는 작은 사분면이, 1번에는 큰 사분면을 넣을 것이다. 설명하자면, x > 0일 경우, result[0] = 1, result[1] = 4 이고, x < 0일 경우, result[0] = 2, result[1] = 3이 될 것이다.
이후에, x>0에서 y가 양수라면, 정답은 1일 것이고, y가 음수라면, 정답은 4가 될 것이다.
전체 코드는 다음과 같다.
import java.util.Scanner;
public class Number14981 {
public static void main(String args[]) {
try(Scanner scan = new Scanner(System.in)){
int result[] = {1, 4};
int x = scan.nextInt();
if(x < 0) {
result[0] = 2;
result[1] = 3;
}
int y = scan.nextInt();
System.out.println( (y > 0 ? result[0] : result[1]) );
}
}
}
맥북이 도착하고 난 뒤부터 코딩테스트를 시작하려 했지만, 맥북이 생각보다 늦게와서 (아니 한국에 들어왔는데 왜 배송이 안되냐고..ㅠㅠ) 데스크탑으로 공부를 시작했다!
앞에 문제들은 이미 풀어져 있길래,, 2588번부터 하나하나 단계별 풀어보기를 진행할 예정이다.
오늘은! 그 대망의 첫 번째 문제인 백준 2588 A*B를 풀 것이다.
오늘의 문제
2588번 A*B를 순차적으로 출력하라!
2588번의 문제는 두 정수 A*B를 계산할 때, 계산 과정을 모두 출력하는 것이다.
이 문제를 딱 봤을 때, 정해야 할것 하나와 알아야 할 것이 두 가지가 있는 것을 알 수 있다.
정해야 할것 1. 두 정수 중 어떤 것을 베이스로 할것인가?
알야아 할것 1. 곱해지는 수는 몇자리 수 인가? (365=3자리 수) 2. 곱해지는 수의 각 자리의 값은 무엇인가? (일의 자리, 십의 자리, 백의 자리 ...)
정해야 할 것은 그냥 첫 번째 수를 베이스로 했고, 따라서 두번 째 수는 자연스럽게 곱해지는 수로 정했다.
해당 문제는 수학적 지식만 조금 있다면 바로 구할 수 있다. 나 같은 경우에는 위의 방법이 바로 떠올랐고, 이미 알고있는 방법이기 때문에 바로 문제를 풀 수 있었다. (세 번 실패한건 비밀... 첫 번째는 오타로인한 컴파일 에러.. 두 번째는 클래스 명이 Main이어야 한다는 것을 까먹고 있었고,, 따라서 틀렸다...)
1. 곱해지는 수는 몇자리 수 인가?
우선 곱해지는 수가 몇자리 수인지 알아야 한다. 우리에게 주어지는 곱의 값은 매번 달라질 것이고, 따라서 하드코딩을 통해 값을 매번 지정할 수 없기 때문이다.
예를 들어, 곱해지는 수가 한자리 수일때의 경우, 두자리 수일 때의 경우, 세자리 수일 때의 경우, ... 엄청 큰 자리수일 때의 경우 를 모두 코딩할수는 없잖아!
해당 질문은 log를 통해 쉽게 구할 수 있다. 먼저 자리수에 대해 우리가 표현할 때, 1의 자리는 다음과 같이 표현할 수 있다.
$$ n * 10^0 $$
마찬가지로 10의 자리는 다음과 같이 표현할 수 있다.
$$ n * 10^1 $$
이쯤 되면 내가 무엇을 하고자 하는지 이해 할 수 있다! 즉, 우리는 정수의 자리수를 표현하기 위해 다음과 같이 일반화 할 수 있다.
$$ n * 10^m ( m >= 0, integer ) $$
이 때,n은 우리가 표현하고자 하는 수이고,m은 해당 숫자의 자릿수이다.
우리는지수를 로그로 표현할 수 있는 것을 고등학교 수학에서 배웠다.
로그와 지수의 관계
즉, 자리수를 로그를 통해 표현할 수 있는 것인데, 위의 일반화를 로그로 표현해 보면 다음과 같이 될 수 있다.
$$ m = log_10 n $$
이 때, m은 자리수가 되고, n은 표헌하고자 하는 수 이다! 그런데, log에서는 한가지 주의할 점이 있는데, log 0이 정의되지 않는 점이다.
$$ 10^m = 0 $$ log 0을 지수로 나타내었을 때 위와 같은 식이되고, 해당 식을 만족하는m의 값은 없기 때문이다.
따라서, 우리가 구하고자 하는 자릿수는 최종적으로 다음과 같은 식이 된다.
$$ m = {log_{10} n} + 1$$
2. 곱해지는 수의 각 자리의 값은 무엇인가? (일,십,백, ...의 자리)
이제 해당하는 m 자리의 값이 무엇인지 구하면 된다.
해당 질문은 놀랍게도 몫을 구하는 식으로 쉽게 풀 수 있다. 위에서 우리는 모든 수를 다음과 같이 표현할 수 있다는 걸 이미 인지했다.
$$ n = 10^m $$
우리는 궁극적으로 n이 무엇인지 구해야 한다. 수는 0~9까지 중 하나로 표현할 수 있고, 거기에 자릿수를 곱해주게 되면, n이 무엇인지 알 수 있다.
"그래서 도대체 0~9 중 무엇인지 어떻게 아는데?!"
우리가 어떤 수를 나눌 때, 해당 식은 다음과 같이 표현된다.
$$ N = Qx + R $$
아직도 감이 안오는가?!?!
우리가 구하고자 하는 수 N에 대하여 Q=10(몫의 밑)이고, x(몫의 배수)가 얼마든 간에 R의 범위는 0~9로 한정된다.
이 때 우리는 몫의 배수를 자리수로 해 줄 것이다. 무슨 말이냐면, 다음과 같이 나타낼 수 있다.
$$ 10^m % 10 $$
여기서 문제점은, 우리가 아무리 10 % 10, 100 % 10, 10....0, % 10을 해도 0이 나온다는 점이다. 그 이유는, 우리 본래 수를 아직 구하지 않았기 때문인데, 본래 우리가 찾고자 하는 수는 다음과 같이 구할 수 있다. 예를 들어, 385에 대하여 8을 구하고자 할 때는 다음과 같다.
$$ {385 / 10^1} % 10 = 8.5 $$
이 때, 우리가 사용하는 수는 정수이기 때문에, 8로 구해지는 것을 알 수 있다.
이제 위 두 수식을 근거로 코드를 작성해보자!
문제의 풀이 과정을 출력하기 위한 함수 하나, 그리고 메인함수 하나 하여 총 두 개의 함수를 만들 것이다.
메인 함수는 두 수를 입력받고, 풀이 과정을 출력하는 함수를 호출하며 최종적으로 두 식의 연산 결과를 출력할 것이다.
BufferedReader와 InputStreamReader를 이용하여 입력받을 수 있지만, 간단한 문제이고 메모리, 속도제한 등 아무 것도 없기 때문에 java.util.Scanner를 이용하여 두 수를 입력받을 것이다.
따라서 최종 코드는 다음과 같다.
public class Number2588{
public static void main(String args[]){
try(Scanner scan = new Scanner(System.in)){
int a = scan.nextInt();
int b = scan.nextInt();
printNth(a, b);
System.out.println(a*b);
}
}
public static void printNth(int a, int b){
int length = (int)(Math.log10(b)+1);
for(int i = 0; i < length; i++){
int tempB = b / (int)Math.pow(10, i) % 10; // tempB 없이 바로 출력해도 된다.
System.out.println(a * tempB);
}
}
}
받자마자 제일 처음에만 한번 보고, 이후에 블루투스 키보드만 사용해서 키판에 찍힘이 존재하는지 몰랐다..
그런데 한번 누워서 맥북 써봐야지 하고, 누워서 맥북을 여는데!!! 그 순간 넘버 4 위에 찍힘이 :O 하는 표정으로 날 바라보고 있는게 아닌가 ㅠㅠㅠㅠㅠ
그래서 쓸까 말까 고민하다가, 주변에서 새 기기이고 애플 정책상 14일 안에 묻지마 환불이 가능하다 하니 얼른 새걸로 교환해라!! 라고 조언해주는 바람에 교환신청 했다.
환불 후 재구매를 하지 않은 이유는, 첫번째로 교육할인 스토어는 환불 진행이 완료되더라도, 교육할인스토어 정책상 학년별 대수 구매 수량 제한이 있기 때문에, 제한이 풀릴때 까지 결제가 불가능하다는 안내를 받았고, 체크카드로 결제했기 때문에 환불 후 카드사에서 실제 환불이 되기까지의 딜레이를 감안했을 때 교환 진행했을 때와 별 차이가 없다는 결론이 나왔기 때문이다.
그래서, 6월 27일 애플 교육할인 스토어에 전화해서 교환절차를 신청했고, 7월 마지막주에 신제품을 받을 수 있을거라는 안내를 받았다.
그런데 내가 제품을 수령하는 날짜는 12일~14일로 찍혀있었다!
그런데 실제 애플 홈페이지에서는 내가 제품을 수령하는 날짜가 12일~14일로 찍혀있었다!
애플에서 나로부터 제품을 수거해가는 날짜가 7월 1일이었고, 애플의 제품검수팀이 환불될 제품을 검수하고, 실제 환불이 진행되는 날짜가 12일쯤이라고 안내를 받았는데, 그 즈음하여 내가 제품을 받을 수 있을거라는 안내였다.
처음에 이 문구를 확인했을때는, '그냥 오류겠지'라고 생각했는데, 얼마 지나지 않아서 다음과 같은 이메일을 받았다.
아니, 이쯤되면 오류가 아니라 진짜 12일~14일에 제품을 받아볼 수 있다는 말 아닌가?!
저때가 되어봐야 실제 제품 수령 여부를 확인할 수 있겠지만, 어쨋거나 내가 안내받은 7월 26일~28일보다 대략 2주나 빠른 기간이기 때문에, 나는 다시 한번 설레고 있다. (사실 이 게시글도 맥북으로 작성하고 있지만...)
이번에 느낀건데 맥북 정말 쫀쫀하다. 키보드 타이핑하는 맛이 있다! 단점이라면,, 한영 변환할 때, 0.4초 정도의 딜레이가 있고, 이 사이에 키를 누르면 내가 요청했던 한영환이 씹힌다. 맥OS의 문제인지, 아니면 하드웨어와의 Communication간에 문제가 있는건지(결국에 Operating System에서 사용자의 요청 IO에 대하여 적절히 처리하지 못하는거지만...) 잘 모르겠지만, 이거 빼곤 아직 다 괜찮다!
M1이 나온지 얼마 안됐기 때문에 개발 IDE(인텔리제이, 이클립스)의 반응속도 문제는 뭐.. 참아줄만하다. (일단 맥북이 너무 예쁘고, 키감이 너무 쫀쫀하고, 배터리가 너무 오래간다........ 저장용량은 뭐.. 내가 옵션을 안넣어서 어쩔 수 없는거고..)