Study

[ javascript && Python ] 알고리즘 챌린지 "Part4"

wookjae 2023. 3. 3. 23:14

about:blank

 

Question31. 등수매기기

영어 점수와 수학 점수의 평균점수를 기준으로 학생들의 등수를 매기려고 합니다. 영어점수와 수학점수를 담은 2차원 정수배열 score 가 주어질 때, 영어 점수와 수학점수의 평균을 기준으로 매긴 등수를 담은

배열을 return 하도록 solution함수를 완성해보세요.

 

Cf)

Score                                                   result

[ [80,70],[90,50],[40,70],[50,80] ]         [1, 2, 4, 3]

 

# javascript 답안

function solution(score) {

    // Step1. 각 수학영어 점수의 합산을 진행한 배열을 구한다.
    // 150, 140, 110, 130
    let totalSum = score.map((v) => v[0] + v[1]);

    // Step2. 위 결과 의 내역을 점수순으로 내림차순 한다.
    // 150 140 130 110
    let sortArr = totalSum.slice().sort((a, b) => b - a);

    return totalSum.map((v) => sortArr.indexOf(v)+1);
}

console.log( solution( [ [80, 70], [90, 50], [40, 70], [50, 80] ]) );

# python 답안 

def solution(score): 

    sortPoints = sorted([ sum(i) for i in score ], reverse=True)
    
    return [ sortPoints.index(sum(j)) + 1 for j in score ]
    
    
    
print(solution([ [80, 70], [90, 50], [40, 70], [50, 80] ]))   

 

Question32. 저주의 숫자3

3x 마을 사람들은 3을 저주의 숫자라고 생각하기 때문에 3의 배수숫자3을 사용하지 않습니다. 

정수 n 이 주어질 때, n을 3x 마을에서 사용한는 숫자로 바꿔 return 하도록 solution함수를 완성해보세요.

 

10진법 3x 마을에서 쓰는 숫자 10진법 3x 마을에서 쓰는 숫자
1 1 6 8
2 2 7 10
3 4 8 11
4 5 9 14
5 7 10 16

 

# javascript 답안

function solution(n) {

    /*** 방법1: 반복문 활용 */
    // var answer = 0;

    // 변수이름이 '_'인 경우는 사용하지 않는 의미없는 변수일 시.. 사용.
    // for (let _ = 0; _ < n; _++) {

    //   answer +=1;

    //   // 3의배수가이거나 3이 포함되어있을 시. 제외
    //   while (answer % 3 == 0 ||
    //          answer.toString().split('').includes('3')) {
    //       answer +=1;
    //   }
    // }
    // return answer;

    /*** 방법2: 배열 활용 */

   let arr = [];

    for (let i = 0; i < 1000; i++) {

        // 3의 배수가 아니며, 3이 포함되지 않은 숫자만 배열에 포함.
        if (i % 3 != 0 && !i.toString().split("").includes("3")) {
            arr.push(i);
        }
    }

    return arr[n - 1];
}
 

# python 답안 

def solution(score): 

    ##### 방법1 
    # answer = 0

    # for _ in range(n): 
    #     answer += 1 
        
    #     while '3' in str(answer) or answer % 3 == 0:
    #         answer += 1 
            
    # return answer
    
    ##### 방법2 
    
    # 3의배수가 아니거나, 3을 포함하지 않는 배열
    return [ i for i in range(1, 100) if i % 3 != 0 and not('3' in str(i))][n-1]

    
# 원본배열
# [ 1, 2, 3, 4, 5, 6, 7,  8,  9,  10]
# 3x 배열 
# [ 1, 2, 4, 5, 7, 8, 10, 11, 14, 16]

 

 

Question34. 안전지대

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌우, 대각선 칸을 모두 위험지역으로 분류합니다. 지뢰는 2차원 배열 board에 1로 표시되어있고 board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역0만 존재합니다. 지뢰가 매설된 지역의 지도 board 가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return 하도록 solution함수를 완성해보세요.

Cf)

