ASAC 빅데이터 분석가 7기/ASAC 일일 기록

ASAC 빅데이터 분석가 과정 7일차 - 1 (24.12.12)

junslee 2024. 12. 12. 10:05

04_cotest

10_자료형_신고결과문제

# 이전 내용 요약

 

# 문제

- 1인이 다른 사람을 여러번 신고 가능하다.
  but, 동일한 사람을 여러 번 신고해도 1번 신고로 간주한다
- 1인이 여러 다른 사람들에 대한 다양한 신고는 가능하다.

- k번 신고 당한 사람은 정지한다.(가변적인 값으로)
   ==> 정지 당한 사람을 신고한 유저한테 알림메일을 전송한다.
  ( 중간 중간 처리 X --> 신고 다 받고 나중에 한 번에 처리한다.)


# 문제 조건

id_list : 리스트로 들어 온다 [ 이용자들 ]
           --> 개별 id : 영문소문자, 중복X, 1~10글자, 원소2~원소1000
report : 리스트로 들어 온다 [ 이용자들 사이 신고내역들 ]
            --> "신고id 신고당한id" : 3~21 & 공백1칸
            --> 20만개
            --> 자기 자신 신고같은 이상한 케이스는 없다
k : 밴 기준값 (2~100)


# 세팅

===> Dict으로 세팅
        1) key : 신고 당한 사람들을 기준으로 세팅한다.
        2) value : 나를 신고한 사람들(여러명) --> 신고한 사람들을 적어둔다[ ]
        ---> 주어진 k값을 기준으로 value에 길이, 갯수 기록 - BlackList로 선정된다.
역으로 BlackList에서 신고한 사람들(value)은 순서에 맞춰서 +1씩 카운팅한다.


# 큰 틀에서 해결 방법

  • 1) 문제 세팅
    --> 주어진 입력에 대해서 정보 처리 : Dict(k:신고당한사람, v:신고한사람"들")
    --> Dict를 초기화 { }
         신규신고당한 사람 vs 기신고당한사람 : 구분하기 위해서
          id_list를 보고
          d ={"muzi":[], "frodo":[], "apeach":[], "neo":[]}
          ===> 나중에 문제 발생!
  • 2) 입력 report 보면서 신고 접수 결과 정리 : Dict
         ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
         - "muzi frodo" : .split[0] : 신고한 사람 (v-->append)
                                  .split[1] : 신고당한 사람 (k)
         d ={"muzi":[], "frodo":["muzi"], "apeach":[], "neo":[]}
          - "apeach frodo"
         d ={"muzi":[], "frodo":["muzi","apeach"], "apeach":[], "neo":[]}
         - "frodo neo"
         d ={"muzi":[], "frodo":["muzi","apeach"], "apeach":[], "neo":["frodo"]}
          - "muzi neo"
         d ={"muzi":[], "frodo":["muzi","apeach"], "apeach":[], "neo":["frodo","muzi"]}
          - "apeach muzi"
         d ={"muzi":["apeach"], "frodo":["muzi","apeach"], "apeach":[], "neo":["frodo","muzi"]}
  • 3) 시스템적으로 k=2이상 신고당한 사람들을 필터링
    d의 value를 보면서 원소의 갯수가 2개 이상인 key를 리스트업한다.
    ==> BlackList 선정
    BL = ["frodo","neo"]
  • 4) 역으로 BL를 돌아가면서 신고한 사람들을 찾아가서 +1 카운팅
         d에서 key를 찾아서 --> 그 key에 해당하는 value(리스트)
                                         --> 신고한 사람들을 돌아가면서 +1 카운팅
         ===> BL = ["frodo","neo"]
         d ={"muzi":["apeach"], "frodo":["muzi","apeach"], "apeach":[], "neo":["frodo","muzi"]}
         answer = [0,0,0,0] # ["muzi", "frodo", "apeach", "neo"]
         : d["frodo"]     // ["muzi","apeach"]
                         answer에서 muzi 위치 찾아서 +1갱신     [0+1,0,0,0]
                         answer에서 apeach 위치 찾아서 +1갱신 [0+1,0,0+1,0]
         : d["neo"]       //["frodo","muzi"]
                  answer에서 frodo위치 찾아서 +1갱신             [0+1,0+1,0+1,0]
                  answer에서 muzi위치 찾아서 +1갱신              [0+1+1,0+1,0+1,0]
    끝!!
     [0+1+1,0+1,0+1,0] = [2,1,1,0]

