본문 바로가기

Python(알고리즘,문제풀이)/프로그래머스(코딩기초트레이닝)

코딩기초트레이닝 / 주사위게임 3

728x90

📚문제

출처 : 프로그래머스(https://school.programmers.co.kr/learn/courses/30/lessons/181916)

 

📝풀이

def solution(a, b, c, d):
    nums = [a,b,c,d]
    cnts = [nums.count(i) for i in nums]
    if max(cnts) == 4:
        return 1111*a
    elif max(cnts) == 3:
        p = nums[cnts.index(3)]
        q = nums[cnts.index(1)]
        return (10*p +q)**2
    elif max(cnts) == 2:
        if min(cnts) == 2:
            return (a+c)*abs(a-c) if a==b else (a+b)*abs(a-b)
        else:
            p = nums[cnts.index(2)]
            return int((a*b*c*d)/(p**2))
    else:
        return min(nums)

그냥 단순하게 if문과 elif문을 사용하여 모든 상황에 노가다해서 일단 풀어보기라도 할까했지만

그것도 a,b,c,d중에서 어떤 수가 p와 q가 될지 정해주지않으면 어려울 것 같아서 구글링했다

그리고 어차피 노가다로 풀었으면 분명 신박한 해법이 있을거라 생각하고 다른 풀이를 찾아보려했다

 

그러다가 발견한 이 코드...진짜 대단하신듯

 

 

한 줄씩 코드 살펴보기

1. count() 함수 사용

cnts = [nums.count(i) for i in nums]

우선 이 코드가 제일 핵심인 것 같다

a,b,c,d를 nums라는 list에 넣어주고 

for문을 돌며 각 숫자(a,b,...)가 nums 안에 몇개 있니 ? 

를 세어주는 코드 

# example
nums = [1,1,3,5]
cnts = [2,2,1,1]

 

2. max()함수 사용 -1

 if max(cnts) == 4:
        return 1111*a
elif max(cnts) == 3:
    p = nums[cnts.index(3)]
    q = nums[cnts.index(1)]
    return (10*p +q)**2

 

max(cnts) == 4 

=> a,b,c,d가 동일

 

max(cnts) == 3

=> a,b,c,d중 3가지만 동일

이 때 

p = nums[cnts.index(3)]

로 설정하였는데

이 뜻은 cnts(몇 개의 숫자가 동일하니?) 리스트에서 3개가 동일한 숫자의 위치(index)를 반환해서

nums(=a,b,c,d) 리스트에서 3개가 동일한 숫자의 위치 중 제일 처음에 있는 수를 반환

 

예를 들어서

nums = [4,4,3,4]
cnts = [3,3,1,3]
nums[cnts.index(3)] == 4

 a,b,c,d = 4,4,3,4 이므로

cnts = [3,3,1,3] 반환

cnts.index(3)은 3이라는 숫자가 있는 인덱스들(여기선 0,1,3) 중 제일 처음에 3이 나올 때를 반환 (리스트의 제일 앞에 있으므로 0반환)

그래서 nums[0] = 4가되서 

3개 있는 수 => p

1개 있는 수 => q 가된다

 

3. max()함수 사용 - 2

elif max(cnts) == 2:
    if min(cnts) == 2:
        return (a+c)*abs(a-c) if a==b else (a+b)*abs(a-b)
    else:
        p = nums[cnts.index(2)]
        return int((a*b*c*d)/(p**2))

이 부분도 보고 이해하면서 감탄했다

처음에는 elif 밑에 if min(cnts) ==2를 보고 무슨 뜻인지 생각했다

 max(cnts) ==2인 경우로 

주사위가 2번만 같은 수가 나온 경우(=p)에서

min(cnts) == 2 라는 것은 나머지 2개의 주사위에서도 같은수(=q)가 나왔지만 

앞선 주사위 2개의 점수와는 다르다는 뜻(p !=q)

 

i) return문

return (a+c)*abs(a-c) if a==b else (a+b)*abs(a-b)

return문에서도 if a==b의 경우만 생각해주면 되는게 

a==b(==p)이면 c==d(==q)이고

a와 c에 대해서 연산해주면 문제에서 말하는대로 p와 q에 대한 연산을 해주는 것이다

 

그리고 else의 경우에서

a==c라면 b==d이고

a와 b에 대해서 연산해주면 p와 q에 대한 연산을 해주는 것이다

 

a==d라면 b==c이고

a와 b에 대한 연산이면 마찬가지로 p와 q에 대한연산

(4개중에 2개씩 같기 때문에 나머지 경우의 수는 없다)

 

이걸 이렇게 한 줄에 표현한걸 보면서 계속 신기하고 감탄...

 

2) else문

else:
    p = nums[cnts.index(2)]
    return int((a*b*c*d)/(p**2))

가장 밑에 else문은

두 수가 같고 나머지 수는 각각 다른 경우(ex 2,2,3,5)

이 때 p는 2

연산에서 a,b,c,d중 2가지가 같고(==p) 나머지 다른 두 수(q,r)이 있으므로

p**2으로 나눠주면 결과값은 q*r이 된다

(a,b,c,d 중 어떻게 2개가 같은지 알아낼 필요없이 p**2으로 나눠주면 자연스럽게 q와r에 대한 연산이 됨)

 

 

+

모르고 풀고 있었는데 코딩기초 125문제들 중 정답률이 2번째로 낮은 문제라고 한다...

역시 어려운 문제였어..ㅎㅎ

나도 앞으로 실력을 더 키워서 단순 노가다말고 이렇게 풀어보고 싶다

꾸준히 문제풀이하다보면 이런 코드가 생각나는 날이 오겠지..?

728x90