programmers : 베스트 앨범, 3진법 뒤집기, 최소 직사각형, 2016년 (요일구하기), 시저암호, 모두 0으로 만들기
베스트 앨범
1. Problem
2. My Solution
- genres_dict : key = 장르, value = 총 재생수
- genres_song : key = 장르, value = [(i번째곡, 재생수),...]
- genres_rank : genres_dict 에서 총 재생수를 기준으로 내림차순 정렬한 결과
- 재생수를 기준으로 장르를 내림차순 정렬 -> 높은 장르부터 꺼내서 해당 장르에 속한 노래와 재생수를 담고 있는 리스트를 정렬한 뒤 1개 또는 2개 pop()
def solution(genres, plays):
answer = []
genres_dict = dict()
genres_song = dict()
genres_rank = []
for i in range(len(genres)):
genres_dict[genres[i]] = genres_dict.get(genres[i],0) + plays[i]
genres_song[genres[i]] = genres_song.get(genres[i],[]) + [(i,plays[i])]
# print(genres_dict) = {'classic': 1450, 'pop': 3100}
# print(genres_song) = {'classic': [(0, 500), (2, 150), (3, 800)], 'pop': [(1, 600), (4, 2500)]}
for i in genres_dict.items():
genres_rank.append(i)
genres_rank.sort(key = lambda x:x[1], reverse = True)
# print(genres_rank) = [('pop', 3100), ('classic', 1450)]
for i in range(len(genres_dict)):
# 재생횟수를 기준으로 1차정렬(오름차순), 인덱스를 기준으로 2차정렬(내림차순)
genres_song[genres_rank[i][0]].sort(key = lambda x:(x[1], -x[0]))
for _ in range(min(2,len(genres_song[genres_rank[i][0]]))):
answer.append(genres_song[genres_rank[i][0]].pop()[0])
return answer
3. Learned
- sort(key = lambda x:x[0]) 에서 내림차순 정렬하려면 -x[0] 지정
3진법 뒤집기
1. Problem
2. My Solution
def change(n):
result = []
while(n > 0):
n,mod = divmod(n,3)
result.append(mod)
return "".join(map(str,result))
def solution(n):
return int(change(n),3)
3. Learned
- 의외로 진법 변환하는 기능을 많이 요구함. 구글링이 되면 그냥 변환 부분을 가져오면 되지만 구글링이 안된다고 한다면 직접 구현해야되므로 어느정도 공식처럼 외우고 있어야함
- 10진법 -> 2,8,16 진법으로 변환은 bin(), oct(), hex() 함수를 이용
- n진법 -> 10 진법으로 변환은 int(num, n진법) 함수를 이용
최소 직사각형
1. Problem
2. My Solution
- 명함의 가로 또는 세로중에서 가장 큰 길이로 지갑의 가로 또는 세로를 지정해야함
- 가장 큰 길이를 정했으면 명함에서 작은 길이중 (큰 길이는 위에서 구한 길이에 맞추면 됨) 제일 큰 길이를 지갑의 나머지 부분으로 지정
def solution(sizes):
w = sorted(sizes, key = lambda x:x[0])
h = sorted(sizes, key = lambda x:x[1])
max_value = max(w[-1][0], h[-1][1])
second_value = 1
for i in sizes:
if second_value < min(i):
second_value = min(i)
return max_value * second_value
3. Others' Solution
def solution(sizes):
return max(max(x) for x in sizes) * max(min(x) for x in sizes)
4. Learned
- 코드 리팩토링을 통하여 코드의 사이즈를 줄이고 가독성을 높임
// 길이가 가장 큰 부분을 구하는 코드
w = sorted(sizes, key = lambda x:x[0])
h = sorted(sizes, key = lambda x:x[1])
max_value = max(w[-1][0], h[-1][1])
=> max(max(x) for x in sizes)
// 명함에서 길이가 작은 것들 중에서 가장 큰 부분을 구하는 코드
for i in sizes:
if second_value < min(i):
second_value = min(i)
=> max(min(x) for x in sizes)
2016년 (요일구하기)
1. Problem
2. My Solution
- datetime 모듈의 weekday() 함수를 이용하여 해당 날짜의 요일에 대한 정수값을 얻어냄
- 0 : 월요일 ~ 6 : 일요일
import datetime
def solution(a, b):
weekday_match = ["MON","TUE","WED","THU","FRI","SAT","SUN"]
return weekday_match[datetime.datetime(2016,a,b).weekday()]
3. Learned
- 날짜 계산을 필요로하는 문제가 종종 출제되므로 날짜 관련 모듈인 datetime 모듈에 대한 사용법을 알고있어야함 (참고사이트)
시저암호
1. Problem
2. My Solution
def solution(s, n):
answer = ""
for alphabet in s:
asci = ord(alphabet)+n
if alphabet.isspace():
answer += " "
elif alphabet.islower():
if asci > 122:
answer += chr(96+asci-122)
else:
answer += chr(asci)
else:
if asci > 90:
answer += chr(64+asci-90)
else:
answer += chr(asci)
return answer
3. Others' Solution
def solution(s, n):
answer = ""
for alphabet in s:
if alphabet.isspace():
answer += " "
elif alphabet.islower():
answer += chr(((ord(alphabet)-97+n)%26)+97)
else:
answer += chr(((ord(alphabet)-65+n)%26)+65)
return answer
4. Learned
- 알파벳을 순환하는 문제도 종종 출제되는데, 이 때 정방향 또는 역방향으로 순환하게 됨
// n 번 만큼 정방향으로 이동한다고 할 때
// -1%26 = 25 이므로 -n 번 만큼 역방향으로 이동한다고 할 때도 동일하게 사용
chr(((ord(alphabet)-65+n)%26)+65)
모두 0으로 만들기
1. Problem
2. My Solution
- 가중치의 총합이 0이 아니면 -1을 출력해야함
- 행동을 최소로 하기 위해서는 연결된 간선의 수가 작은 노드부터 0으로 만들어야된다고 생각해서 노드에 연결된 간선의 수를 각각 계산하고, 간선의 수를 기준으로 오름차순 정렬하여 해당 노드 순서대로 0을 만들어 나감 -> 실패 (행동을 취할 노드를 정할 때 순서의 기준없이 랜덤으로 정하게되고, 중간에 끊기는 경우도 생김)
def solution(a, edges):
graph = [[] for _ in range(len(a))]
conn_cnt = [0] * len(a)
order = []
answer = 0
# 가중치의 총합이 0이 아니면 만들 수 없으므로 return -1
if sum(a) != 0:
return -1
# 연결된 간선의 수를 기준으로 오름차순 정렬하는 부분
for edge in edges:
conn_cnt[edge[0]] += 1
conn_cnt[edge[1]] += 1
graph[edge[0]].append(edge[1])
graph[edge[1]].append(edge[0])
for idx,cnt in enumerate(conn_cnt):
order.append((idx,cnt))
order.sort(key = lambda x:x[1])
# 간선의 수가 작은 노드부터 0으로 만듬
for node, _ in order:
for victim in graph[node]:
if a[victim] != 0:
a[victim] += a[node]
answer += abs(a[node])
a[node] = 0
return answer
3. Others' Solution
- 그래프가 항상 트리로 주어지므로 임의의 노드를 루트로 설정하고 리프노드부터 루트까지 올라가면서 0으로 만들면 됨
- dfs 를 이용하면 dfs 를 호출하면서 루트노드에서 리프노드까지 방문할 수 있고, dfs 호출이 종료되고 다시 돌아오면서 리프노드에서부터 루트노드까지 이동할 수 있음
import sys
sys.setrecursionlimit(10**8)
def solution(a, edges):
def dfs(node):
nonlocal answer
visited[node] = True
for u in graph[node]:
if visited[u] == False and a[u] != 0:
dfs(u)
a[node] += a[u]
answer += abs(a[u])
graph = [[] for _ in range(len(a))]
visited = [False] * len(a)
answer = 0
# 가중치의 총합이 0이 아니면 만들 수 없으므로 return -1
if sum(a) != 0:
return -1
for u,v in edges:
graph[u].append(v)
graph[v].append(u)
dfs(0)
return answer
4. Learned
- 트리에서 DFS 알고리즘을 이용하면 루트노드에서 리프노드까지 방문할 수 있음. 이를 역으로 생각한다면 리프노드에서 루트노드까지 방문하는 원리 또한 생각해낼 수 있음
Author And Source
이 문제에 관하여(programmers : 베스트 앨범, 3진법 뒤집기, 최소 직사각형, 2016년 (요일구하기), 시저암호, 모두 0으로 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@codren/programmers-베스트-앨범저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)