# 위의 방법대로 하면)

["ryan con", "ryan con", "ryan con", "ryan con"]
d= {"ryan":[],"con":[]}
--> d = {"ryan":[], "con":["ryan","ryan","ryan","ryan"]}
!! con의 value의 원소 수 4가 되어서 BL 
===> BL이 아닌데 BL로 판정되어 오답

이유 : ["ryan","ryan","ryan","ryan"] ==> ["ryan"]
           ==> set의 자료형으로 왔다 갔다
sol1) d= {"ryan":set([]),"con":set([])} --> append를 add 코드로 수정한다.
sol2) report의 원소를 유니크하게 : set


# 위의 방식으로 하면 2번 케이스는 실패하므로 해결 방법

def solution(id_list, report, k):
    #answer = []
    # 0. ==> 출력의 용이성을 위해서 answer = [0,0,0,,,,,,,0] 유저에 맞춰서 세팅
    answer = [0]*len(id_list)

    # 1. 신고 내역에 대한 정보 처리 세팅
    # ==> k:신고 당한 사람, v : 신고한 사람들[]
    #     이 시스템 모든 유저 id_list에 대한 것을 key 초기화!!
    #     d= {"muzi":[], "prodo":[],,,}
    reported_dict = {}
    for id in id_list:
        reported_dict[id] = []     # --->????? 나를 신고한 사람들 적어두자.

    # 2. 신고 내역에 대한 정보 처리 : report
    # --> [ "A B",,,,,]
    for report_pair in report: # ---> ???? set 중복신고 결과 유니크
        # 신고 내역 1건별로 처리할 규칙
        # "A B" --> "A":신고자(v)추가, "B":신고당한사람(k)
        reporter = report_pair.split(" ")[0] # "A"
        reported = report_pair.split(" ")[1] # "B"
        # --> reporter, reported = report_pair.split(" ")
        # ===> 나의 자료 정리에 추가!!!!
        reported_dict[reported].append(reporter) # ---> ???add로
    # ==> 신고 내역 정리 끝!!!!!

    # 3) 시스템 기준으로 k 이상 신고 당한 BL들을 필터링!!!
    # ===> reported_dict의 value의 원소의 갯수 >= k
    #      ["prodo","neo"]
    # ===> 금지당한 여러명 사용자일 수 있으니 리스트업!!!!
    #      : BL는 정리한 내역의 k, 필터링의 조건 : v : .items()
    k_reported = []
    for key_id, v in reported_dict.items():
        if len(v) >=k:
            k_reported.append(key_id)
    # ===> LC
    # k_reported = [key_id  for key_id, v in reported_dict.items() if len(v) >=k]

    # 4) 최종적으로 신고한 사람들한테 메일 발송 --> 카운팅!!!
    # ==> 정지당한 리스트들을 돌려가면서,,,
    # d[BL] : value에 신고한 사람들
    #       ---> 돌아가면서,,,카운팅!!! ansWER
    for ban_id in k_reported:
        # 정지먹은 id를 신고한 사람들을 :frodo
        mail_res_ids = reported_dict[ban_id] #  ["muzi"," apeach"]
        # 신고한 id들을 돌려가면서 메일 발송 : +1 갱신 카운팅
        for id in mail_res_ids:
            id_index = id_list.index(id)
            answer[id_index] += 1
    #####
    return answer

# test1

a = ["muzi", "frodo", "apeach", "neo"]
b = ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
c = 2
solution(a,b,c) # [2,1,1,0]
[2, 1, 1, 0]

 

