[Python / Javascript] 프로그래머스 : 숫자 짝꿍

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

최대한 for문을 적게 돌고자 딕셔너리를 만들었다.

개인적으로 자료형이나 메서드 연습하기 괜찮은 문제같다

Python Answer

from collections import Counter

def solution(X, Y):
    xCounter = Counter(X)
    yCounter = Counter(Y)
    commonKey = sorted(set(xCounter.keys()) & set(yCounter.keys()))
    commonDict = {key: min(xCounter[key], yCounter[key]) for key in commonKey}
    if len(commonDict) == 1 and '0' in commonKey:
        return "0"
    answer = ''
    for key in sorted(commonDict.keys(), reverse=True):
        while commonDict[key] > 0:
            commonDict[key] -= 1
            answer += key
    if answer == "":
        return '-1'
    return answer

Counter를 처음 사용해봤는데 정말 짱 편했다,,

commonKey 구할 때 sorted 안 해도 되는데 왜 했지?

 

Javascript Answer

function solution(X, Y) {
    let xSet = new Set(X);
    let ySet = new Set(Y);
    let commonDigits = Array.from(xSet).filter(digit => ySet.has(digit));
    // commonDigits에는 두 문자열에 공통으로 나타나는 숫자들이 배열로 저장

    if (commonDigits.length === 0) {
        return '-1';
    }
    if (commonDigits.length === 1  && commonDigits[0] === '0') {
        return '0'
    }

    commonDigits.sort((a, b) => b - a);
    let result = '';
    // 공통으로 나타나는 숫자들을 순회하면서 최소 등장 횟수만큼 추가
    for (let digit of commonDigits) {
        let countInX = X.split(digit).length - 1;  // X에서 현재 숫자가 등장하는 횟수
        let countInY = Y.split(digit).length - 1;  // Y에서 현재 숫자가 등장하는 횟수
        let minCount = Math.min(countInX, countInY);

        // 최소 등장 횟수만큼 현재 숫자를 결과 문자열에 추가
        result += digit.repeat(minCount);
    }

    return result;
}

자바스크립트는 주언어가 아니라 그런지 더 미숙하게 풀었다,,, 코드가 깔끔해보이는 건 서치와 서치를 거듭해서 겨우 알아낸 것들. split으로 현재 숫자가 등장하는 수를 알 수 있었다.

python과 비슷한 방식으로 풀고자 했는데, tc 1개가 틀려서 포기했다. 밑은 틀린 코드.  왜 틀렸지?

function solution(X, Y) {
    var answer = '';
    xDict = {}
    yDict = {}
    numList =[]
    for (i = 0; i < X.length; i++) {
        if (X[i] in xDict) {
            xDict[X[i]] += 1
        } else{
            xDict[X[i]] = 1
        }
    }
    for (i = 0; i < Y.length; i++) {
        if (Y[i] in yDict) {
            yDict[Y[i]] += 1
        } else{
            yDict[Y[i]] = 1
        }
    }
    commonKeys = Object.keys(xDict).filter(key => yDict.hasOwnProperty(key))
    commonKeys.sort((a,b) => b - a)
    commonDict = {}
    for (key of commonKeys) {
        commonDict[key] = Math.min(yDict[key], xDict[key])
    }

    if (commonKeys.length == 1 && '0' in commonKeys) {
        return '0'
    }
    if (commonKeys.length == 0) {
        return '-1'
    }
    for (key of Object.keys(commonDict)){
        while (commonDict[key] > 0) {
            commonDict[key] -= 1
            numList.push(key)
        }
    }
    numList.sort((a, b) => b - a)
    console.log(numList)
    for (i = 0; i< numList.length ; i ++) {
        answer += numList[i]
    }
    return answer;
}

 

 

+ 찾았다. '0' in commonKeys 부분을 commonKeys[0] === '0' 부분이나, commonKeys.includes('0')으로 바꿔주면 해결이 된다.

 

그 이유는 뭘까?

이처럼 javascript에서 in 연산자는 객체의 속성을 확인하기 위한 연산자이다. commonKeys.length == 1 && '0' in commonKeys 조건에서는 '0'이라는 키가 배열 commonKeys 안에 있는지를 확인하는 것이 아니라, 객체의 프로퍼티로서 '0'이 있는지를 확인 후 boolean 값을 반환한다.

 

그래서... '0' in commonKeys는 항상 false가 되기 때문에 해당 조건으로 들어가지 않는다. 따라서 해당 예제에서는 if (commonKeys.length == 1 && '0' in commonKeys) 부분은 실행되지 않는다.

 

js의 경우 속성 in 객체명으로 적어야 하기 때문에 해당 조건이 늘 false이던 것. 배열의 경우 인덱스를 적어주면 된다.

 

대체 지금까지 자바스크립트로 알고리즘 어떻게 푼 거지?

 

 

출처

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/in

 

in 연산자 - JavaScript | MDN

in 연산자는 명시된 속성이 명시된 객체에 존재하면 true를 반환합니다.

developer.mozilla.org

 
 
 
TAGS.

Comments