알고리즘 스터디 2일차 - 문제 풀이(Javascript)

싱클베어·2022년 1월 15일
0

algorithm

목록 보기
2/6
post-custom-banner

아래 3개의 문제에 대해 문제 풀이를 작성하였습니다.

프로그래머스 - 연습문제 - 2016년
프로그래머스 - 연습문제 - 문자열 내 p와 y의 개수
프로그래머스 - 연습문제 - 수박수박수박수박수박수?

1. 2016년 (q13)


문제 설명

2016년 1월 1일은 금요일입니다. 2016년 a월 b일은 무슨 요일일까요? 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, solution을 완성하세요. 요일의 이름은 일요일부터 토요일까지 각각 SUN,MON,TUE,WED,THU,FRI,SAT 입니다. 예를 들어 a=5, b=24라면 5월 24일은 화요일이므로 문자열 "TUE"를 반환하세요.

제한 조건

  • 2016년은 윤년입니다.
  • 2016년 a월 b일은 실제로 있는 날입니다. (13월 26일이나 2월 45일같은 날짜는 주어지지 않습니다)

예시

입력
a=5, b=24

출력
"TUE"


나의 풀이

function solution(a, b) {
    var answer = '';
    // new Date(year, monthIndex, day) 순으로 받는다. (시, 분, 초, 밀리초도 지원)
    // 이 때 month는 monthIndex로 받으므로 1월 = 0, 12월 = 11 임.
    var date = new Date(2016, (a - 1), b);
    console.log(date.toDateString()); // "Tue May 24 2016"
    var answer = date.toDateString().slice(0,3).toUpperCase()
    return answer;
}

바닥부터 날짜를 세서 계산하는것보다는 있는 메서드를 사용하는 편이 나아보였다. 물론 2016년으로 입력값을 한정지었기 때문에 그 방법도 유효하다.

Date() 생성자가 있는 것을 확인했고, 아래와 같이 입력값을 받는다.
new Date(year, monthIndex, day)

연, 월Index, 일로 받아 실제로 입력하는 값보다 1을 빼주어야 우리가 생각하는 월이 입력된다.
예시 데이터가 5,24인데, 월 부분에 -1을 하지 않고 넣으면 6월 24일의 데이터가 나와 원하는 결과인 Tue가 아닌 Fri가 나온다.

Date.toDateString()
en-US 로케일을 기본으로 하여 Date 객체의 날짜 부분을 반환한다. 따라서 요일이 가장 앞에 오게 된다.

var date = new Date(2016, 5-1, 24); // MonthIndex 이므로 입력으로 5월을 받았다면 -1을 빼서 한 칸 땡겨준다.
var date2 = new Date(2016, 5, 24);
console.log(date.toDateString()); // Tue May 24 2016
console.log(date2.toDateString()); // Fri Jun 24 2016

arr.slice([begin[, end]])
문자열을 지정한 begin 부터 end 위치까지 잘라낸 복사본을 리턴한다. 원본 배열을 대체하지 않는다.

console.log(date.toDateString().slice(0,3)) // Tue

str.toUpperCase()
str문자열을 대문자로 변환하여 반환한다.

console.log(date.toDateString().slice(0,3).toUpperCase()) // TUE

다른사람의 풀이

function getDayName(a,b){
  var dayList = ['FRI','SAT','SUN','MON','TUE','WED','THU'];
  var monthArr = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  var daySum;
  if(a < 2) {
    daySum = b - 1;
  } else {
    daySum = monthArr.slice(0, a - 1).reduce((a, b) => a + b) + b - 1;
  }
    return dayList[daySum % 7];
}

분석 필요..

2. 문자열 내 p와 y의 개수 (q16)


문제 설명

대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.
예를 들어 s가 "pPoooyY"면 true를 return하고 "Pyy"라면 false를 return합니다.

제한 조건

  • 문자열 s의 길이 : 50 이하의 자연수
  • 문자열 s는 알파벳으로만 이루어져 있습니다.

예시

입력
예1) "pPoooyY" 'p'의 개수 2개, 'y'의 개수 2개로 같으므로 true 리턴
예2) "Pyy" 'p'의 개수 1개, 'y'의 개수 2개로 다르므로 false 리턴

출력
예1) true
예2) false


나의 풀이

function solution(s){
    var answer = true;
    var p_str_array = [];
    var y_str_array = [];
    // String.match(regexp) : 문자열에 정규식 regexp 가 일치하는 부분 검색
    // /p/gi : 'p'가 일치하고, g 일치하는 하위 문자열을 포함하는 Array 리턴, i는 대/소문자 무시
    p_str_array = s.match(/p/gi);
    y_str_array = s.match(/y/gi);
    var p_str_num = 0;
    var y_str_num = 0;
    
    // 문자열 s 내에 p, y중 아무것도 없는 경우 null 체크하여 비어있지 않을 경우 
    // 문자열 배열의 길이를 저장, 아닌 경우 0 저장
    p_str_num = (p_str_array != null) ? p_str_array.length : 0;
    y_str_num = (y_str_array != null) ? y_str_array.length : 0;
    answer = (p_str_num === y_str_num) ? true : false;

    return answer;
}

