내일배움캠프 TIL 23/10/30

김민재·2023년 10월 30일
1


코드카타 문제 풀이 복습

29번 문제 (최대공약수와 최소공배수)를 풀면서 겪었던 시행착오와 해결방법을 기술해보려고 한다.
함수에 변수 값 n,m을 넣으면 return answer 값으로 [x,y]와 같은 리스트 형식으로 뱉어내줘야 한다. x가 최대공약수이고, y가 최소공배수이다. 이전에 약수를 구하는 문제가 있었기에 기억을 더듬으면서 앞의 풀이과정을 살펴봤고, % 내장함수로 몫이 0이 되었을때 약수를 뱉어내주는 로직을 활용할 수 있을 것 같았다. 다만 최대공배수는 어떻게 뽑아내야 할 지 감이 안 잡혀서 검색을 통해 최대공배수가 수학적으로 어떻게 얻어낼 수 있는지를 참고했다.

    1. 약수를 통해 공통된 약수의 최대 승수 값과 나머지 약수들을 전부 곱해주는 것.
    1. lcm(a,b) 최소공배수 = a*b의 절대값 / gcd(a,b) 최대공약수

def test(n, m):
    answer = []
    for x in range(n, 0, -1):
        if m % x == 0:
            answer.append(x)
            break
    y = int((n*m)/answer[0])
    answer.append(y)
    return answer

처음에는 코드를 이런 식으로 짰는데 사실 약수를 전부 구해서 그 중 최대값을 최대공약수로 찾는 것도 귀찮아서 for문을 사용하되, 역순으로 짜서 변수 n이 변수 m의 약수에 해당하는 지에 대한 확인을 하고 아니라면 n의 값이 1씩 줄어들테니 거기서 약수 값을 찾아낸다면 그 값이 최대공약수가 될 것이라 생각했다. 그리고 이렇게 구해진 최대공약수를 위의 2번 수식을 적용시켜 x,y값을 얻어내기로 했는데, 테스트 사례는 통과했지만 제출하고 채점에서 다량의 오류가 발생하는 문제가 있었다. 다만 채점에서는 어떤 사례에서 통과가 못했는지는 나오지 않고 코드 문제에서 때때로 사전 조건에 대한 설명이 모호한 부분이 없지 않아 있기에 처음에는 n,m 값의 크기가 n>m의 형태라면 문제가 생기는 것이 아닐까 생각했다.(실제로도 문제가 있었고)


def solution(n, m):
    answer = []
    gcd = []
`
    if n > m:
        a = n
        n = m
        m = a
    for x in range(1, n+1):
        if m % x == 0:
            gcd.append(x)
    answer.append(max(gcd))
    y = int((n*m)/answer[0])
    answer.append(y)
    return answer

별로 마음에 안 드는 형태긴 하지만, if문에서 n이 m보다 클 시 변수값을 각각 할당해주는 방법을 사용했다.(원래는 두 변수의 값만을 바꿔주고 싶었는데) 다만 여전히 같은 오류를 뱉어내주고 있어서 for문의 형태도 살짝 바꿔줬지만 달라지는게 없어서 질문하기 탭에서 채점하는 데 사용하는 문제를 알 수 있을까 싶었는데 다른 사람의 문제에서 반례로 든 값이 나에게도 안되는 것을 보고 내 코드에 어떤 문제가 있는지 알게 되었다.
반례 : solution(6,4)


반례를 따르면 기대값은 [2,12]인데 실제로는 [3,8]이 출력된다. 그래서 최종 코드를 이렇게 짰다.

def solution(n, m):
    answer = []
    n_cd = []
    gcd = []
    for x in range(1, n+1):
        if n % x == 0:
            n_cd.append(x)
`
    for a in n_cd:
        if m % a == 0:
            gcd.append(a)
    answer.append(max(gcd))
`
    y = int((n*m)/answer[0])
    answer.append(y)
    return answer

최대공약수에서 뭔가 문제가 있어서 오류가 생기는게 아닌가 의심하고 있었는데 실제로 예시를 통해 보니 어떤 문제가 있는지 확실히 알 수 있었다. 최소공배수 값은 최대공약수를 통해 뽑아내주기에 같이 영향을 받는 것이고. 4라는 값이 하나씩 내려온다면 6과 나눴을때 나머지가 0이 되는 값은 6의 약수인 (1,2,3) 최종적으로 max값을 뽑아내기에 3이 추출될건데 3은 4의 약수가 되지 않기때문에 앞의 수의 약수에 대한 정의를 먼저 해주고 뒤의 값과 약수를 정의해주는 함수(m%x == 0)을 지정해줘야 할 것 같았다. 다른 사람의 해설에선 람다식을 이용하기도 하고 보기에 별로 깔끔한 코드 배열은 아니지만 일단은 문제 해결이 됐다는 점에서 만족한다.

1개의 댓글

comment-user-thumbnail
2023년 10월 31일

각자 해결하는 방법은 다르죠. 점차 다듬어가는게 중요하다고 생각합니다!

답글 달기