post-custom-banner

오늘은 9시부터 알고리즘 타입어택이 있었다. 프로그래머스 문제를 푸는 건데 10시 20분에 끝내고 미리 TIL을 쓰고 있는 중이니까 1시간 20분동안 4문제를 푼 셈이다.

각도기

def angle_return(angle):
    if 0 < angle < 90:
        return 1
    if angle == 90:
        return 2
    if 90 < angle < 180:
        return 3
    if angle == 180:
        return 4
def solution(angle):
    answer = angle_return(angle)
    return answer

첫번째 문제는 각도에 따라 리턴값을 따로 주라는 거였다.

예각 : 1, 직각 : 2, 둔각 : 3, 평각 : 4

나는 이렇게 밖에 생각이 나지 않아 길게 작성했는데 제출 후 다른 사람이 작성한 코드를 볼 수 있어 구경해보니 2줄? 만으로 작성한 분들이 계시더라.

def solution(angle):
    answer = (angle // 90) * 2 + (angle % 90 > 0) * 1
    return answer

이거였는데 처음에 보고 뒷 부분이 이해가 가지 않아 이게 뭐지? 싶었지만 임의의 수를 넣어 대입해서 풀어보니 이해가 갔다.

//은 소수점 이해를 전부 버린다는 뜻이다. 때문에 앞의 (angle // 90)은 90이상이면 2가 되고 90이하면 0이 된다.

뒤의 (angle % 90 > 0) 은 참인 경우 1을 반환하고 거짓인 경우 0을 반환하기 때문에 angle이 90이나 180이 아닌 이상 1이 된다. 이런식으로 값을 넣어 결과값을 뽑는 것이었는데 이런 식으로 뽑는다는 생각은 해본 적이 없어 대단했다.

옷가게 할인받기

def solution(price):
    answer = 0
    if 10 <= price < 100000:
        answer = price
    if 100000 <= price < 300000:
        answer = (price - (price * 5/100))//1
    if 300000 <= price < 500000:
        answer = (price - (price * 10/100))//1
    if 500000 <= price <= 1000000:
        answer = (price - (price * 20/100))//1
    return answer

두번째 문제는 옷 가격에 따라 할인률이 달라지는 문제였는데 4문제 중에 시간을 가장 많이 썼다. 처음에 결과를 제출했을 때 자꾸 틀렸다고 해서 테스트 문제를 여러개 넣고 다시 돌려봤는데 한 부분이 answer에 결과가 담기지 않고 있었다. 뭔가 싶어서 보니 answer를 anwer로 적어놨더라... 프로그래머스는 오타 한 번 나면 고치기 힘들다는 걸 깨달았다.

다른 분이 작성한 코드는 역시나 깔끔했다.

def solution(price):
    discount_rates = {500000: 0.8, 300000: 0.9, 100000: 0.95, 0: 1}
    for discount_price, discount_rate in discount_rates.items():
        if price >= discount_price:
            return int(price * discount_rate)

할인가의 기준이 되는 가격을 키 값에 놓고 100 - 할인율 의 결과를 벨류값에 넣었는데 큰 순서대로 넣어놔서 하나씩 뽑아 비교를 할 때 기준이되는 가장 큰 값에 걸리면 즉시 계산을 해 반환하도록 만들어진 코드였다. 나도 언젠가는 이렇게 다양한 자료형을 자유자재로 쓰는 날이 왔으면...

369게임

def solution(order):
    num = [3, 6, 9]
    answer = 0
    for i in str(num):
        answer += str(order).count(i)
    return answer

세번째 문제는 order에 존재하는 3, 6, 9의 개수를 합산해 반환하는 문제였다. 어제 잠이 안 와서 프로그래머스 문제 풀다가 뻘짓을 하던 중에 문자 개수를 구하는 함수가 있다는 걸 알아서 구글링을 해 찾아본 후 이렇게 구현해보았다.

다른 분들은 한 줄로 구현하신 분들이 계시더라. 역시 익숙해지면 저렇게 할 수 있을까 싶었다.

def solution(order):
    return sum(map(lambda x: str(order).count(str(x)), [3, 6, 9]))

잘은 모르지만 이 분게 가장 깔끔하다고 느꼈다. 람다와 맵이라니 분명 며칠 전 배운 건데 개념도 까먹은 거라 해석은 좀 찾아봐야할 듯 했다. 하지만 대충 해석해보면 order.count를 하는데 x의 자리에 3, 6, 9가 들어가고 그 결과들을 다 합한다는 뜻이 아닐까? 지금 자바랑 파이썬을 동시에 배워서 헷갈리는데 맵이 반복문 같은 느낌이 든다 했더니 찾아보니 map(적용시킬 함수, 적용할 값) 이란다.

적용할 값에는 리스트나 튜플 같은 반복 가능한 자료형이 온다하니 참고

def solution(order):
    return len(list(filter(lambda v: int(v) in [3, 6, 9], [int(n) for n in str(order)])))

이 경우에는 좀 긴데 filter의 경우 filter(조건함수, 순회 가능한 데이더) 로 사용되고 람다함수를 쓸 수 있어 filter의 기준을 v 에 들어가는 3, 6, 9로 하여 뒤의 값에서 일치하는 것을 뽑아오겠다는 뜻이다. filter의 경우 리스트나 튜플 타입으로 값을 저장해야만 하며 order에 있는 조건에 일치하는 모든 값이 리스트에 저장되었으므로 그 길이를 반환해주면 개수가 된다. 는 뜻이다.

개인적으로는 위에 맵과 람다를 쓴게 더 잘 이해가 되었던 것 같다. 아래 글은 금방 까먹을 느낌.

로그인 성공?

def solution(id_pw, db):
    answer = ''
    for i in range(len(db)):
        if id_pw[0] == db[i][0]:
            if id_pw[1] == db[i][1]:
                answer = "login"
                return answer
            else:
                answer = "wrong pw"
                return answer
        else:
            answer = "fail"
    return answer

이것도 시간이 제법 걸린 문제였다. login과 wrong pw까지는 잘 출력하는데 fail 부분만 넣으면 잘 되던 것도 안 되서 조건을 넣어보기도 하고 return을 잘못 썼나 고민도 했었는데 저 login 부분과 wrong pw 가 출력되는 부분 밑에 return 을 해주면 해결되는 문제였다.

나는 아이디를 db를 하나하나 돌려가며 비교하게 코드를 짰는데 만약 첫번째에 일치하는 아이디를 찾고 패스워도 역시 맞을 때 answer에 login이 들어가지만 문제는 여기서 return을 안 해주면 그 다음 반복문이 돌면서 login을 fail로 바꾼다는 것이었다. 이걸 모르고 안 넣었다가 조금 골치를 썩었다.

이 문제는 대부분이 비슷하게 푼 것 같다. db를 딕셔너리에 넣어서 푸시거나 for문에 아이디와 패스워드를 전부 가져와서 돌리시면서 비교하시거나, 그 중 유난히 다른 방식으로 푸신 분이 계셔서 가져와본다.

def solution(id_pw, db):
    if db_pw := dict(db).get(id_pw[0]):
        return "login" if db_pw == id_pw[1] else "wrong pw"
    return "fail"

다른 분들보다 코드가 훨씬 짧고 간결하긴 한데 이건 이해가 좀 심각히 많이 필요할 듯 싶었다. db를 딕셔너리로 넣은 건 알겠는데 := 가 뭐지? 에서 막혀버렸다.

:=을 찾던 중 자료형에 약한 내게 도움이 될만한 링크를 발견해 남긴다.
자료구조

:= 는 python3.8 부터 도입된 연산자라는데 바다코끼리 연산자라고 불리며 할당과 동시에 반환을 해주는 연산자라고 한다. 코드 가독성을 좋게 해주는 연산자라는데 dict(db).get(id_pw[0])의 값을 db_pw에 할당과 동시에 반환해주고 값이 존재하지 않는다면 None(False)가 반환되어 fail이 return 되고 값이 존재한다면 return 역시 삼항연산자를 이용해 조건이 일치하면 login을 하지 않으면 wrong pw를 반환해주는 코드였다.

코딩은 아는게 많을수록 좋은 코드를 짤 수 있다는 생각이 들었다.

계속 프로그래머스 문제는 풀 생각인데 개인적으로 자바 공부를 더 해야할 거 같아서 교재를 구매했다. 프로그래머스 문제를 처음 풀 때는 파이썬으로 풀고 이후에 자바로도 구현해보는 식으로 해볼까 생각 중인데 하다보니 자바와 내가 전혀 친하지 않다는 것을 깨달았다....

내가 스프링반 수업을 듣고 있음을 잊지 말자

profile
개발자의 길에 한 걸음 더
post-custom-banner

0개의 댓글