20220718_TIL_알고리즘 2, 3, 4일차 복습

codeing999·2022년 7월 18일
0

TIL/WIL

목록 보기
3/22

8. 내림차순으로 배치하기

function solution(n) {  //정답은 split("")이거로 하나씩 쪼갠다음 문자열인 상태로 sort()로 간단히 바로 정렬해버리네. 그다음 reverse()로 뒤집고
    arr = [];
    var i = 0;
    while (n/10 != 0){
            left = n%10;
            arr[i] = left;
            n = Math.floor(n/10);
        i++;
    }
    var sorted = arr.sort(function(a, b){  //sort함수로 숫자 내림차순 정렬
                           return b-a;
                           });
    var sum = 0;
    for (let n of sorted){  //첨에 var n in sorted 했는데 인덱스가 받아져서 물어봤는데 이렇게 하니까 됨. 첨봄. 근데 for in이나 for of 잘 안쓴다고 잘쓰는거로 배우라고함.
        sum = sum + Number(n); //sum + (+n) 이렇게 해도 n을 숫자로 바꿔준다고함.
        sum = sum*10;
    }
    
    var answer = sum/10;
    return answer;
}

@ 이건 코드에 주석을 이미 달아놨다. 특기할만한 점은 sum + (+n) 이런식으로 해줘도 숫자타입으로 변환이 된다는 거.

13. 3진법 뒤집기

function solution(n) { //3진법 뒤집기
    var temp = n;
    var arr = [];
    while (temp / 3 != 0) {
        arr.push(temp % 3);
        temp = Math.floor(temp / 3);
    }
    arr = arr.reverse();
    for (var i in arr){
        answer= answer + arr[i]*Math.pow(3, i);
    }
    return answer;
}

@ 원래는 아래와 같이 for...of를 썼었다. 근데 인덱스에도 접근해야하는데 i를 변수 따로 선언하고 i++까지 있는게 별로인거 같아서 위와같이 for...in으로 바꿨다.

 var i = 0;
    var answer = 0;
    for (var n of arr) {
        answer = answer + n * Math.pow(3, i);
        i++;
    }

@ 제출한 코드에서는 push를 쓴다음 나중에 reverse를 썼는데, unshift를 쓴다면 처음부터 앞에다 넣을 수 있다는 피드백을 받았다.

15. 같은 숫자는 싫어

function solution(arr)
{
    var answer = [];
    answer = arr.filter((v, i) => v != arr[i+1] ) 
    return answer;
}

@ filter함수를 처음 써봤던 문제이다. 원본함수의 일부만을 추려서 새로운 배열을 만들면 되는 거여서 딱 filter를 써볼 기회라 생각되었다.
@ 다른 사람의 답을 보니 저 식을 그대로 return에 넣었으면 한줄로 돼었겠다.
@ filter같음 함수 쓸 때 안에 매개변수 이름은 value에서 따온 v, index에서 따온 i가 직관적인 것 같다. reduce 쓸 때 누산기는 ac를 쓴다.

16. 두 개 뽑아서 더하기

function solution(numbers) {
    var answer = [];
    
    for (let i=0; i<numbers.length-1; i++){
        for (let j= i+1; j<numbers.length; j++ ){
            (!answer.includes(numbers[i]+numbers[j])? answer.push(numbers[i]+numbers[j]) : {} );
        }  
    }
    console.log(answer)
    return answer.reduce( (ac, v) => (ac.includes(v)? ac : [...ac, v]), []).sort( (a, b) => a-b); //배열에서 중복제거하는 방법 중 recude쓰는 방법.
}

@ https://jsikim1.tistory.com/227
배열에서 중복제거하는 방법은 이 블로그를 참고했다. 총 5가지나 소개되어 있다. indexOf를 써서 이 값이 처음 나온 인덱스가 아니면 제거하거나, set으로 변환해서 중복을 없앤다음 다시 배열로 만드는 등의 방법이 있다. 난 그중에서 reduce 써보고 싶어서 이 방법을 써봤다.
@ reduce 부분에서 처음에 에러가 났었는데 이유는

