문제 : 정수 n을 입력받아 n의 약수를 모두 더한 값을 리턴하는 함수, solution을 완성해주세요.

https://school.programmers.co.kr/learn/courses/30/lessons/12928

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


코드 1

function solution(n){
    let a = [];
    for(let i = 1; i <= n; i++){
        if (n % i === 0) a.push(i);  // i가 n의 약수라면 배열에 추가
    }
    return a.reduce((acc, num) => acc + num, 0);
}
  • 먼저 빈 배열 a를 만든다.
  • 1부터 n까지 숫자를 순회하면서 삼항연산자를 사용하여 n % i === 0 이면 약수이므로 배열에 넣고, 아니면 push()로 추가해준다.
  • 배열에 모든 약수가 모이면 reduce()를 사용해 약수들의 총 합을 구한다.

굳이 배열을 쓴거같아서 바로 누적하는 코드로 짜보았다.

코드 2

function solution(n){
    let sum = 0;
    for(let i = 1; i <= n; i++){
        if (n % i === 0) sum += i; // 약수면 바로 누적
    }
    return sum;
}

 

  • 값을 누적시킬 sum을 0으로 초기화한다.
  • 1부터 n까지 순회하면서 약수라면 sum에 바로 더해준다. 

문제 : 정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.

https://school.programmers.co.kr/learn/courses/30/lessons/12944

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


코드 1

function solution(arr){
    let sum = arr.reduce((acc, num) => {
        return acc + num;
    }, 0);
    return sum / arr.length;
}
  • reduce 를 사용해 배열의 모든 요소를 더해 sum 값을 만들었다.
  • 그 후, sum 배열의 길이로 나누어 평균을 반환하였다. 

코드 2 (흥미로웠던 코드)

function average(array){
  return array.reduce((a,b) => a+b) / array.length;
}
  • 나의 코드보다 더 간결하게 짜서 흥미로웠다.

< 궁금했던  점 (코드 2) >

"reduce에 초기값을 안주면 기본으로 초기값이 0인가?" 라는 의문이 들었다.

 

📝 reduce의 초기값 정리

    초기값을 주지 않았을 경우.

  • 배열이 비어있지 않다면 acc(누적값)는 자동으로 배열의 첫 번째 요소가 된다.
  • 그 다음 요소부터 reduce가 시작된다.

    예) [2, 3, 4,]

    초기값 없음 -> acc = 2, num = 3 부터 시작

 

이때 num이 두번째 요소가 되는 이유는?

reduce는 기본적으로 두 값을 합쳐 하나로 만들어 가는 함수인 초기값이 없을 경우 첫번째 요소를 초기값처럼 사용하고 두번째 요소부터 연산을 시작하는 구조이다. 

 

-> 그래서 위 풀이처럼 초기값을 생략해도 문제없이 잘 동작한다. 

 

하지만 배열이 비어있으면?

- 초기값이 없으면 에러 발생

- 초기값이 있으면 정상 동작

 

그래서 안전하게 코드를 작성하고 싶다면 웬만하면 초기값을 넣어주는 걸 추천한다. 


< 이번 문제를 통해 배운 점 >

1. reduce에서 초기값을 주지 않으면 배열의 첫 번째 요소가 누적값(acc)이 된다. 

2. 배열이 비어있는데 초기값이 없으면 에러가 발생한다.

3. 배열이 비어있지 않고 단순 합계를 구할때에는 초기값을 생략해도 동작하지만, 안전성을 생각하면 초기값을 명시하는 것이 더 안전한 코드다. 

문제 : 자연수 N이 주어지면, N의 각 자릿수의 합을 구해서 return 하는 solution 함수를 만들어 주세요.
예를들어 N = 123이면 1 + 2 + 3 = 6을 return 하면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/12931

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 


코드 1

function solution(N){
    let answer = [...String(N)].map(Number);
    return answer.reduce((acc, num) => acc + num);
}

 

이 문제는 숫자를 그대로 다루기 보단 문자열로 바꿔서 자릿수를 분리하는게 가장 간단하다.

 

1. 숫자를 문자열로 변환한 뒤, 한 글자씩 배열로 펼쳤다.

  • String(N) 으로 문자열을 만든다. N = 123, "123"
  • [...String(N)] 로 배열로 펼친다. ["1", "2", "3"]

 

2. 문자열 배열을 숫자배열로 변환하였다.

  • 문자열 상태에서는 더하기 연산이 되지 않기에 숫자로 변환한다.
  • map(Number) 로 "1" 을 1로 변환

 

3. reduce로 모든 숫자를 누적해서 더하였다.

  •  reduce((acc, num) => acc + num)
  • 누적값(acc)에 현재숫자(num)를 계속 더해 최종 합을 만든다.

< 궁금했던 점 >

map(Number)을 실행하면 새로운 배열을 만드는걸까?

=>  map(Number)는 원본 배열을 건드리지 않고 새로운 배열을 만들어서 거기에다가 변형된 값들을 담는다. 

