코딩테스트/그리디

[코테] 숫자 카드 나누기

수타. 2024. 6. 11. 11:29

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

 

프로그래머스

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

programmers.co.kr

 

문제요약: 

두 개의 배열이 주어질 때 한 배열은 모두 나누어떨어지고 한 배열엔 하나도 나누어 떨어지지 않는 숫자 중 가장 큰 수a를 구하시오.

 

소요시간:

25분

 

난이도:

level2

 

제출횟수:

2회

 

코딩:

def solution(arrayA,arrayB):
    def gcd(a,b):
        while b!=0:
            r = a%b
            a = b
            b = r
        return a
    def find(A):
        if len(A)==1:
            return A[0]
        m = gcd(A[0],A[1])
        for a in range(2,len(A)):
            m = gcd(m,A[a])
            if m==1:
                break
        return m
    mA = find(arrayA)
    mB = find(arrayB)
    LmA = [[a,1] for a in range(2,mA//2+1) if not mA%a ]
    LmB = [[a,0] for a in range(2,mB//2+1) if not mB%a]
    L = LmA+LmB+[[mA,1],[mB,0]]
    L.sort(key= lambda x :x[0],reverse = True)
    
    Arr= [arrayA,arrayB]
    for n,arr in L:
        for i in Arr[arr]:
            if i%n:
                pass
            else:
                break
        else:
            return n
    return 0

먼저 최소공배수를 구하는 로직 gcd를 짜주고 각 배열을 순환하며 각 배열 전체의 최소 공배수를 구해줍니다. (이때 길이가 1이될 수 있으므로 예외처리를 해줘야함 이걸로 제출 날림) 그 후 그 최소공배수를 나열한뒤 만약 a배열에서 나온숫자라고 한다면 b배열에서 그 숫자를 하나씩 나눠보면서 전체가 다 나누어 떨어지지 않으면 탈출하여 그 숫자를 반환합니다. 준비되어있는 숫자를 전부 다 하면 for문이 종료되므로 0을 반환해 주었습니다.

 

다른사람 풀이:

from functools import reduce
from math import gcd


def solution(nums1, nums2):
    gcd1, gcd2 = reduce(gcd, nums1), reduce(gcd, nums2)
    answer = []
    if all(each % gcd2 for each in nums1):
        answer.append(gcd2)
    if all(each % gcd1 for each in nums2):
        answer.append(gcd1)
    return max(answer) if answer else 0

사실 이번 문제는 문제에서 말해준 과정들을 구현을 열심히하면 시간복잡도와 상관없이 풀리는 문제였습니다. 하지만 구현과정을 다른사람들이 더 빠르고 가시적으로 보기쉽게 푼 풀이가 있어 리마인드 차 기록해봅니다.

먼저 math모듈에 구현이 되어있는 gcd가 있고, functools 에 reduce함수가 있는데 이는

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

이런식으로 선언되어있습니다. 초기값을 선언해주지 않으면 첫번째 인자값이 시작값이고, 선언해주면 초기값이 첫번째값이 됩니다.

그 이후 function을 기존값과 그다음값을 진행한 뒤 그값을 다시 value에 저장시켜줍니다. 위 함수를 통해 각 배열의 전체의 최대공약수를 구하는데 가난하게 서술할 수 있었고, 각 값을 나머지 배열에 나눠보는것 역시 all함수를 통해 다음과같이 깔끔하게 정리할 수 있었습니다.