알고리즘 코딩 테스트를 공부하기 위해서는 여러가지 사이트가 있지만,
일단 프로그래머스스쿨에서 시작한다.
난이도는 0단계-5단계까지 난이도별,언어별,
각 기업의 기출문제 별로 구분되어 있다.
알고리즘 코딩테스트의 문제들을 처음 봤을 때 너무 다 어려워서 풀 엄두가 안나는 문제들이 많았다.
하지만 프로그래머스0단계는 풀 수 있는 문제들이 어느정도 있었기 때문에,
프로그래머스스쿨에서 먼저 알고리즘을 공부하는 것은 순전히 나의 알고리즘 공부의 흥미가 떨어지지 않게 하기 위해서이다.
차근차근 풀어나가보자!
프로그래머스 입문 0단계부터 풀어가며 앞으로 어려웠던 문제들을 리뷰하며 포스팅 할 예정이다.
프로그래머스 코딩테스트 입문 0단계
정수 num1과 num2가 매개변수로 주어집니다. 두 수가 같으면 1 다르면 -1을 retrun하도록 solution 함수를 완성해주세요.
//내 코드
function solution(num1, num2) {
if(num1===num2){
return 1
}
return -1
}
//다른 사람 코드
const solution = (num1, num2) => num1 === num2 ? 1 : -1
//화살표 함수에, 삼항연산자를 사용하여 만든 코드로,
//내 코드보다 훨씬 간결해보인다. 앞으로 코드를 짤 때 간결한 코드로 쓰도록 노력하자!
//하지만 화살표 함수를 남용하는 것은 좋지 않다!
//이유는 나중에 포스팅하겠다.
두 수를 나눈뒤 1000을 곱하고 정수를 반환하라
//내 코드
function solution(num1, num2) {
return parseInt((num1/num2)*1000);
}//나는 parseInt로 정수를 반횐했다.
//다른 사람 코드
function solution(num1, num2) {
return Math.trunc(num1 / num2 * 1000);
}
//Math함수들을 알고 있었는데, 새로운 메서드를 배웠다!
//Math.trunc()소수 자릿수를 제거하여 숫자의 정수 부분을 반환
분수를 덧셈하고 나온 결과의 분자와 분모를 배열에 넣어 반환하라
//내 코드
function solution(denum1, num1, denum2, num2) {
//num의 최대공배수 구하기 num1*num2
//숫자1의 분자는 denum1*num2
//숫자2의 분자는 denum2*num1
//둘을 더하면 (denum1*num2)+(denum2*num1)
let denum = (denum1*num2)+(denum2*num1);
let num = num1*num2;
//denum과 num둘다 2 또는 3으로 나뉘어지면 나눠진 값을 재할당한다.
//소수로 나눴을 때 나눠지면 소수로 나눈다.
for(i=2; i<1000; i++){
for(j=2; j<1000; j++){
if(i%j===0){
if(denum%j===0 && num%j===0){
denum = denum/j;
num = num/j
}
}
}
}
const arr = [denum, num];
return arr;
//나름 내 코드도 간결하다고 생각했는데, 더 간결한 코드가 있었다.
}
//다른 사람 코드
function fnGCD(a, b){
return (a%b)? fnGCD(b, a%b) : b;
}
function solution(denum1, num1, denum2, num2) {
let denum = denum1*num2 + denum2*num1;
let num = num1 * num2;
let gcd = fnGCD(denum, num); //최대공약수
return [denum/gcd, num/gcd];
}
//최대공약수를 함수로 빼서 삼항연산자를 이용하고 마지막에 최대공약수를 분자와 분모에 나눠주는 코드
//코드가 길어지면 함수로 빼서 간결하게 만들어주자!
배열 안의 요소 숫자들 모두 두배로 만들어 반환하라
//내 코드
function solution(numbers) {
//for 반복문으로 numbers의 요소들을 나열
//나열한 요소들 *2
//새로운 배열 arr에 push
let arr = [];
for(let number of numbers){
arr.push(number*2);
}
return arr;
}
//다른 사람 코드
function solution(numbers) {
return numbers.map(i=>i*2);
//완전 간결한 새롭게 알게된 map()메서드
//map()메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.
}
각도에 따라 1,2,3,4 반환하라
//내 코드
function solution(angle) {
if(0 < angle && angle < 90){
return 1;
}
else if(angle === 90){
return 2;
}
else if(90 < angle && angle < 180){
return 3;
}
else if(angle === 180){
return 4;
}
}
//다른 사람 코드
function solution(angle) {
return [0, 90, 91, 180].filter(x => angle>=x).length;
}
//새롭게 알게된 filter()메서드
//angle이 0보다 크거나 같으면 0이 배열에 담기고 배열의 길이는 1
//angle이 90보다 크거나 같으면 0,90이 배열에 담기고 배열의 길이는 2
//angle이 91보다 크거나 같으면 0,90,91이 배열에 담기고 배열의 길이는 3
//angle이 180보다 크거나 같으면 0,90, 91, 180이 배열에 담기고 배열의 길이는 4
배열의 평균값을 구하여 반환하라
//내 코드
function solution(numbers) {
let sum = 0;
for(let number of numbers){
sum+=number
}
return sum/numbers.length;
}
//다른 사람 코드
function solution(numbers) {
return numbers.reduce((acc, cur) => acc + cur) / numbers.length
}//reduce()메서드는 acc는 누산기역할, cur은 현재계산할숫자를 의미한다.
배열의 중앙값을 구하여 반환하라
//내 코드
function solution(array) {
array.sort(function compare(a, b) {
return a - b;
});
return array[Math.trunc(array.length/2)];
}//sort()메서드를 사용했다. 오름차순으로 배열을 재정리해준다
//다른 사람 코드
function solution(array) {
return array.sort((a, b) => a - b)[Math.floor(array.length / 2)];
}//sort()메서드를 사용했고 return한 곳이 내 코드와는 다르다.
배열 중 가장 많이 등장하는 요소를 반환하고, 최빈값이 2개라면 -1을 반환하라
이 코드는 라매개발자 님의 유튜브 영상의 풀이를 보고 작성한 코드입니다
(왜냐면 여기서 부터는 제가 풀 수 있는 문제가 아니었고 다른 사람들의 풀이를 봐도 어려운 메서드와 함수를 사용하여 제가 아직 이해할 수 있는 수준이 아니었기 때문에
참고하며 다시 나혼자 풀어본 코드를 정리했습니다.)
//내 코드
function solution(array) {
//오름차순으로 정렬
let soltedArray = array.sort((a, b) => a - b);
let cnt = 0; //인덱스 숫자 반복용
let many = -1; //최빈값이 뭔지
let manyRepeatCnt = 0; //최빈값이 될 때 몇번 반복해서 된건지
let repeatCnt = 0; //현재 똑같은 숫자가 몇번 등장했는지
let beforeNumber = -1; //지금 보고 있는 이전 숫자
let equalMany = false; //최빈값이 중복되면 체크할 용
while(cnt<array.length){
if(beforeNumber !== array[cnt]){//이전숫자와 지금 숫자가 다르다 =경계가 넘어갔다
repeatCnt = 1; //그때부터 몇번반복했는지 세는 카운트
}else{ //만약에 이전 숫자와 현재숫자가 같다면 반복했다는 소리
repeatCnt = repeatCnt + 1; // repeatcnt를 1씩 증가시켜준다.
}
if(repeatCnt === manyRepeatCnt){ //현재 돌고있는 숫자의 반복횟수와 최빈값의 반복횟수가 같으면
if(many !== array[cnt]){ //지금 최빈값이랑 원래 최빈값이 다를 때만
equalMany = true; //최빈값이 중복되었다 체크
}
}
if(repeatCnt > manyRepeatCnt){ //현재 돌고있는 숫자의 반복횟수가 최빈값의 반복횟수보다 크면
many = array[cnt]; //최빈값은 지금 돌고 있는 숫자가 된다.
manyRepeatCnt = repeatCnt; // 최빈값의 반복횟수는 현재 돌고있는 숫자의 반복횟수가 된다.
equalMany = false;
//위에서 최빈값이 중복이었다가 아니고 현재값의 반복횟수가 더 큰거니까 중복이 아니라고 체크
}
beforeNumber = array[cnt]; //while문을 한바퀴 돌면 이전 숫자는 현재 숫자가 된다.
cnt = cnt+1; //인덱스는 1추가되서 다음 숫자를 돌게 된다.
}
if(equalMany) return -1;
return many;
}
//1.앞에서부터 차례대로 원소를 확인하며 갯수를 센다.
//2. 최빈값을 그때그때 기록한다.
피자는 7조각, n명이 최소한 피자 1개를 먹어야 될 때, 피자는 몇 판이 필요한지 반환하라
(이 문제는 나도 쉽게 풀었고, 다른사람들의 코드를 보고 한줄로 할 수 있다는 게 놀라웠는데,
나도 Math.ceil()메서드가 뭔지 알았는데 저렇게 생각하지 못했다는 것에 충격을 받아 썼다.)
//내 코드
function solution(n) {
let i = 1;
while(i<15){
if(n>=1 && n<=7){
return 1;
}else if(n>7*i && n<=7*(i+1)){
return i+1;
}
i=i+1;
}
}
//피자조각이 7조각, 피자먹을사람이 n명
//n명이 최소 1조각을 먹으려면 필요한 피자는 몇판인가?
//1-7*1명이면 1판 / 8 ~ 7*2이면 2판 / 15 ~ 7*3이면 3판
//100명이면 7나누면 14하면 98 14판이면 98명이 먹고 최소 15판이 있어야 함
//다른 사람 코드
function solution(n) {
return Math.ceil(n / 7)
} //Math.ceil()메서드는 소수점이나오면 모두 올림하는 메서드이다.
//이렇게만 해도 충분히 결과가 나온다..
어제와 오늘 Day1-4까지의 문제를 풀어보았다.
처음에는 풀 만한 문제들만 나왔는데 나중에는 점점 어려워져서 결국 유튜브의 풀이영상을 참고하였다. 최대한 나 혼자 힘으로 풀어보고 도저히 방법을 모르겠다 싶으면 구글에 검색해서 푸는 방법을 참고해보지만 다른 분들의 코드조차 이해하지 못할 때에는 유튜브 풀이 영상을 참고할 예정이다.
또한 앞으로 하루에 Day문제 8개씩 풀고 8문제 다 풀이하여 포스팅 할 예정이다.
자칫 많은 분들이 어려워 할 수도 있는 내용들인데 알아보기 쉽게 정리해주셔서 감사합니다^^
저도 많이 배우고 가요!