# test2

a = ["con", "ryan"]
b = ["ryan con", "ryan con", "ryan con", "ryan con"]
c = 3 # [0,0]
solution(a,b,c)
[0, 4]

???? 설명이나 이유들을 잘 찾아봐야 한다!!
==> 같은 신고 내역에 대한 중복 처리를 놓쳤다!!!!
       sol1) v --> set
       sol2) report --> set

 

def solution(id_list, report, k):
    answer = [0]*len(id_list)
    reported_dict = {}
    for id in id_list:
        reported_dict[id] = [] # --->????? 나를 신고한 사람들 적어두자.
    for report_pair in report: # ---> ???? set 중복신고 결과 유니크
        reporter = report_pair.split(" ")[0] # "A"
        reported = report_pair.split(" ")[1] # "B"
        reported_dict[reported].append(reporter) # ---> ???add로
    k_reported = []
    for key_id, v in reported_dict.items():
        if len(v) >=k:
            k_reported.append(key_id)
    for ban_id in k_reported:
        mail_res_ids = reported_dict[ban_id] #  ["muzi"," apeach"]
        for id in mail_res_ids:
            id_index = id_list.index(id)
            answer[id_index] += 1
    return answer

# ==> 수정

def solution(id_list, report, k):
    answer = [0]*len(id_list)
    reported_dict = {}
    for id in id_list:
        reported_dict[id] = set([]) # *******
    for report_pair in report: # ---> ???? set 중복신고 결과 유니크
        reporter = report_pair.split(" ")[0] # "A"
        reported = report_pair.split(" ")[1] # "B"
        reported_dict[reported].add(reporter) # *******
    k_reported = []
    for key_id, v in reported_dict.items():
        if len(v) >=k:
            k_reported.append(key_id)
    for ban_id in k_reported:
        mail_res_ids = reported_dict[ban_id] #  ["muzi"," apeach"]
        for id in mail_res_ids:
            id_index = id_list.index(id)
            answer[id_index] += 1
    return answer

# test1

a = ["muzi", "frodo", "apeach", "neo"]
b = ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
c = 2
solution(a,b,c) # [2,1,1,0]
[2, 1, 1, 0]

 

# test2

a = ["con", "ryan"]
b = ["ryan con", "ryan con", "ryan con", "ryan con"]
c = 3 # [0,0]
solution(a,b,c)
[0, 0]

# ==> 수정

def solution(id_list, report, k):
    answer = [0]*len(id_list)
    reported_dict = {id:set([]) for id in id_list}
    for report_pair in report: # ---> ???? set 중복신고 결과 유니크
        reporter, reported = report_pair.split(" ")
        reported_dict[reported].add(reporter) # *******
    k_reported = [key_id for key_id, v in reported_dict.items() if len(v) >=k]
    for ban_id in k_reported:
        mail_res_ids = reported_dict[ban_id] #  ["muzi"," apeach"]
        for id in mail_res_ids:
            id_index = id_list.index(id)
            answer[id_index] += 1
    return answer

다 하시고 나서
---> 본인 풀이 끝
---> 본인 풀이 정리!!!!!

---> 다른 사람의 풀이는 뭐지!!!!
---> 괜찮은 풀이가 있다면 체크!!!!!
---> 내것  vs 다른 괜찮은 풀이 : 뭐가 어떤지 판단!!!

+++ 문제를 조금 수정하면서,,어떻게 출제할까!!!
=================>
안 보고 다시 할 수 있을 정도로,,,,반복 & 훈련!!!!!!


11_구현_카카오2022_주차요금

주차요금 문제
ref : https://school.programmers.co.kr/learn/courses/30/lessons/92341?language=python3
2022년도 문제 : 여러 경우에 대해서 꼼꼼하게,,
              ==> 주어진 시간 내에서 코드를 꼼꼼하게 빨리 완성!!!

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


# 문제를 체크

