개발조각

[프로그래머스] [3차] n진수 게임 본문

알고리즘🅰/프로그래머스

[프로그래머스] [3차] n진수 게임

개발조각 2022. 4. 17. 18:20
728x90
반응형

이번 문제는 문제 이해하는데 오래 걸리고 아직도? 진번에 따라 이렇게 진행이 되는지 의문이 되는 문제입니다.

인간의 머리속 ?진법과 컴퓨터에서? 진법은 다른가 봐요.

 

그래서 이번 교훈은
애매하고 잘 모르겠으면 콘솔부터 찍어보고 확인해보자
(머릿속과 종이로 백날 생각해도 답이 안 나오니까 치고 시작해보자!!)

 

 

테스트 1로 설명하자면

테스트 1

1. 0부터 시작하는 숫자를 2진법(n=2)으로 바꾸고

  • 0 -> 0
  • 1 -> 1
  • 2 -> 10
  • 3 -> 11
  • 4 -> 100

이걸 이어 붙이면 -> 011011100

 

2. 이어붙이 숫자들에서 2명(m=2)중 1번째(p=1)의 숫자들만 나열하기

0 1 1 0 1 1 1 0 0
1 2 1 2 1 2 1 2 1

-> 01110

 

3. 나열한 숫자 중 4개(t=4)만 추출하기

-> 0111


해결방안

function solution(n, t, m, p) {
    var answer = '';
    for(let i=0; answer.length<=t*m; i++){
        let numtS = i.toString(n);
        answer += numtS.toUpperCase();
    }
    
    let answer2 = '';
    for(let i=0; i<answer.length; i++){
        if(m === p){
            if((i+1) % m === 0) answer2 += answer[i];
        }else{
            if((i+1) % m === p) answer2 += answer[i];
        }
        if(answer2.length === t) break;
    }
    return answer2;
}

해결방안 순서

  1. 0부터 시작하는 숫자를 n진법으로 바꾸어서 나열하기
  2. p번째에 해당되는 숫자들만 추출하기

 

 

 

1단계. 0부터 시작하는 숫자를 n진법으로 바꾸어서 나열하기

var answer = '';
for(let i=0; answer.length<=t*m; i++){
    let numtS = i.toString(n);
    answer += numtS.toUpperCase();
}

0부터 시작하는 숫자를 n진법으로 바꾸어서 나열을 해주었습니다.

for문을 사용해서 n진법을 나열해주었습니다.

  • let i=0; : n진법을 바꾸기 전의 숫자(0부터 시작해서 초기값으로 0으로 설정해주었습니다.)
  • let numtS= i.toString(n); : 10진수 i를 n진수로 바꾸어 줌(? 진법으로 바꿀 때는 toString()을 사용해줍니다.)
  • answer += numtS.toUpperCase(); : numtS를 answer에다가 이어줍니다.(toUpperCase()은 11~16진법일 경우 대문자가 아닌 소문자로 나와서 썼습니다.

여기서 answer.length<=t*m;가 가장 중요한 포인트인데요.

answer.length<=t*m;쓴 이유는 answer.length가 t*m 이상의 문자열은 필요가 없기 때문입니다.

 

예를 들어 t=16 m=2 이럴 경우에는

t=16 임으로, 문자열의 길이가 16까지만 필요합니다.

그리고 m=2 임으로 1, 2만 반복합니다.

여기서 answer의 문자열을 32개만 추출하면 p가 1이든 2이든 딱 맞게 추출할 수 있고 그 이상은 필요 없겠죠.

 

테스트 1 n=2 t=4 m=2 p=1
-> 011011100

테스트 2 n=16 t=16 m=2 p=1
-> 0123456789ABCDEF101112131415161718

테스트 3 n=16 t=16 m=2 p=2
-> 0123456789ABCDEF101112131415161718

 

 

 

2단계. p번째에 해당되는 숫자들만 추출하기

let answer2 = '';
    for(let i=0; i<answer.length; i++){
        if(m === p){
            if((i+1) % m === 0) answer2 += answer[i];
        }else{
            if((i+1) % m === p) answer2 += answer[i];
        }
        if(answer2.length === t) break;
    }
    return answer2;

answer에서 만든 숫자열을 p위치에 해당하는 숫자만 추출해야 됩니다.

 

만약 m=3이면

1 % 3 = 1

2 % 3 = 2

3 % 3 = 0

 

4 % 3 = 1

5 % 3 = 2

6 % 3 = 0

 

이걸 보시면 m=3일 때

p가 1이면 나머지 값이 1이면 되고

p가 2이면 나머지 값이 2이면 되고

p가 3이면 나머지 값이 0이면 됩니다.

 

즉,

m===p이면 나머지 값이 0이고

m===p 아니면 나머지 값이 p이면 됩니다.

 

그래서

if(m === p){
    if((i+1) % m === 0) answer2 += answer[i];
}else{
    if((i+1) % m === p) answer2 += answer[i];
}

조건문을 이렇게 적어주었고 해당되는 값에는 answer2에 answer[i]를 담아주었습니다.

 

 

마지막으로 if(answer2.length === t) break;를 넣어주어 answer2의 길이가 t와 같으면 반복문을 종료하게 해 주었습니다.

테스트 1 n=2 t=4 m=2 p=1
-> 011011100
-> 0111

테스트 2 n=16 t=16 m=2 p=1
-> 0123456789ABCDEF101112131415161718
-> 02468ACE11111111

테스트 3 n=16 t=16 m=2 p=2
-> 0123456789ABCDEF101112131415161718
-> 13579BDF01234567

프로그래머스 [3차] n진수 게임 해결방안 설명은 여기까지입니다.

728x90
반응형
Comments