[JS] 프로그래머스 - 소수 찾기(레벨2)

2020. 11. 11. 17:00·알고리즘/프로그래머스

문제 설명

한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.

 

제한사항

  • numbers는 길이 1 이상 7 이하인 문자열입니다.
  • numbers는 0~9까지 숫자만으로 이루어져 있습니다.
  • 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.

입출력 예

numbers return
17 3
011 2

입출력 예 설명

예제 #1

[1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.

 

예제 #2
[0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.

  • 11과 011은 같은 숫자로 취급합니다.

 

나의 풀이)

// 입력받은 숫자가 소수인지 아닌지 판단
function isPrime(num) {
  if (num <= 1) return false;
  if (num === 2) return true;
  for (var i = 2; i <= Math.sqrt(num); i++) {
    if (num%i === 0) return false;
  }
  return true;
}
 


function solution(numbers) {
  var num_array = numbers.split(''); // 배열화
  var primeNums = []; 
  
  function solution2(first, second) {
    if (second.length > 0) { // 두 번째 인자에서는 숫자가 소수인지 판단
      if (primeNums.indexOf(Number(second)) === -1) { // nums 안에 이 숫자가 들어있지 않으면,
        if (isPrime(Number(second))) {
          primeNums.push(Number(second));
        }
      }
    }
    if (first.length > 0) { // 첫 번째 인자에서는 배열을 쪼개서 모든 숫자를 비교할 수 있도록 함.
      for (let i = 0; i < first.length; i++) {
        let t = first.slice(0);
        t.splice(i, 1); // 반복문을 돌려서 first의 모든 값들을 뒤로 돌려준다.
        solution2(t, second + first[i]);
      }
    }
  }

  solution2(num_array, ''); // 배열과 빈 문자열을 넣어줌.

  return primeNums.length;
}


이 문제를 푸는 데는 꼬박 이틀이 걸렸다. 문제를 차근차근 읽고 먼저 어떻게 접근하는 것이 좋을지 생각해보았다.

이 문제는 다음과 같이 접근할 수 있다.

1. 주어진 숫자 문자열을 배열로 전환해준다.

2. 배열의 요소들을 조합하여 배열의 요소로 만들 수 있는 모든 숫자들을 만들어낸다.

3 이 숫자들이 소수인지 아닌지 판단한다.

4. 이 숫자들의 중복 여부를 체크하고 서로 다른 숫자들을 전부 primeNums 배열에 저장해둔다.

5. primeNums 배열의 길이를 결과값으로 반환한다.

 

주어진 숫자들에 대해 소수인지 아닌지 판단하는 함수는 이전에 짜본 적이 있어서 무리 없이 짤 수 있었다.

배열의 요소들을 조합하여 가능한 모든 숫자들을 만드는 과정에서 많이 헤맸다. 구글을 이용하여 검색을 해보던 도중 순열 알고리즘을 이용하면 해결할 수 있다는 것을 알게 되었다. 하지만 순열 알고리즘이 재귀 함수로 구성되어 있어서 코드를 이해하는 데 어려움이 많았다. 많은 자료를 보며 이해하였고 여러 시행착오 끝를 겪고 나서야 풀 수 있었다.

 

solution2 함수의 동작 순서

solution2 함수는 숫자 문자열들로 구성된 배열과 동적으로 바뀌는 문자열을 인자로 가진다.

먼저 배열 내 각각의 요소에 접근한다.

각 요소들을 첫 번째로 추출하여 이를 두 번째 인자에 더하며, 재귀적으로 solution2 함수를 호출한다.

두 번째 인자로 받은 문자열을 숫자로 변환하여 소수인지 여부를 판단한다. 소수라면 primeNum 배열에 추가한다.

이어서, 앞의 요소부터 순서대로 추출하며 두 번째 인자에 이를 이어붙이고 소수인지 여부를 판단한다.

이와 같은 과정이 배열의 요소가 존재하지 않을 때까지 재귀적으로 계속 반복된다.

 

이해를 돕기 위해, 예시를 살펴보자.

입력받은 문자열은 "011"이고, 이를 배열로 바꿔주면 ["0", "1", "1"]와 같은 형태를 가지고 있다.

이 배열을 solution2 함수의 첫 번째 인자로, 빈 문자열을 두 번째 인자로 넣고 호출해보자.

solution2(["0", "1", "1"], '')  호출

  - i = 0일 때, solution2(["1", "1"], "0") 호출 => "0"은 0으로 변환되고 소수가 아니라고 판단 =>

  solution2(["1", "1"], "0") 내의 for 문이 수행된다.

      - i = 0일 때, solution2(["1"], "01") 호출 => "01"은 1로 변환되고 소수가 아니라고 판단 => solution2([ ], "011") 호        출 => "011"은 11로 변환되고 소수라고 판단되어 primeNums 배열에 저장된다. => i = 0 일 때의 모든 동작이            완료되어 i++ 로 넘어온다.

      - i = 1일 때, solution2(["1", "01") 호출 => "01"은 1로 변환되고 소수가 아니라고 판단 => solution2([ ], "011") 호        출 => "011"은 11로 변환되고 소수라고 판단되지만 이미 primeNums 배열에 저장되어 있다. 

  => i = 0 일 때의 모든 동작이 완료되어 i++ 로 넘어온다.

  - i = 1일 때, solution2(["0", "1"], "1") 호출 => "1"은 1로 변환되고 소수가 아니라고 판단 => solution2(["1", "1"], "0")    내의 for 문이 수행된다.

      - i = 0일 때, solution2(["1"], "10") 호출 => "10"은 10으로 변환되고 소수가 아니라고 판단 => solution2([ ], "101")        호출 => "101"은 101로 변환되고 소수라고 판단되어 primeNums 배열에 저장된다. => i = 0 일 때의 모든 동작이        완료되어 i++ 로 넘어온다.

      - i = 1일 때, solution2(["0"], "11") 호출 => "11"은 11로 변환되고 소수라고 판단되어 primeNums 배열에 저장된          다. => solution2([ ], "110") 호출 => "110"은 110으로 변환되고 소수가 아니다.

  => i = 1 일 때의 모든 동작이 완료되어 i++ 로 넘어온다.

 

  - i = 2일 때, solution2(["0", "1"], "1") 호출 => "1"은 1로 변환되고 소수가 아니라고 판단 => solution2(["0", "1"], "1")    내의 for 문이 수행된다. 

      - i = 0일 때, solution2(["1"], "10") 호출 => "10"은 10으로 변환되고 소수가 아니라고 판단 => solution2([ ], "101")        호출 => "101"은 101로 변환되고 소수라고 판단되지만 이미 primeNums 배열에 저장되어 있다. => i = 0 일 때의        모든 동작이 완료되어 i++ 로 넘어온다.

      - i = 1일 때, solution2(["0"], "11") 호출 => "11"은 11로 변환되고 소수라고 판단되지만 이미 primeNums 배열에          저장되어 있다. => solution2([ ], "110") 호출 => "110"은 110으로 변환되고 소수가 아니라고 판단

  => 이로써 solution2 함수가 종료된다.

primeNums 배열에는 11, 101이 저장되어 있다.

'알고리즘 > 프로그래머스' 카테고리의 다른 글

[스택/큐] 같은 숫자는 싫어  (0) 2022.11.23
[프로그래머스 - SQL] 상품 별 오프라인 매출 구하기  (0) 2022.11.22
[JS] 프로그래머스 - 위장  (0) 2020.11.14
[JS] 프로그래머스 - 괄호 변환(레벨2)  (0) 2020.11.09
[JS] 프로그래머스 - 가장 큰 수(레벨 2)  (0) 2020.11.08
'알고리즘/프로그래머스' 카테고리의 다른 글
  • [프로그래머스 - SQL] 상품 별 오프라인 매출 구하기
  • [JS] 프로그래머스 - 위장
  • [JS] 프로그래머스 - 괄호 변환(레벨2)
  • [JS] 프로그래머스 - 가장 큰 수(레벨 2)
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (100)
      • k8s (1)
      • AWS (1)
      • 리눅스 (4)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Til
    Kubectl
    FastAPI
    django
    Kubernetes
    스택
    도커
    레벨2
    mysql
    iterable
    Python
    리눅스
    typeorm
    javascript
    redis
    배열
    생활코딩
    Linux
    네트워크
    코딩테스트
    프로그래머스
    모듈
    쿠버네티스
    컨테이너
    typescript
    nestjs
    자바스크립트
    IP 주소
    Docker
    기초
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
[JS] 프로그래머스 - 소수 찾기(레벨2)
상단으로

티스토리툴바