도면

         
  X X X  
  X 지뢰 X  
  X X X  
         

// 안전한 지역1, 안전하지 않은지역 0 

[  

    [0,0,0,0,0], 

    [0,1,1,1,0],

    [0,1,1,1,0],

    [0,1,1,1,0],

    [0,0,0,0,0]

]

 

# javascript 답안

function solution(board) {

    const n = board.length;

    const riskArea = [
                                    [0, 0], // 지뢰가 있는 원 위치
                                    [0, 1], // 지리가 있는 원 위치 에서 한칸 위
                                    [0, -1],
                                    [1, 1],
                                    [1, 0], // 지뢰가 있는 위치에서 우측 한칸
                                    [1, -1],
                                    [-1, -1],
                                    [-1, 0], // 지뢰가 있는 위치에서 좌측 한칸
                                    [-1, 1],
                               ];

    // 좌표의 중복을 제거하기 위해 Set(집합)으로 생성
    let dangerZone = new Set();
    //let dangerZone = new Array();

    // N * N 이므로 2중배열로 동일하게 가져간다.
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            // 지뢰가 깔린 핵심지역은 초기 값 == 1
            if (board[i][j] === 1) {
                riskArea.forEach(v => {
                    let [col, row] = [i + v[0], j + v[1]];

                    // 좌표 중 음수가 나올 수 있으므로.. 조건을 체크하여 Add..
                    if (col >= 0 && col < n && row >= 0 && row < n) {
                        dangerZone.add(col + ' ' + row);
                    }
                });
            }
        }
    }

    //riskArea.forEach(v => console.log(`v1 : ${2 + v[0]} , v2: ${2 + v[1]}`));
    //console.log(dangerZone);

    return n * n - dangerZone.size;
}

console.log(solution([
  [0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0],
  [0, 0, 1, 0, 0],
  [0, 0, 1, 0, 0],
  [0, 0, 0, 0, 0],
]));

# python 답안 

##### 방법1 

def solution(n):    

    factorial = 1      
    i = 1 
    
    while factorial <= n: 
        i += 1
        factorial *= 1
        
    return i-1

##### 방법2 : math 라이브러리 사용하기 

from math import factorial 


def solution(n):    
    i = 1     
    
    while factorial(i) <= n: 
        i += 1
        
    return i - 1

 

Question35. 겹치는 선분의 길이

선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[strat, end], [strat, end], [strat, end]] 형태로 들어있는 2차원 정수배열 lines 가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 
return 하도록 solution함수를 완성해보세요.

Cf)

            ----------------- (A)
    -------------(B) ----------(C)
-------------------------------------------
   -3    -2    -1    0    1    2    3

>> A, B, C 선분의 겹치는 선분의 길이 2
    [-2, -1] [0, 1] 로 길이 2만큼 겹침

 

 

# javascript 답안

function solution(lines) {

    let line = new Array(200).fill(0);

    lines.forEach(([min, max]) => {

        // 시작값은 존재X
        for (; min < max; min++) {
          // 음수고려 하여 여유만큼 (+)
          // 0부터 시작할 시. 좌표 표시가 X
          line[min + 100]++;
        }
    });

    //return line;
    return line.filter((v) => v > 1).length;
}

# python 답안 

def solution(lines):
    
    line = [0 for i in range(20)] 

    for a, b in lines: 
        while a < b: 
            line[a+10] += 1
            a += 1
    
    # chk = list(filter(lambda x: x>1, line))    
    # print(chk)
        
    # return len(list(filter(lambda x: x>1, line)))

    # print(line)

    # return [ i for i in range(1, 100) if i % 3 != 0 and not('3' in str(i))][n]

    # 2 3 4 5 6
    #   3 4 5 6 7 8 9

print(solution([[0, 1], [2, 6], [3,9]]))  

 

 


[ 코딩도장 문제 ]

 

Question36. 구글입사문제 

1부터 10,000까지 8이라는 숫자가 총 몇번 나오는가?

