이번 주차는 알고리즘 주차였다. 그래서 먼저 알고리즘에 관한 WIL을 작성하고, JS의 ES에 대해 알아보고자 한다.
풀스택때도 내가 당최 뭘한건지 라는 생각이 들었던 터라 사실 알고리즘 주차에 문제들을 잘 풀수 있을지 걱정이 됐었다.
프로그래머스의 알고리즘 풀이를 작성하는 창을 키고 문제를 읽고, 제한사항을 보고, 입출력예를 본 뒤
코드를 작성해야하는데 어떻게 작성해야하는지조차 생각이 나지 않았다.
처음 문제는 직사각형 별 찍기였다. 분명 책으로 혼자 공부할때 for문을 사용하여 작성했었는데,
방법이 전혀 떠오르지않아 처음 문제부터 타인의 답안을 보고 코드를 이해하도록 하였다.
두번째 문제부터 if문을 사용하기 시작했고, 문제해석이 잘되어 생각보다 막히는 문제가 없이 쭉쭉 풀렸던 것 같다.
여러문제들을 for문과 if문을 사용하다보니 뭔가 불안함이 느껴졌다.
내가 for문과 if문으로 어찌저찌 풀고나서 타인의 답을 보면, reduce()라던지, map()이라던지,
다양한 JS의 메소드를 사용해서 푸는 것이었다.
솔직히 자괴감이 들었다.
나는 중첩반복문, 반복문속의 조건문... 등 코드의 길이가 엄청나게 길어지는데,
메소드를 사용해서 한줄, 두줄, 세줄로 간단하게 풀이한 것을 보고 나도 저렇게 될 수 있을까? 라는 생각을 했다.
그렇게 알고리즘 모의고사를 보게되었다.
//2번 문제 (몇시간 했더라?)
function solution(arr1, arr2){
let answer=0; //새벽5시 = 29시
for (let i=0; i<arr1.length; i++) {
if (arr2[i]<29) { //만약 체크아웃 시간이 새벽5시 이전일때
answer += arr2[i]-arr1[i] //체크아웃 시간을 기준으로 공부기록을 남긴다.
}
else { //만약 체크아웃 시간이 새벽5시를 포함한 이상일때
answer += 21-arr1[i] //21시를 체크아웃 시간으로 삼고, 공부기록을 남긴다.
}
}
return answer;
}
let arr1=[9, 9, 9, 9, 7, 9, 8];
let arr2=[23, 23, 30, 28, 30, 23, 23];
console.log(solution(arr1, arr2))
내가 풀었던 문제는 체크인 시간과 체크아웃시간을 입력받고, 사이의 시간을 합해서 반환하는 것 이었다.
Date()메소드를 사용하는 문제는 그때 당시 메소드에 대한 이해가 부족하여 시험문제로는 선택을 하지 않고,
시험을 풀고 와서 공식문서를 찾아보며 풀게 되었다.
//1번 문제 (신대륙 발견)
function solution(month, day){
let result="" //98일 후에 수료 / 달은 1~12 일은 1~31 / 2월은 28일 고정
let year = new Date().getFullYear() //현재 년도 가져오기
let startday = new Date(year, month-1, day) //현재년도, 입력된월 일 startday설정
startday.setDate(startday.getDate()+98) //시작일로부터 98일 후의 날짜로 startday변경
let endmonth = startday.getMonth() +1 //startday에서 월을 가져옴
let enddate = startday.getDate() //startday에서 일을 가져옴
result = `${endmonth}월 ${enddate}일`
return result;
}
console.log(solution(1,18))
마지막 문제는 문자열로 입력된 숫자들을 소수인지 아닌지 판별하고,
소수들 중 최댓값과 소수가 아닌 것들 중 최소값을 반환하는 문제였다.
function issosu(x) { //소수인지 판별해주는 함수
if (x===2) return true; //주어진 값이 2라면 소수이므로 true반환
for(let i=2; i<Math.floor(Math.sqrt(x)); i++) { //i가 2부터 x-1까지 x를 나누며 소수인지 판별
if (x%i===0){ //만약 특정 i값에서 나누어 떨어진다면 소수가 아니다.
return false; //소수가 아니므로 false반환
}
}
return true; //for문을 다 할동안 if문에 해당하지 않는다면 true반환
}
function solution(s){
let answer="";
let arr = s.split(' ')
let sosuarr = arr.filter(x=> issosu(x) === true).map(Number) //소수판별함수를true반환한 값들을 filter하고, Number형식으로 바꿈
let notsosuarr = arr.filter(x=> issosu(x) === false).map(Number) //소수판별함수를false반환한 값들을 filter하고, Number형식으로 바꿈
let minnotsosu = Math.min(...notsosuarr) //소수가 아닌 수들 중 최솟값 지정
let maxsosu = Math.max(...sosuarr) //소수가 맞는 수들 중 최댓값 지정
answer = `${minnotsosu} ${maxsosu}` //순서대로 answer에 넣음
return answer;
}
let s="97 75 88 99 95 92 73";
console.log(solution(s))
위 코드는 다른 분들과 코드리뷰를 하면서 소수판별함수를 고친 것이다.
function issosu(x) { //소수인지 판별해주는 함수
if (x===2) return true; //주어진 값이 2라면 소수이므로 true반환
for(let i=2; i<x; i++) { //i가 2부터 x-1까지 x를 나누며 소수인지 판별
if (x%i===0){ //만약 특정 i값에서 나누어 떨어진다면 소수가 아니다.
return false; //소수가 아니므로 false반환
}
}
return true; //for문을 다 할동안 if문에 해당하지 않는다면 true반환
}
이건 원래 내가 만들었던 소수판별 함수인데, 위에서의 바뀐 함수와 다른점은 판별하는 구간이 절반-1이라는 것이다.
소수에 대한 이해도가 적어 효율성이 떨어지게 작성했던 것 같다.
모의고사가 끝나고 또 문제들을 풀었다. 그 중 하나를 소개하고자 한다.
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
위 링크속 문제 였다.
여태껏 코딩을 배우며 배열에 관한 여러 메소드들을 알게되었었는데,
나는 그 중 splice, includes를 사용하려고 했었다.
function solution(participant, completion) {
var answer = '';
for (let i =0; i<=completion.length; i++) {
if (participant.includes(completion[i])===true) {
participant.splice(participant.indexOf(completion[i]), 1)
}
}
answer = participant.join('')
return answer;
}
문제에서 주어진 테스트들은 통과를 했지만, 효율성테스트에서 모두 실패하였다.
그 이유를 나중에 알게 되었는데, includes, splice는 for문과 비슷하게 모든 요소들을 검사해 보기 떄문이었다.
위의 코드는 for문 안에 if문속 includes를 지났을 때 splice를 사용하기 때문에, 사실상 3중 for문을 돌리는 것과 같은 것이었다.
그래서 효율성이 떨어진다고 했던 것 같다.
그래서 다시 문제를 읽으며 효율적으로 할 수 있는 방법이 없을까 생각을 해보았다.
주어지는 배열 두개는 같은 값들을 가지고 있지만, 단 한가지만 없는 것이기 때문에 sort메소드를 사용하기로 했다.
function solution(participant, completion) {
var answer = '';
participant.sort() //참여자 배열 정렬
completion.sort() //완주자 배열 정렬
//비교를 위해 최대길이인 참여자의 길이로 설정
for (let i=0;i<participant.length; i++) {
//만약 처음으로 값이 같지 않은게 나오면 정렬이 되었으므로
//처음 나온 곳의 participant요소가 완주하지 못한 사람이다.
if (participant[i]!==completion[i]) {
answer = participant[i]
//탈락자를 찾아냈으므로 for문을 마무리하기위해 break를 사용한다.
break
}
}
return answer;
}
이중, 삼중 for문을 돌리는 것들이 사라지고 간단하게 하나의 for문으로 풀었기 때문에 효율성 검사도 무사히 통과하게되었다.
결과적으로 알고리즘 주차때 알게된 것은, 간단한 코드도 좋지만 효율적이고 가독성 좋은 코드가 더 좋다는 것이다.
단순히 메소드만 남발하는 것이아니라, 사용자가 웹에 접속할 때 더빠르게 화면을 그려내고, 타인이 내 코드를 보았을 때 가독성이 좋은 것이 더 좋은 코드라는 것을 알게 되었다.
ES
JavaScript는 10일만에 만들어진 언어이기 때문에 설계미스가 있을 수 밖에 없다.
그래서 지속적으로 업데이트를 하고, 그 것을 나타내는 표준이다.
ES5에서 ES6으로 넘어오며 let 과 const키워드가 추가되었다. 이전에는 var로만 사용했다고 한다.
Arrow function이 추가되었다.
Default Parameter이 추가되었다.
Template literal이 추가되었다.
Multi-ling string이 추가되었다.
클래스가 추가되었다.
모듈이 추가되었다.
디스트럭처링 할당이 추가되었다.
프로미스가 도입되었다.
string매서드(includes, startsWith, endsWith)이 추가되었다.
'1차 공부 > WIL' 카테고리의 다른 글
항해 6주차 미니프로젝트 (0) | 2022.12.26 |
---|---|
항해 5주차 주특기 심화 WIL (0) | 2022.12.18 |
항해 4주차 주특기 숙련 WIL (0) | 2022.12.13 |
항해 3주차 주특기 입문 WIL (0) | 2022.12.05 |
항해 1주차 풀스택프로젝트 WIL (0) | 2022.11.20 |