본문 바로가기
알고리즘 풀이

[알고리즘] 프로그래머스 | 대충 만든 자판, 추억 점수

by 째깍단 2023. 11. 6.

추억 점수

답: 

더보기
def solution(name, yearning, photo):
    answer = [0] * len(photo)
    
    yearn = {}
    for k, v in zip(name, yearning):
        yearn[k] = v
    
    for i, p in enumerate(photo):
        for name in p:
            if name in yearn:
                answer[i] += yearn[name]
        
    return answer

 

 

문제 분석 및 해석

각각의 사람마다 추억 점수가 있다.

사진에는 여러 사람이 들어가 있는데, name 과 yearning을 바탕으로 각 photo의 추억점수를 계산하고자 한다

 

입력

name 이름이 담긴 배열

yearning 추억점수가 담긴 배열 

   - name과 yearning의 길이는 동일

photo는 중복된 값이 들어있지 않다

 

출력

photo길이만큼의 [추억점수, 추억점수 ...] 배열

 

※ 문제에는 제시되어있지 않지만 photo에는 추억점수가 없는 사람이 포함되어있다.

   해당 사람을 제외하는 코드를 추가해주어야함

 

 

>> 풀이생각

 

1. name 과 yearning 두 배열은 길이가 같으므로 zip()함수 활용이 가능함

    각각 key와 value로 dictionary에 저장해주기

2. photo의 이름 = key값이므로 key값을 통해 추억 점수를 찾아 해당 위치에 더해주기

3. answer에 append하기보단 미리 자리를 만들어주고 더해주면 효율이 더 좋지 않을까?

 

 

 

 

리뷰.

name, yearning 배열 중 하나로 enumerate로 index, value값을 각각 찾은 후 index를 이용해 yearning을 찾을 수도 있다.

조금 더 코드가 길어지고 복잡하게 작성될 듯.

 

zip함수를 사용하면 길이가 같은 두 배열을 간단히 처리할 수 있어 편리했다

 

 

 

 

미리 자리를 만들어주는 것이 좋을지, append하는 것이 좋을지 궁금해 시험해보았다.

데이터의 크기가 작다보니 (최대 700) 큰 차이가 없다

 

# score 변수와 append 사용
for i, p in enumerate(photo):
    score = 0
    for name in p:
        if name in yearn:
             score += yearn[name]
    answer.append(score)

 

 

answer = [0] * len(photo) 로 미리 점수 넣을 자리 만들기

 

점수를 저장할 score를 선언하고 append를 사용

 


 

대충 만든 자판

답: 

더보기
def solution(keymap, targets):
    answer = []
    
    newmap = {}
    for key in keymap:
        i = 1
        for k in key:
            if not k in newmap:
                newmap[k] = i
            elif newmap[k] > i:
                newmap[k] = i
            i += 1

    for target in targets:
        num = 0
        for t in target:
            if not t in newmap:
                num = -1
                break
            else:
                num += newmap[t]
        answer.append(num)
    return answer

 

 

문제 분석 및 해석

 

휴대폰처럼 각 키에 여러 문자가 지정되어있는 '대충 만든 자판'

여러번 누르면 할당된 순서대로 문자가 바뀌고 해당 문자를 입력할 수 있다.

대문자만 지정되며, 같은 문자가 여러번 지정될 수도 있다.

 

해당 자판과 작성하기 위한 문자열이 주어질때,

각 문자열을 작성하기 위한 최소 횟수를 순서대로 배열에 담아 return하기

 

입력

keymap : 자판 문자열을 가지는 배열

targets : 입력하려는 문자열을 가지는 배열

 

출력

배열, 각 targets에 대한 최소횟수 및 작성 불가할 경우 -1

 

 

 

>> 풀이생각

 

1. keymap을 가공하여 각 문자를 누르기 위한 최소 횟수를 담은 dictionary만들기

2. targets의 문자열을 생성한 dictinary에서 찾아 더하기

3. -1이 나올 경우에 대한 결과 처리해주기

4. 결과를 answer배열에 append & return

 

※ targets의 1개 케이스가 -1 로 출력되어도 모든 문자열에 대하여 결과를 도출하여 배열을 return해야 한다.

   ex. [-1, 2, ...] 

 

 

 

 

리뷰.

 

key를 더해줄때 i 라는 매개 변수를 설정해 최소 키 값을 설정해주고,

더 작은 값이 발견되면 교체할 수 있도록 했다.

newmap = {} # dictionary 변수 선언
for key in keymap: # 새로운 keymap 만들기
    i = 1 # 문자를 찾기위해 눌러야하는 기본 키 값을 1로 설정
    for k in key:
        if not k in newmap: 
        # newmap에 없으면 현재 i값과 함께 더해주기
            newmap[k] = i
        elif newmap[k] > i: 
        # newmap에 있으면 저장된 value값과 현재 i값을 비교해 작은 값을 넣어주기
            newmap[k] = i
        i += 1  # i값을 1씩 더해가며 눌러야하는 값을 저장

 

 

 

문제를 풀이할 때 위 주의사항을 생각하지 못해 약간 헤맸다.

append를 한 줄로 줄여쓰기위해 -1을 num에 저장하고 break하는 식으로 바꾸었다.

 

 

수정 전  : -1인 경우 targets의 요소가 몇 개든 [-1]을 반환함

for target in targets:
    num = 0
    for t in target:
        if not t in newmap:
            return [-1]
        else:
        ...
        answer.append(num)

 

 

수정 후

for target in targets: # targets가 작성할 수 있는 문자열인지 확인하기
    num = 0 # 횟수 저장을 위한 변수
    for t in target: # 각 문자열을 1개씩 확인
        if not t in newmap: 
            # newmap에 target요소가 없으면 -1저장
            num = -1
            break
        else:
            # newmap에 target이 있으면 num에 횟수 더해주기
            num += newmap[t]
    # 한 문자열 점검이 끝난 후 append 
    answer.append(num)

 

 

 


 

두 문제가 dictionary를 활용하는 비슷한 문제여서  쉽게 풀이할 수 있다:)