return answer.reduce((ac, v) => {ac.includes(v)? ac : [...ac, v]}, []).sort

return answer.reduce((ac, v) => {return ac.includes(v)? ac : [...ac, v]}, []).sort

위와 같이 화살표함수 오른쪽을 중괄호로 묶었기 때문이었다. 이게 왜 문제가 되는거냐면. 난 중괄호는 생략해도되고 안해도 되는 거라 생각했는데 중괄호를 생략하는 경우는 오른쪽 전체가 리턴값일 때에만 그런 것이었다. 즉 화살표 함수에서 오른쪽에 괄호가 없다는 것은 return이란 글씨도 같이 생략된 것이다. 즉 생략을 할거면 중괄호와 return 둘 다 생략하고 쓸거면 둘 다 써줘야 한다. 물론 return 외의 다른 구문까지 있을 땐 {}을 생략할 생각을 하면 안된다.

17. 로또의 순위

이 문제는 코드 생략. 이거 풀 때 조건문이 두 번 필요한 경우인데도 3항연산자 억지로 써보려다가 더 복잡해진 경우였다.

18. 모의고사

function solution(answers) {
    let first = [1,2,3,4,5]
    let second = [2,1,2,3,2,4,2,5]
    let third = [3,3,1,1,2,2,4,4,5,5]
    fgrade = answers.reduce((ac, v, i) => v == first[i%5]? ac+1: ac, 0);
    sgrade = answers.reduce((ac, v, i) => v == second[i%8]? ac+1: ac, 0);
    tgrade = answers.reduce((ac, v, i) => v == third[i%10]? ac+1: ac, 0);
    arr = [fgrade, sgrade, tgrade];
    return arr.reduce((ac, v, i) => Math.max(...arr) == v? [...ac, i+1] : ac, []);//세사람 중 최고점인 사람들의 인덱스 리턴.
}

@ 팀원은 나랑 비슷하게 했는데 저 reduce의 ac를 아예 길이 3인 배열로 만들어서 3개를 한꺼번에 처리했었다.

return [fgrade, sgrade, tgrade].reduce((ac, v, i) => Math.max(fgrade, sgrade, tgrade) == v? ac.push(i+1) : ac, []);

@ 처음에 위와 같이 코드 짰다가 오류가 났었는데 좀 당연한 부분을 놓쳤다. push함수는 그 원본의 값을 바꾸는 것이지 바꾼 값을 리턴하는 게 아닌데 push를 써버린 것. 앞으로는 함수들이 원본을 바꾸는지, 값을 리턴하는지 혹은 둘다인지 이런 것들을 잘 생각하고 써야겠다. 결국엔 제출한 코드 처럼 [...ac, i+1] 스프레드를 쓰는 방식으로 해결했다.

19. 문자열 정렬하기

function solution(strings, n) {
    let temp = strings.sort().map(v => v[n]+v ).sort(); //앞에 n번째 문자를 붙이고 정렬
    var answer = temp.map(v =>v.substring(1));          //다시 떼어내고 답 제출.
    return answer;
}

@ 이건 내가 생각해도 좀 신박하게 풀었다. 첫번째 문자가 아닌 주어진 n번째 문자로 정렬하라길래 그 n번째 문자를 맨앞에 잠깐 붙여서 정렬하고 정렬 후에 떼어내는 방식으로 풀었다.
@ 근데 좀 더 sort를 활용하는 방식으로 다시 풀어볼만 할 듯. sort 뒤에 뭐 함수 붙여서 하는 방식.

20. 내림차순으로 배치하기

function solution(s) {
    return s.split('').sort().reverse().join('');
}

@ 이건 문자열 짜르는 거 구글링하다가 이 문제 답을 봐버렸다. 배울 건 split('')로 나누면 한 문자 별로 쪼개진 배열이 리턴된단 점.
@ 그리고 join()으로 인자 없이 합치면 쉼표가 들어가면서 합쳐진다. join('')와 같이 빈문자를 명시해줘야 그대로 합쳐진다.

22. 숫자 문자열과 영단어

