코딩: 말하기 듣기 쓰기-6

정렬을 주제로한 알고리즘 연습

이번주의 주제는 정렬이였다. 그래서 정렬을 주제로 프로그래머스에서 두문제를 푸는 것이 시험이였다. 역시나, 쉬운문제라 생각하고 급하게 미친듯이 풀었지만, 항상 1문제만 맞는다. 3주동안 목요일에 2문제씩 문제가 선정되어서 푸는데, 항상 1문제 맞을까말까이다. 쉽지않다. 아무튼, 맞든, 안맞든 오늘 굉장히 쉬우면서도 기본적으로 알아야할 문제로 가득하다. 그래서 정리를 깔끔하게 해볼까한다. 우선 첫번째문제 시작!

H-Index

https://programmers.co.kr/learn/courses/30/lessons/42747

H-Index 가 생각보다 간단한 것을 깨닫게 해준 문제이긴하지만, 사실 좀더 복잡하긴한데...흠..연구소에 있을때 저거 많이봐서 어느정도 아는 개념이긴하다. 아무튼 정렬문제는 구현이 귀찮고 어렵지 사실 왠만하면 내장함수를 쓰면 되는 것 같다. 그리고 이번 문제는 다른건 몰라도, 확실히 그냥 문제에 나와있는대로 그대로 코드로 직역하면 되는 문제들인 것 같다.

def solution(citations):
    answer = 0
    citations.sort()
    n = len(citations)
    
    for i in range(n):
        h_index = n-i
        if citations[i] >= h_index:
            answer = h_index
            break
    return answer

나는 이런문제들이 너무좋다. 깔끔하다. 그냥 내장함수 쓰면되니까. BFS, DFS문제보다 깔끔하고 쉽다. 하지만, 이런문제는 잘 안나올것이다. 내가 쉽다고 생각하는건 절대 안나올걸~~~
이 문제의 포인트는:
1. if citations[i] >= h_index
h번 이상 나온 논문이 h편 이상이라는 문제에 쓰여진 것을, 그대로 코드로 작성한것이다.
2. for문에서 i는 논문이 인용된 횟수이고, h_index는 최댓값부터 하나씩 줄여나간것이다 -> 최댓값을 찾아야 하므로, 최댓값부터 빼줘야한다.
3. 오름차순으로 미리 정렬시켜놨기때문에 if문에 만족하는 순간 최댓값이 될것이다.
이 문제는 단순히 우선 하라는대로 코드를 짜고나서, 살짝 if문 써주면서 변형시키면 되는 문제라 생각이든다. 그런데 힘들게힘들게 풀었다...

파일명 정렬

이 문제는 보자마자 드는 생각이 미니/토이 프로젝트할때가 생각이 났다. 파일명 정렬해서 페이지에 보일때, 정렬되서 보이는 형태로 보이기위해서 자바스크립트 언어로 요리조리 구글링하면서 했던 기억이 난다. 그럴때 했던 방법중 하나가, 파일명을 보면, 뒤에 .jpg, .img, .svg 등등 다양한 형태가 있는데 이를 오름차순으로 정렬했던 기억이 난다. 아무튼. 이문제 해설을 보면 이해가 안갔다. 다행히, 글을 읽다가 바로 example로 내려가서 이해하려고 애를 썼더니 보였다.

https://programmers.co.kr/learn/courses/30/lessons/17686

이문제도 마찬가지로 문제에서 하라는대로 코드를 짜면되긴하는데...나는 틀렸다..하라는대로 하긴했는데...너무 무지성으로 코드를 짜지않았나싶다. 아무튼 파일의 구조를 보면 HEAD, NUMBER, TAIL이렇게 나와있다. 이것을 바탕으로 코딩을 하면되지만....풀어도풀어도 나는 되지않았다. 우선 접근법에서는 맞았다. 세가지로 구조를 나누어서 각각 해당하는 조건대로 푸는것. 하지만 마무리가 되지않았다. Head는 사전순, Number는 숫자순으로 정렬해주는것. 이것을 쉽게 하기위해서는 당연히 sort함수를 써야하지만 거기에 더해서 간단한 람다식을 써야 한다. 내가 그것을 어떻게 생각을할까...이머리에... 많이 풀다보면 익숙해지겠지..일단 믿어보고 일단 머리에 넣는다. 일단해본다.

https://brightnightsky77.tistory.com/416

def solution(files):
    # 정렬이 된 파일명들을 저장할 리스트 변수를 선언합니다.
    answer = []
    # 파일들의 개수인 files의 길이를 저장하는 변수를 선언합니다
    files_len = len(files)

    # files에 있는 각 파일마다 반복한다.
    for idx in range(files_len):
        # 현재 파일의 Head부분을 저장할 변수를 선언한다.
        head = ''
        # 현재 파일의 number부분을 저장할 변수를 선언합니다.
        number = ''
        # 현재 파일의 이름을 한 문자씩 읽다가 숫자 부분을 읽기 시작했을 때 감지하는 변수를 선언합니다.
        is_number = False

        # 현재 파일에서 한 문자씩 반복해봅니다.
        for char in files[idx]:
            # 현재 문자가 숫자 형태의 문자라면
            if ord('0') <= ord(char) <= ord('9'):
                # is_number의 값을 True로 변경합니다.
                is_number = True
                # number에 현재 문자를 넣어줍니다.
                number += char
            # 파일명에서 아직 Number부분을 읽기 시작하지 않아 Head부분을 읽어야 한다면
            elif not is_number:
                # head에 현재 문자를 넣어준다.
                head += char
            # is_number가 True라면 파일명에서 Head와 Number부분을 변수에 다 저장한 상태이므로
            elif is_number:
                # 더 이상 파일명을 읽을 필요가 없으니 반복문을 탈출한다.
                break
        # Head는 대소문자를 가리지 않으므로 head의 값을 소문자로 변경합니다.
        head = head.lower()
        # Number 부분을 실제 숫자 기준으로 정렬해야하므로 정수형으로 변환합니다.
        number = int(number)
        # files에서의 현재 파일명 값을 (현재 파일명, Head, Number)의 튜플 형식으로 변경해줍니다.
        files[idx] = (files[idx], head, number)

    # 문제에서 제공한 기준의 우선 Head는 사전순, 다음으로 Number는 숫자순으로 정렬해준다.
    files.sort(key=lambda file: (file[1], file[2]))
    # 정렬된 상태에서 파일명들만 그대로 answer에 저장해준다.
    answer = [file[0] for file in files]
    # 정렬된 파일명 리스트 변수인 answer를 반환해준다.
    return answer

files = ["img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"]
print(solution(files))

구글링해서 이 분이 정말 자세하게 주석을 달고 코드를 짜셔서 이해가 잘 되어서 이것을 보았다. 우선 내 생각대로 Head, Number, Tail 이렇게 세 부분으로 나누었고. 그다음에 람다식으로 마무리. 전반적으로 내가 부족한것을 보면 전체적인 그림을 보고 그 안에 세세하게 디테일을 짜주는 것이였다. 지금 나의 레벨에서 문제푸는것에 급급해서 그림을 다 그리지않은채 바로 코딩을 시작하다보니까 틀리는것같다. 그리고 파이썬 문법이 많이 부족해서 그런것같기도하고...우선 풀자.

좋은 웹페이지 즐겨찾기