CodeWars 18 : Streeeet

김기욱·2021년 7월 8일
0

코딩테스트

목록 보기
57/68

문제설명

Task
You've just moved into a perfectly straight street with exactly n identical houses on either side of the road. Naturally, you would like to find out the house number of the people on the other side of the street. The street looks something like this:

# STREET
1|   |6
3|   |4
5|   |2

Evens increase on the right; odds decrease on the left. House numbers start at 1 and increase without gaps. When n = 3, 1 is opposite 6, 3 opposite 4, and 5 opposite 2.

Given your house number address and length of street n, give the house number on the opposite side of the street.

문제요약 : 거리길이인 n이 주어집니다, n의 길이만큼 위의 예시와 같이 홀수와 짝수가 두개씩 정렬되는데 홀수는 정배열 짝수는 역배열입니다. n만큼 길이의 거리에서 주어진 숫자 address의 맞은편에 있는 숫자를 구하는 함수를 만드시오.

제한사항

None

입출력 예시

over_the_road(address, n)
over_the_road(1, 3) = 6
over_the_road(3, 3) = 4
over_the_road(2, 3) = 5
over_the_road(3, 5) = 8

풀이

# 최초풀이
def over_the_road(address, n):
    odd = [i*2+1 for i in range(n)]
    even = sorted([i*2+2 for i in range(n)], reverse=True)
    for x, y in zip(odd, even):
        if x == address:
            return y
        elif y == address:
            return x
# 두번째 풀이
def over_the_road(address, n):
    odd = [i*2+1 for i in range(n)]
    even = sorted([i*2+2 for i in range(n)], reverse=True)
    return even[odd.index(address)] if address % 2 else odd[even.index(address)]

# 최종풀이
def over_the_road(address, n):
    return n*2-(address-1)

이번문제는 사실 난이도가 무척 쉬운 문제였습니다. 다만 수학적으로 계산하면 쉽게 풀 수 있는걸 초반에는 코드에 치중해 쓸데없는 부분이 많고 메모리 사용량도 많은 로직을 짰었는데, 이를 조금씩 개선해 나갔던 과정을 공유하고자 게시물을 올려봅니다.

먼저 첫 번째 풀이입니다. 짝수와 홀수의 리스트를 n길이만큼 만들고, 짝수는 역배열시킵니다.
이 두개를 zip을 통해 동시 돌려가면서 address랑 맞는 x(or y)가 나오면 그 위치에 위치한 y(or x)를 리턴시켜줍니다. 이 풀이의 문제는 두 개나 리스트를 만들고 for문을 통해 처음부터 일일히 대조해 나간다는 점입니다. 당연히 메모리관리 측면에서 매우 안좋습니다.

두 번째 풀이는 두 개의 리스트를 만드는 것은 동일하나, 마주보는 숫자는 똑같은 인덱스를 가진다는 점에 착안해 for loop + zip 대신 index함수를 사용해서 답을 구해주는 방식입니다. 코드길이도 짧고 메모리 관리 측면에서도 나으나 여전히 두 개의 리스트를 만들어야 된다는 점이 아쉽습니다. n의 길이가 클 경우 메모리 부하가 염려됩니다.

세 번째 풀이는 두 숫자의 관계를 생각했을 때(문제설명에 나와있는 예시 참조) 1의 맞은편 숫자인 6은 3*2(전체길이)-(address(=1) - 1)이였고 6역시 맞은편 숫자인 1이 나오려면 똑같은 공식을 쓰면 된다는 점에서 착안했습니다. 중학수학 정도의 규칙이였지만 오랜만에 생각해보려니 생각보다 시간이 좀 더 걸리더군요. 단순 연산이기 때문에 메모리리소스 관리적인 측면도 매우 좋고, 코드 길이도 짧았습니다.

결론 : 수학을 잘해야 코딩도 잘한다..🤦🏻‍♂️

다른풀이

None

profile
어려운 것은 없다, 다만 아직 익숙치않을뿐이다.

0개의 댓글