- 요금표의 구성 : 기본 요금/시간 + 추가요금/시간
                     ==> case by case
- 입출에 대한 기록 : 출력의 기준인 차량별로 작성된정보가 아니라
                     이벤트 중심으로 찍힌 로그들...
                     ==> 차량별로 정리를 해야할 것 같음!!!
                     [ why:출력을 차량 중심으로 하라고 해서...]
                     ==> 이벤트발생시간(시:분), 차량번호, 상태(입/출)



# 주의사항 

Step1) 로그 기록을 차량별로 머문 시간 정리에 있어서 주의할 사항!
0000차량의 예를 보니 : 입차는 있는데, 출차가 없는 경우 처리한다
                                      시간 처리 단위(분으로 통일해서 처리)
                                      ++ 일괄 정산이니 이용누적시간으로 처리한다

 

--> 요금 정산 : 중간 정산이 아니라 "일괄정산" (누적시간이 기준)
                      :기준 : 그날의 누적 이용 시간
                      c1) 누적 시간 <= 기본 이용 시간 : 기본 요금
                      c2) 누적 시간 >  기본 이용 시간 :
                                               : 기본 요금 + 추가요금
                                                                (기본 시간기준 )
                       c2-1) 나눠 떨어지는지   :  그냥 몫*추가요금
                                490분/10분==> 49
                                49*600 = 29400
                                5000+ 49*600=34400
                       c2-2) 나눠 안 떨어지는지   :  (올림) * 추가요금
                                154분 /10분 --> 15.4
                                (올림)16 * 600 = 9600
                                5000+9600= 14600


# 예제1) 

0000 : 출차 기록이 없는 경우 // 기본시간초과// 추가요금계산 시 나머지 0 아닐 때 ==> 올림
0148 : 출차 기록이 있는 경우 // 기본시간초과// 추가요금계산 시 나머지 0 --> 그냥 계산
5961 : 출차 기록이 있는 경우 // 기본시간이내// X

     [ 누적시간에 계산:출차]    [추가요금발생여부]    [추가요금 계산시 올림여부]


# 출력 주의사항

1. 자동차 번호가 작은 순서대로(값, 오름차순) : 정렬
2. 1번 순서대로 요금만 리스트로 출력한다
   : 자동차 번호는 출력대상이 X, only 요금만 (순서는 차량 번호)


# 제한 사항

- fees : 요금 관련 정보
         : 정수/리스트
         : 길이 4
         : 정보의 순서 [ 기본시간(분), 기본요금, 단위시간(분),단위요금]
         : 참고) 숫자가 커도 연산으로 사용하고 --> 효율성에 영향 X?
- records : 입출기록
         : 1대는 무조건 들어가고, 최대 1000건의 이벤트
         : 1개 원소 구성 "HH:MM XXXX(차량번호) YY(이벤트IN/OUT)"
         : 원소의 순서는 시간 순
         : 0분 이용 내역은 고민하지 말자!(입출시간이 동일 or 입 23:59 X)
         : 앞에서 이야기를 한 이상한 케이스 말고는 고민하지 말자


# 예시2) 요금 처리에 있어서 기준값을 잘 처리하기!

==> 기본 시간 120분에 딱 걸리면 : 기본 요금 처리(이하)
==> 기본 시간에 +1분이라도 넘어가면 : 추가요금
+++ 입차기록은 있는데,,출차 기록이 없는 예외 처리 잘 해



# 예시3) 요금 처리에 있어서 00:00에 오는 특이 케이스(제일 앞)

--> 입차 기록은 있는데,,,출차 기록이 없는 경우 꼭 하세요!
==> 시간 기록 00:00~~23:59 범위 내에서만 처리!

 

주어진 정들을 처리할 자료형 / 세팅 : Dict
==> key : 차량 번호
==> value : 차량에 대한 입출기록"들" --> []


입력에 대한 정보 처리) HH:MM ---> 처리 기준 (분)
==> 여러 기록마다 필요하므로 함수로 만들어 하겠다!!!!
        00:00~23:59
        0분~23*60+59 분( 0분~1439분)