str.match(regexp)
문자열이 정규식 regexp와 일치하면 일치하는 전체 문자열을 첫 번째 요소로 포함하는 Array 형태로 반환한다. 일치하는 것이 없으면 null이 반환된다.

match(regexp) 에서 해당 정규식에 사용된 내용을 뜯어보면,

/p/gi

/p/ 'p' 라는 문자열이 포함되어 있는지, condition
g/p/ 표현식을 만족시키는 패턴이 한 개 이상 있는지 확인, flag
i 대소문자를 무시하고 일치 확인, flag

이어서, null 값이 왜 들어왔는지를 체크하지 못해서, 예외 처리에 시간을 좀 많이 소요했다. 제출 시 'p' 문자열이 하나도 없거나, 'y' 문자열이 하나도 없는 경우 p_str_array.length 체크 시 아래와 같은 오류 메시지가 발생한다.

Uncaught TypeError: Cannot read properties of null (reading 'length')

null값에 null.length; 를 한것과 같은 효과이다. 그래서 null 체크하는 구문을 넣고, null이 아니면 배열의 길이를, null이면 0을 리턴하도록 실행하고 그 결과값을 비교했다.

다른 사람의 풀이

function solution(s){
    return s.toUpperCase().split("P").length === s.toUpperCase().split("Y").length;
}

.split()으로 문자열을 분리하면 모두 배열이 생성된다. null 이 리턴하는 경우가 발생하지 않는다. 심지어 주어진 s 값이 '' 와 같이 빈 문자열이어도, .split 을 수행하면 [''] 와 같은 배열이 나오는 것을 확인했다.

console.log(''.split('p')); // ['']
console.log('p'.split('p')); // ['', '']
console.log('p'.split('y')); // ['p']
console.log('pPoooyY'.toUpperCase().split('P').length); // 3, ['', '', 'OOOYY']
console.log('pPoooyY'.toUpperCase().split('Y').length); // 3, ['PPOOO', '', '']
console.log('Pyy'.toUpperCase().split('P').length); // 2, ['', 'YY']
console.log('Pyy'.toUpperCase().split('Y').length); // 3, ['P', '', '']

3. 수박수박수박수박수박수? (q19)


문제 설명

길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다.

제한 조건

n은 길이 10,000이하인 자연수입니다.

예시

입력

  • n : 3
  • n : 4

출력

  • result : "수박수"
  • result : "수박수박"

나의 풀이

function solution(n) {
    var answer = new Array();
    for (let i = 1; i < n+1; i++){
        (i%2 === 0) ? answer.push('박') : answer.push('수') // 홀수는 '수', 짝수는 '박' .push
    }
  	console.log(answer); // n=4, ['수', '박', '수', '박']
    return answer.join(''); // return '수박수박'
}

손에 익지 않았던 Array.push() 를 사용하여 구현해보았다. .push()는 배열의 끝에 값을 추가하므로, 직접 Array의 인덱스로 접근해서 저장하지 않아도 된다.

for 문을 돌며 i%2 값이 0이면 짝수번째 이므로 '박' 을 배열에 넣고, 홀수번째엔 '수'를 배열에 넣게 했다.

마지막에 answer 배열을 하나의 문자열로 합치기 위해 Array.join([separator]) 를 사용했고, 구분자는 '' 를 사용했다.

다른사람의 풀이

function solution(n) {
    const waterMelon = n =>'수박'.repeat(n/2) + (n%2 === 1 ? '수' : '');
    var answer = waterMelon(n);
    return answer;
}

화살표 함수가 아직 눈에 덜 익었다. 아래와 같이 변환해서 보면,

function solution(n) {
    const waterMelon = function(n){
        // (n/2) 가 float 값이 들어가면 integer 값으로 변환
	    var answer_string = '수박'.repeat(n/2) + (n%2 === 1 ? '수' : '');
        return answer_string;
    }
    var answer = waterMelon(n);
    return answer;
}

이것과 동일하다고 할 수 있다. ES6 문법에 속하는 화살표 함수는 함수를 표현하는 것이 더 간단해졌는데, 아래와 같다.

  • function 키워드를 생략할 수 있습니다.
  • 함수의 매개변수가 1개라면 괄호()를 생략할 수 있습니다.
  • 함수 바디가 표현식 하나라면 중괄호와 return 문을 생략할 수 있습니다.

이 내용에 모두 포함된다.


참고 URL

  1. 2016년

    MDN - Date() 생성자
    Date 활용해서 요일 구하기
    문자열 자르기 (substr, substring, slice)

  2. 문자열 내 p와 y의 개수

    MDN - RegExp 정규식표현
    Regex- g flag와 []의 기능, 그 외

  1. 수박수박수박수박수박수?

    MDN - Array.prototype.push()
    배열 하나의 문자열로 만들기 (JOIN 함수)
    ES6 문법 맛보기 - 화살표 함수

profile
안녕하세요.
post-custom-banner

0개의 댓글