let num1 = ["1", "2", "3"];
let num2 = num1.map(Number);

console.log(num1); // ["1", "2", "3"]
console.log(num2); // [1, 2, 3]
  • console.log(num1)에서도 알 수 있듯이 num1의 원본은 절대 바뀌지 않는다
  • map()은 항상 새로운 배열을 반환한다

<  이번 문제에서 배운 점 >

1. 숫자를 자릿수로 나누고 싶을 때 문자열로 반환하면 간단하게 처리할 수 있다

2. map(Number)는 원본 배열을 변경하지 않고 변환된 값들을 담은 새 배열을 반환한다

3. reduce()는 배열의 값을 누적해 하나의 값으로 합치는데 유용하다

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

https://school.programmers.co.kr/learn/courses/30/lessons/12916

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


코드 1

function solution(s){
    let a = [...s].reduce((acc, num) => {
        return (num == 'p' || num == 'P') ? acc + 1 : acc;
    }, 0);
    let b = [...s].reduce((acc, num) => {
        return (num == 'y' || num == 'Y') ? acc + 1 : acc;
    }, 0);
    return a === b ? true : false;
}

 

 

  • 문자열을 스프레드 연산자로 하나씩 분리한 뒤 reduce 로 순회했다.
  • 대소문자 비교를 위해 'p' / 'P', 'y' / 'Y' 를 모두 조건에 넣고 누적값을 증가시켰다.
  • 마지막에 p와 y의 개수를 비교하여 true / false를 반환했다.

 

전체적인 로직은 잘 동작한다👍


처음에 작성한 틀린 코드

function solution(s){
    let a = [...s].reduce((acc, num) => {
        (num == 'p' || num == 'P') ? acc + 1 : acc; // return을 하지 않음
    }, 0);
    let b = [...s].reduce((acc, num) => {
        (num == 'y' || num == 'Y') ? acc + 1 : acc; // return을 하지 않음
    }, 0);
    return a == b ? true : false;
}

 

‼️ 문제가 생긴 이유 -> 이 코드는 어떤 입력을 넣어도 무조건 true를 반환하였다.

 

무조건 true를 반환한 이유 : reduce 콜백 안에서 return 을 하지않았기 때문에 삼항 연산자로 계산을 하였으나 그 값을 반환하지 않아서 콜백이 항상 undefined 를 반환한다. undefined == undefined 에서 무조건 true 가 나오는 이유가 이런 이유 때문이였다.

 

 

이 실수 덕분에 reduce 가 어떻게 작동하는지 한 번 더 확실하게 알게되었다 😊


코드2 (흥미로웠던 코드)

function solution(s){
    let lower = s.toLowerCase().split('');
    return lower.filter(c => c === 'p').length === lower.filter(c => c === 'y').length;
}

 

처음에 문자열 전체를 소문자로 바꿔버리면 대문자 처리를 신경 쓸 필요가 없고, filter로 원하는 문자만 추출하고 길이를 비교하면 끝인 직관적이도 짧은 코드가 흥미로웠다.


< 이번 문제에서 배운 점 >

1. 대소문자 비교는 문자열 통째로 변환하면 훨씬 단순해진다. 

- 처음부터 toLowerCase() 또는 toUpperCase()를 쓰면 조건문에 'p' || 'P' 이렇게 두 번 적을 필요가 없다.

 

2. reduce 는 순회 + 누적을 동시에 하는 메서드이다.

reduce((acc, num) => acc + num, 0)
  • acc -> 누적 값
  • num -> 현재 요소
  • 0 -> 초기 값
  • 리턴값이 다음 acc가 된다. 

 

문제 : 정수 num1, num2가 매개변수로 주어질 때, num1를 num2로 나눈 나머지를 return 하도록 solution 함수를 완성해주세요.

https://school.programmers.co.kr/learn/courses/30/lessons/120810

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

코드1

function solution(num1, num2){
    return num1 % num2;
}

 

 

코드2

let solution = (num1, num2) => num1 % num2;

 

문제 : 정수 num1, num2가 매개변수 주어집니다. num1과 num2를 곱한 값을 return 하도록 solution 함수를 완성해주세요.

https://school.programmers.co.kr/learn/courses/30/lessons/120804

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

코드1 

function solution(num1, num2){
    let result = num1 * num2;
    return result;
}
  • 중간 변수 result에 계산 값을 담아 반환
  • 반환값이 하나라면 변수를 생략하고 바로 return할 수 있음

 

코드2

function solution(num1, num2){
    return num1 * num2;
}

 

  • 반환값이 하나라서 변수 선언 없이 바로 return
  • 계산 과정이 간단할 때 이렇게 쓰면 코드가 깔끔해짐

 

코드3

let solution = (num1, num2) => num1 * num2;

 

  • 반환값이 하나라서 한 줄로 바로 반환 가능
  • 함수 자체를 변수(solution)에 할당하여 화살표 함수로 작성

 

 

+ Recent posts