"06:00 0000 IN"    // 06:00 0000차량 입차
 ---> (6*60, 입차)
"06:34 0000 OUT" // 06:34 0000차량 출차
 ---> (6*60+34, 출차)
=====>6*60+34 - 6*60 = 34분 이용시간

"18:59 0000 IN" // 18:59 0000차량 입차
----> (18*60+59, 입차)
========================================
++++ 출차 기록을 추가!!!!
++++ (1439, 출차)
===> 1439 - (18*60 + 59) = 300분

0000차량 기록 : [(360, 입차), (394,출차),(1139,입차) ] ++ (1439,출차)
==> 출차 기록 처리 : 그 차량의 로그 기록이 홀수 --> (1439,출차)추가
                                           짝수 --> X

==> 누적 시간 계산 : ( 출차 시간의 총합)   -   (입차 시간의 총합)
                                         짝수에 위치                  홀수에 위치
       단, 출차 기록이 없으면 생성하고 해야한다

 


# 참고사항 : 올림에 대한 부분

146/10 ===> 14.6 ---> 15
140 /10 --> 14   ---> 14

i = 141
if i % 10 ==0:
    print(i//10)
else:
    print( (i//10)+1)
15

 

//파이썬의 math : 기본 패키지 ---> 올림해줘 함수


# skill) 지식적인 부분 ==> 음수의 나눈셈을 활용하는 방법

===> 이런 스킬은 종종 사용되는 방식임!!! 배경지식으로 알아 두시면,,,

i = 141
-(int(-i //10))     # -14.6 ===> -15 ---> 15
15

# 참고) "05:34" --> 시간, 분으로 분리

"05:34".split(":")
['05', '34']

 


# 시간 변환 함수

입력 : HH:MM 5글자 문자열
할일 : 입력HH:MM을 00:00기준으로 몇 분이 지났는지 분으로 계산한 값
          HH*60 + MM
출력 : 00:00기준으로 지나간 분.....

def convert_h_to_m(time_HHMM):
    h_part, m_part = time_HHMM.split(":") # "05:34"-->["05","34"]
    total_min = int(h_part) * 60 + int(m_part) # 나중에 산수+/- 정수로 변환
    return total_min
convert_h_to_m("05:34")
334
convert_h_to_m("00:00")
0
convert_h_to_m("23:59")
1439

//본인 스타일로 직접 해보기!!


def solution(fees, records):
    answer = []
    ###########
    # 1) fees의 요금 관련 정보 처리 : 기본시간/기본요금/기준시간/기준요금
    # ==> 정수/리스트 : 멀티 할당 : 변수화!!! : 생략하고 나중에 인덱스로 사용해도 됨!!!
    base_time, base_cost, add_time, add_cost = fees
    # ==> 참고) 안 해도 나중에 fees[0], fees[1], fees[2], fees[3]


    # 2) 주차로그기록에 대한 정보 처리!!!! ==> 마라톤 // 신고자 유사!!!
    # ==> Dict를 자료형으로 처리하자!!(개취!)
    #     key : 자동차 번호 ---> 오름차순,,,
    #     value : 차량 입출정보"들" [] , (HH:MM을 00:00기준 분 환산, 상태)
    # ==> 기존에 키로 등록된 차인지 ., 아닌지에 따라서 처리가 다름!!!
    #     예) {5961:[(5*60+34, IN)]}
    #         { 5961:[(5*60+34, IN)], 0000:[(6*60, IN)]}
    #         { 5961:[(5*60+34, IN)], 0000:[(6*60, IN), (6*60+34, OUT)]}
    # ...... 이런 식으로 출입 기록을 정리하려고 함!!!
    park_dict = {}
    # 입력에 대한 주차 로그 기록지를 보면서 정리!!!!
    for record in records: # ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT",,,]
        # 2-1) 1개 로그 기록을 처리 : 시간, 차번호, 상태 ==> 공백
        park_time, car_id, status = record.split(" ")
        # "05:34 5961 IN" ---> ["05:34", "5964", "IN" ]
        # 2-2) 정리의 기준 차 번호 : key --> "0000" --> int --->0
        car_id = int(car_id) # "0000"---> 0
        # 2-3) 정리를 차 번호 기준에 맞춰 상태 정로 : value
        # (00:00기준분, 상태) ---> ["05:34","IN"]-->함수 -->[5*60+34, "OUT"]
        car_record = [convert_h_to_m(park_time), status ] #--> value추가
        # 2-4) 실제 등록 처리!!!!
        # case1) 이미 등록된 차 번호
        if car_id in park_dict:
            park_dict[car_id].append( car_record) # [334,"OUT"]
            # {0:[ [300,"IN"]] } ---> {0:[ [300,"IN"], [334,"OUT"] ]}
        # case2) 신규 등록할 차 번호
        else:
            # {0:[ [300,"IN"] ]}
            park_dict[car_id] = [car_record] #**** 형 주의!!!!
            # 처음 등록하면서 value의 자료형을 list , 개별원소(시간,상태 리스트로)
    # ----> 받은 입출기록을 정리!!!!

    # 3) 누적시간 + 비용을 계산!!!!!
    # ===> 계산용으로 dict( key: 차번, value: 누적요금) : 출력에도 사용
    # check1) 출차 정보 처리 : +++ 출차 정보가 없으면 추가(23:59)
    # chekc2) 누적 시간 계산
    #         2-1) 기본 요금 이하
    #         2-2) 기본 요금 초과
    #               2-2-1) 초과 시간이 나눠 떨어질 때 : 몫 그대로 사용
    #               2-2-2) 초과 시간이 나눠 안 떨어질 떄 : 몫+1
    car_dict = {} # k : 차번호, v:누적 요금
    # 차별로 주차 기록을 바탕으로 누적시간 & 요금....
    for car, logs in park_dict.items(): # k, v
        # 개별 차량의 기록들을 기준으로....
        # car : 0
        # logs = [  [300,"IN"], [ 334,"OUT"], [1139,"IN"] ]
        # ---> IN : [300, 1139]
        # ---> OUT : [334] + [1439]
        out_time_list = [ m for m,sta in logs if sta=="OUT"] # [334]
        in_time_list  = [ m for m,sta in logs if sta=="IN"]  # [300, 1139]
        # 들어는 왔는데,,나간 정보가 없는 차량에 대해서 예외 처리!!: logs 홀수개/짝수개
        if len(logs) % 2 == 1: # --> OUT이 없는 친구
            out_time_list.append( convert_h_to_m("23:59")) # 1439
        # ===> in/out의 갯수가 딱 맞게 됨!!!
        # out = [ 334, 1439], in=[300, 1139]

        # 차량별로 누적 시간 계산 : 분
        total_min = sum(out_time_list) - sum(in_time_list)
        # (334+1439) - ( 300+ 1139) = (334-300) + (1439-1139)

        # 요금 계산을 수행!!!
        if total_min <= base_time: # fees[0]
            # 기본 시간 이내 누적 주차 시간 : 기본 요금
            car_dict[car] = base_cost # fees[1]
        else: # 추가 요금이 발생하는 경우,,,,
            # 추가 시간이 나눠 떨어지냐/ 아니냐 case by case
            cost = 0
            cost += base_cost
            total_min -= base_time # 누적시간 = 기존누적시간 - 기본시간
            # ---> 추가 요금을 계산!!!  나눴을 때 떨거지 있냐...
            # ==> 올림에 대한 trick : 음수 활용--> 직접 구현해도 됨..
            over_time_base =  -(total_min * (-1) // add_time)
            cost += over_time_base * add_cost
            # 최종 추가 요금까지 정산을 했으니,,,기록
            car_dict[car] = cost
    # ----> 롤링 : 차 번호의 유니크한 갯수!!!!
    # car_dict = {0:14600, 148:34400, 5961:5000}

    # 4) 최종 제출 답안지를 작성!!!
    # ===> 정렬 : key 차량 번호대로 오름차순,,,,
    # ===> 출력물 : 오로지 요금만 -- value정보..// 리스트양식
    car_cost = dict(sorted(car_dict.items()))
    answer = list(car_cost.values())
    # ---> 형 변환에 대해서 자유롭게 필요에 따라서 하시면 됨!!!
    # dict에서 .items()리스트로 풀릴 때 순서,,,,,,,,,
    ###########
    return answer

 

23*60+59
1439

# test1

a = [180, 5000, 10, 600]
b = ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"]
solution(a,b)  # [14600, 34400, 5000]
[14600, 34400, 5000]

 

# test2

a = [120, 0, 60, 591]
b = ["16:00 3961 IN","16:00 0202 IN","18:00 3961 OUT","18:00 0202 OUT","23:58 3961 IN"]
solution(a,b) # [0, 591]
[0, 591]

# 코드 정리

def convert_h_to_m(time_HHMM):
    h_part, m_part = time_HHMM.split(":") # "05:34"-->["05","34"]
    total_min = int(h_part) * 60 + int(m_part) # 나중에 산수+/- 정수로 변환
    return total_min

def solution(fees, records):
    answer = []
    base_time, base_cost, add_time, add_cost = fees
    park_dict = {}
    for record in records: # ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT",,,]
        park_time, car_id, status = record.split(" ")
        car_id = int(car_id) # "0000"---> 0
        car_record = [convert_h_to_m(park_time), status ] #--> value추가
        if car_id in park_dict:
            park_dict[car_id].append( car_record) # [334,"OUT"]
        else:
            park_dict[car_id] = [car_record] #**** 형 주의!!!!
    car_dict = {} # k : 차번호, v:누적 요금
    for car, logs in park_dict.items(): # k, v
        out_time_list = [ m for m,sta in logs if sta=="OUT"] # [334]
        in_time_list  = [ m for m,sta in logs if sta=="IN"]  # [300, 1139]
        if len(logs) % 2 == 1: # --> OUT이 없는 친구
            out_time_list.append( convert_h_to_m("23:59")) # 1439
        total_min = sum(out_time_list) - sum(in_time_list)
        if total_min <= base_time: # fees[0]
            car_dict[car] = base_cost # fees[1]
        else: # 추가 요금이 발생하는 경우,,,,
            cost = 0
            cost += base_cost
            total_min -= base_time # 누적시간 = 기존누적시간 - 기본시간
            over_time_base =  -(total_min * (-1) // add_time)
            cost += over_time_base * add_cost
            car_dict[car] = cost
    car_cost = dict(sorted(car_dict.items()))
    answer = list(car_cost.values())
    return answer

# 정리 

==> 문법 자체가 난해하지 않음!!! & 필요하면 간단히 그냥 구현하면 됨!!!
==> 여러 케이스 by 케이스 : 꼼꼼하게 코드 작성하세요!!!!
       : 논리적으로, 분석으로 잘 전략을 세워서,,, 코드화를 잘 하세요!!!!!
       : 문제를 정확하게 분석을 하고, 파악을 하고 손을 대야 함!!!!
==> 내가 필요한 정보들을 세팅하는 과정에서 어떤 자료형/ 어떻게 구성할지..
       : 본인의 기준 + 풀었던 문제들을 어떤거와 유사한지...
+++ : 정렬에서도 할 수 있어야 함!!!구현으로....
==> 꼼꼼하게 분석 잘 해서 꼭!!맞추자!!!!

 

+++ 본인이 출제자라고 하면,,
---> 여러 날짜의 순서가 엉망이 로그 기록을 주고,,,,
---> 정렬을 복잡하게 : 요금을 많이 내는 순서대로(단, 요금이 같으면)
                                    차번호가 작은 것을 우선으로 하고, ++++