[알고리즘] 각도기, 옷가게 할인, 369, 로그인 문제

조성현·2022년 11월 16일
0

Progammers의 0단계 알고리즘 문제를 풀었다.

  1. 각도기 문제 (링크)
  2. 옷가게 할인 받기 문제 (링크)
  3. 369 게임 문제 (링크)
  4. 로그인 성공? 문제 (링크)

1~3번 문제는 큰 어려움 없이 풀었기에 아래에 부족하나마 답변 코드를 넣어두고,
빨리 풀기는 풀었으나 코드의 메커니즘이 만족스럽지 않아 두번 수정한 4번 문제를 먼저 자세히 기술하고자 한다.


프로그래머스 - 로그인 성공? 문제 - 풀이과정


1. 먼저 생각나는대로 코드를 작성했다.
(시간제한을 둔 코딩테스트 방식으로 진행되어 테스트 통과 코드작성을 우선순위에 두었다.)

def solution(id_pw, db):
    answer = ''
    db_id_list = []
    for i in range(len(db)):
        db_id_list.append(db[i][0])
    
    for i in range(len(db)):
        if id_pw[0] not in db_id_list:
            answer = "fail"
            
        elif id_pw[0] == db[i][0] and id_pw[1] != db[i][1]:
            answer = "wrong pw"
            
        elif id_pw[0] == db[i][0] and id_pw[1] == db[i][1]:
            answer = "login"
            
    return answer

2. 테스트 통과 후 내가 작성한 코드를 돌아보며 개선해야 될 부분들을 체크했다.

  • for 문을 두번이나 돌리는 구조
  • 기껏 for문을 돌려서 db_id_list에 id값만 저장해두고, pw검증에는 또 db와 비교하는 구조
  • db에서 id가 일치하는 값을 가져오고, 가져온 값에서 pw를 비교하고 싶었다.
    (db에 자꾸 접근하는게 비효율적이라 생각했다.)

개선사항에 대한 생각을 정리한 뒤 다른 사람들의 답변을 보며, 다른 개선방식도 있을까를 고민해봤다.

  • 그 과정에서 바다코끼리 연산자(walrus operator)에 대해 알게 되었다. (링크)
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"

3. 1차적으로 코드를 개선했다.

  • for문을 1번만 돌리도록 개선하고,
  • db에서 id값이 일치하는 데이터를 id_pw_checklist에 담아 pw 검증에 사용했다.
def solution(id_pw, db):
    answer = "fail"
    id_pw_checklist = []

    for i in range(len(db)):
        if id_pw[0] == db[i][0]:
            id_pw_checklist = db[i]      
            
    if len(id_pw_checklist) == 2:
        if id_pw[1] == id_pw_checklist[1]:
            answer = "login"
        else:
            answer = "wrong pw"

    return answer

4. 벨로그에 글을 쓰다가 2차적으로 코드를 개선했다.

  • 굳이 list에 따로 값을 빼두는 것이 공간도 차지하고, 보안에서도 문제 될 여지가 있지 않을까라는 생각이 들었다.
  • 처음 작성했던 코드와 비교해보니 코드 길이도 줄고, 불필요한 작업도 많이 줄인 것 같다.
    (아직 개선의 여지가 차고 넘치는 코드지만, 현재 시점에서는 이정도면 최선!)

리팩토링을 왜 해야 하는지, 어떻게 하는지를 부족하지만 경험해본 좋은 과정이었다.

def solution(id_pw, db):
    answer = "fail"

    for i in range(len(db)):
        if id_pw[0] == db[i][0]:
            if id_pw[1] == db[i][1]:
                answer = "login"
            else:
                answer = "wrong pw"

    return answer

++ 3번 과정에서 db의 값을 id_pw_checklist에 담는 것이 보안상 위험하지는 않을까? 하는 궁금증이 있어 튜터님께 질문을 드렸다.

  • 'db connection pool'이라는 키워드를 공부해보라는 말씀과
  • db의 데이터 자체가 '1234'라는 pw 값을 저장하는 것이 아니라 암호화된 값으로 저장한다는 점을 알려주셨다.
  • 책도 추천해주셨다. [ 1. 생활보안 첫걸음(링크), 2. 웹개발자를 위한 웹보안(링크)]

1~3 문제의 답변들

  1. 각도기 문제 (링크)
 def solution(angle):
    answer = 0
    
    if angle < 90:
        answer = 1
    elif angle == 90:
        answer = 2
    elif angle < 180:
        answer = 3
    else:
        answer = 4
        
    return answer
  1. 옷가게 할인 받기 문제 (링크)
 import math
 
 def solution(price):
   	answer = 0
    
   	if price < 100000:
   	    answer = price
  	elif price < 300000:
   	    answer = math.trunc(price*0.95)
   	elif price < 500000:
   	    answer = math.trunc(price*0.9)
   	else:
   	    answer = math.trunc(price*0.8)	
        
   	return answer
  1. 369 게임 문제 (링크)
def solution(order):
    num_list = list(map(int, str(order)))
    answer = 0
    
    for num in num_list:
        if num % 3 == 0 and num != 0:
            answer += 1
            
    return answer
profile
맛있는 음식과 여행을 좋아하는 당당한 뚱땡이

2개의 댓글

comment-user-thumbnail
2022년 11월 17일

저도 풀고 성현님과 비교해보겠습니다!

1개의 답글