[프로그래머스] 124 나라의 숫자, 로또의 최고 순위와 최저 순위, 신고 결과 받기 (Python)

seulzzang·2022년 12월 16일
0

코딩테스트 연습

목록 보기
44/44
post-thumbnail

예전에 교육 시작한 지 얼마 안됐을 때 진행했던 코테 문제들이다. (한 4개월전에 풀었던 문제들)
해당 문제들을 다시 푸는 것이 오늘의 과제였기 때문에 이를 정리하고자 한다.

1. 124 나라의 숫자

  • 사실 이 문제를 처음 풀었을 때 강사님 풀이를 듣고도 이해를 못했는데 이제서야 이해한 듯 하다🥹
  • 기존의 3진법에서 3만 4로 대체를 하면 된다. 나머지가 0인 경우 3을 넣어준다.
  • 다만 3이 아닌 3의 배수인 경우 제대로 적용이 안된다. 기존 3진법을 계산하듯이 코드를 작성하게 되는 경우 발생하는 문제점이다.

이렇게 기존 3진법을 구하듯이 코드를 짜버리면

nums124 = ['4', '1', '2']
while n > 0:
        answer = nums124[n%3] + answer
        n //= 3

124나라의 법에 따르면 6은 14가 되어야 하지만, 24로 바뀐다.

  • 3대신 4가 들어와서 나머지가 1, 2, 3인데 기존 3진법은 나머지가 0, 1, 2이기 때문이다. 그래서 인덱스를 사용할 때 -1을 해줘야 한다.

💻나의 코드

def solution(n):
    answer = ''
    nums124 = ['4', '1', '2'] # 나머지가 0, 1, 2라고 생각해야함
    # 기존 3진법에서 3만 4로 대체
    
    while n > 0:
        answer = nums124[n%3] + answer
        # 3의 배수인 경우 체크
        if n%3 == 0:
            n = n//3 -1
        else:
            n //= 3
        
    return answer

2. 로또의 최고 순위와 최저 순위

  • 그때 당시 코딩을 시작한 지 1주일인가.. 그정도 됐을 때 인데.. 유일하게 풀었던 문제이다 ㅋㅋㅋㅋㅋㅋㅋ

  • 위 표를 따라서 {맞춘 개수: 순위}형식의 딕셔너리를 만들어준다.
  • 알아볼 수 없는 숫자를 0으로 표기하기 때문에, 최고 순위를 구할 때는 이를 맞췄다고 하여 max_num += 1을 해주고, 최저 순위를 구할 때는 min_num에 더해주지 않고 넘겨주면 된다.
  • 출력 형식에 맞게 answer에 답을 담아주기만 하면 끝

💻나의 코드

def solution(lottos, win_nums):
    answer = []
    # 로또 순위를 결정하는 방식
    # 맞춘 개수: 순위
    score = {
        '6': 1,
        '5': 2,
        '4': 3,
        '3': 4,
        '2': 5,
        '1': 6,
        '0': 6
    }
    max_num = 0 
    min_num = 0 
    
    # 최고 순위
    for lotto in lottos:
        if lotto in win_nums:
            max_num += 1
        elif lotto == 0:
            max_num += 1
    answer.append(score[str(max_num)])
    
    # 최저 순위
    for lotto in lottos:
        if lotto in win_nums:
            min_num += 1
        elif lotto == 0:
            continue
            
    answer.append(score[str(min_num)])
        
    return answer

3. 신고 결과 받기

  • 그때 제일 어려웠던 문제이다. 124나라의 숫자는 3진법 비슷한거구나 라고 감이라도 잡았는데 이건 뭐 아무생각도 안나서 걍 포기했었음(자랑은 아니지만ㅠ)

  • 문제 설명에 따르면 신고 횟수에 대한 제한은 없지만, 동일한 유저에 대한 신고 횟수는 1회로 처리된다. 따라서 {신고 당한사람: 신고한 사람}이런 형태의 딕셔너리를 만들 때, 신고한 사람은 중복을 제거해주기 위해 set()자료형을 사용한다.
  • 또한 메일을 받는 유저의 정보도 필요하므로, 이를 {신고한 사람: 받는 메일수}형태의 딕셔너리로 생성해준다.
  • k번 이상 신고된 유저는 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.이므로 {신고 당한사람: 신고한 사람}의 딕셔너리에서 벨류값의 길이가 k이상이면 {신고한 사람: 받는 메일수}의 딕셔너리에 메일의 개수를 추가해준다.
  • 이후 출력에 맞게 받은 메일 수를 answer에 추가해주면 끝이다.

💻나의 코드

def solution(id_list, report, k):
    answer = []

    info = {}
    # 동일한 유저에 대한 신고 횟수는 1회로 처리되므로 중복적용 x
    for user_id in id_list:
        info[user_id] = set()
    
    for r in report:
        # 신고한 사람, 신고를 당한 사람
        singo, singoed = r.split()
        # 신고당한 사람: 신고한 사람
        info[singoed].add(singo)

    mail = {}
    # 만약에 내가 신고한 유저가 k번 이상 신고를 받았으면, 메일을 받는다
    # mail을 받는 횟수를 +=1 해주는 부분
    for user_id in id_list:
        mail[user_id] = 0
    # 유저가 받는 메일 수를 계산
    for singoed in info:
        # k번 이상 신고를 당했으면
        if len(info[singoed]) >= k:
            # mail[ap, mu..] += 1
            for singo in info[singoed]:
                mail[singo] += 1
    # print(mail)
    for cnt in mail.values():
        answer.append(cnt)
    return answer

이제와서 보니까 124나라의 숫자보다도 얘가 더 쉬운 것 같다.. 그냥 문제 설명에 따라 구현을 하면 되는 문제이기 때문이다. 아마 내가 알기론 124나라의 숫자만 레벨2고 나머지가 레벨1인데, 레벨1인 이유가 있었음.. 물론 그걸 차치하더라도 카카오코테는 문제 해석 시간이 오래걸리고 어렵다😅


옛날 문제 푸니까 코딩 처음 시작했을 때 생각도 나고 좋았다(사실 좋진 않다) 요새 푸는 문제들에 비하면 쉬운건 맞지만 지금도 막 그렇게 쉽냐고 물어보면 쉽다고 답 못할 것 같다 ㅋㅋ

profile
중요한 것은 꺾이지 않는 마음

0개의 댓글