function solution(s) {
    let eng = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
    let temp =s;
    for(i = 0; i<eng.length; i++){
        for (j = 0; j<s.length; j++)    //같은 숫자 여러개 있을 수도 있네.
            temp = temp.replace(eng[i], i);
    }
    return Number(temp);
}

@ 이건 문제에서 같은 숫자가 여러번 있을 경우를 떠올리지 못해서 좀 해맨 경우. 모든 테스트케이스를 다 대비해야하는게 코딩의 어려움인 듯

23. 시저 암호

function solution(s, n) {
    let temp = s.split('');
    for (let i = 0; i<temp.length; i++){
        //console.log('Z'>temp[i]>'A')
        if ((temp[i]<='z') && (temp[i]>='a')){
            console.log(temp[i])
            temp[i] = String.fromCharCode(temp[i].charCodeAt(0) + n); //아스키코드값으로 변환시켜서 숫자 더해주고 나서 다시 스트링으로.
            console.log(temp[i])
            if (temp[i] > 'z')
                temp[i] = String.fromCharCode(temp[i].charCodeAt(0) -26);
            console.log(temp[i])
            
        }else if((temp[i]<='Z') && (temp[i]>='A')){
            console.log(temp[i])
            temp[i] = String.fromCharCode(temp[i].charCodeAt(0) + n);
            if (temp[i] > 'Z')
                temp[i] = String.fromCharCode(temp[i].charCodeAt(0) -26);
        }   
    }
    var answer = temp.join('');
    return answer;
}

@ 이건 문자를 아스키코드값으로 바꿔서 더한 후, 다시 그걸 문자로 바꾸는 함수 써본 거. 내가 해봤던 다른 언어에서는 그냥 문자에 숫자 더해도 알아서 잘 더해졌는데 자바스크립트는 좀 어렵게 해야되네.

27. 예산

function solution(d, budget) {
    var temp = d.sort(function (a, b) {
        return a - b;
    });
    var sum = temp[0];
    var i = 1;
    while ((sum <= budget)) { //다 더해도 버젯보다 작을 땐 무한루프 돌거같았는데 왜 안돌지.
        sum += temp[i];
        i++;
    }
    var answer = i - 1;
    console.log(answer)
    return answer;
}

solution([1, 1, 2, 1],5);

@ 이건 다 더해도 예산을 안넘는 경우에 왜 무한루프가 안돌까. 왜 제대로 작동해버리는건가. 궁금했던 건데 질문방에 올렸더니 친절한 답변을 올려주셨다. 결론적으론, i가 temp의 범위 밖이 되서 그게 sum에 더해지는 순간 sum은 그냥 마지막 값에서 값이 안변하는 게 아니고 NaN이 되버린다. while의 조건부분에서 비교에서 하나라도 NaN이 오면 그냥 false로 판단한다고 한다. 하긴 참이 될 수 없으니 false인게 직관적으로도 맞긴 하다.

28. 최대공약수와 최소공배수

function solution(n, m) { //최대공약수는 두개의 약수들을 구하고 공집합을 만들고 그중 젤 큰거로 구하려고 함.
    // 최소공배수는 최대공약수 구한 다음 그걸로 두 수를 나눈 몫을 곱한다?
    var answer = [];
    var narr = [];
    var marr = [];
    var bigger = (n > m ? n : m)
    for (i = 1; i <= bigger; i++) {
        if (n % i == 0) {
            narr.push(i);
        }
        if (m % i == 0) {
            marr.push(i);
        }
    }
    var same = narr.filter(x => marr.includes(x)); //교집합 filter랑 화살표 써봄. 
    console.log(same)
    answer.push(Math.max(...same)); //최소공배수 여기 ...이 스프레드라는 건데 배열을 펼쳐서 일일이 다 인자로 넣어주는 느낌인 듯. 이거 해주니까 잘됨.
    answer.push(answer[0] * (n / answer[0] * (m / answer[0])))
    return answer;
}

@ filter랑 includes를 써서 교집합부분을 구하여 공약수들을 구했다.
@ 최소공배수는 최대공약수x(n/최대공약수)x(m/최대공약수)로 구했다. 근데 곱하고 나누는 거 생략할 수 있었네.

profile
코딩 공부 ing..

0개의 댓글