8이 포함되어 있는 숫자의 갯수를 구하는 것이 아니라 8이라는 숫자를 모두 카운팅 해야 한다.

(※ 예를들어 8808은 3, 8888dms 4로 카운팅 해야 한다.)

 

# javascript 답안

function solution() {
    //////////////////// TEST
    // 1부터 ~ 10,000 (1만)까지의 수를 문자열로 붙인다.
    let num = "0123456789101112131415";

    // 빈 공백 기준으로 Split (1개의 문자단위로 Cut)
    let numArr = num.split("");
    let oneCount = numArr.filter((val) => val == "1").length;

    //console.log(numArr);
    //console.log(oneCount);
    //////////////////// 테스트

    // 1 ~ 100까지만 TEST
    // Array(100).fill(0) -- 0으로 채워진 100의 길이의 배열생성
    // map으로 0~99까지의 원소를 추출 하여 toString()으로 하나의 문자열로 치환
   let chk = Array(100).fill(0)
                                   .map((val, idx) => idx)
                                   .toString()
                                   .split('')
                                   .filter((val) => val === '8').length;

    console.log(chk);
    console.log(typeof chk);
}

 

# python 답안 

def solution(): 
        
    # 0~100까지의 범위의 배열을 문자열로 변환시킨 이후 8의 갯수를 카운트.
    aa = str(list(range(100))).count('8')
  
    return aa

 

Question37. 다음 (Kakao) 입사문제 

1차원 점들이 주어졌을 때,  중 가장 거리가 짧은 것의 쌍을 출력하는 함수를 작성.

(※ 단 점들의 배열은 모두 정렬되어있다고 가정한다.)

예를들어 S = {1, 3, 4, 8, 13, 17, 20}이 주어졌다면 결과값은 3,4가 될 것이다. 

 

# javascript 답안

function solution(tgtArr) {
    ///////////// 방법1. 반복문 및 제어문활용
    // let index = 0;
    // let minim = Infinity;

    // //console.log(minim);

    // // 순회
    // for (let i = 1; i < tgtArr.length; i++) {
    //   // 최소값 보다 작을 시 `.
    //   if (tgtArr[i] - tgtArr[i - 1] < minim) {

    //     //console.log(tgtArr[i], tgtArr[i - 1]);
    //     index = i
    //     minim = tgtArr[i] - tgtArr[i - 1];
    //   }
    // }

    //console.log(tgtArr[index], tgtArr[index - 1])

    ///////////// 방법1. 반복문 및 제어문활용

    let tgtSli = tgtArr.slice(1); // 첫번째 요소를 Cut
    //console.log(tgtSli)             // 3 4 6 8 13 17 20

    let tgtArrConv = tgtArr
      .map((val, idx) => [val, tgtSli[idx]])
      .sort((a, b) => (a[1] - a[0]) - (b[1] - b[0]))[0];

    //console.log(tgtArrConv);

    let ttt = [3, 1, 8, 13, 4, 20, 17];
  
    console.log(ttt.sort((a,b) => b -a));
}

solution([1, 3, 4, 8, 13, 17, 20]);

# python 답안 

def solution(): 
    # Methods1
    s = [1, 3, 4, 8, 13, 17, 20]
    
    # index = 0
    # minim = float('inf')
    
    # for i in range(1, len(s)):
    #     if (s[i] - s[i-1]) < minim: 
            
    #         index = i 
    #         minim = s[i] - s[i-1]
    
    # print(s[index], s[index-1])
    
    
    # Methods2 : Using Sliceing 
                # [ 1, 3, 4, 8,  13, 17, 20]
    ss = s[1:]  # [ 3, 4, 8, 13, 17, 20 ]
    
    # [(1, 3), (3, 4), (4, 8), (8, 13), (13, 17), (17, 20)]
    finl = list(zip(s, ss))
    
    # 오름차순으로 정렬 
    finlRtn = sorted(zip(s, ss), key=lambda x:x[1]-x[0] )[0]
    
    print(finlRtn)

# Call a Function     
solution()