11/25 Programmers LV1

김태준·2022년 11월 25일
1

Coding Test - Programmers

목록 보기
17/29
post-thumbnail

전날 카타르 월드컵 한국 우루과이 전을 보고 매우 늦게 일어나버렸다😋
내가 뛴 것도 아닌데 늦잠을 자버렸네,, 한국 선수들 너무 열심히 뛰는 걸 보니까 감동이더라 남은 가나전 포르투갈전도 열심히해서 좋은 성과 있길🙌

Programmers LV1

요새 프로그래머스로 문제를 풀고 있다.
원래는 백준으로 코딩테스트 문제 풀고 그랬었는데 카카오 테크 인턴십 코딩테스트 준비해보면서 Programmers가 좀 더 깔끔한 느낌,,?이 들었다.
앞으로 프로그래머스로 문제 풀이를 진행하고 특정 알고리즘에 대해 공부할 때는 백준을 이용할 예정이다.

11월에 중간고사, 밀린 강의 등등 듣다보니 코딩테스트 공부를 잠깐 2주정도 쉬었다. 한동안 쉬고 다시 문제풀려하니 머리가 안돌아가더라... 금붕어도 아니고😒
그래서 LV1부터 다시 차근차근 풀고 있다.

프로그래머스 lv1은 지금까지 풀어보니 주어진 문제를 뭐 알고리즘 사용 없이 단순 구현해내는? 느낌이 강했다.

완주하지 못한 선수

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

아래 문제는 해시를 이용해야만 효율성을 통과할 수 있었다. 단순히 Constraint만 보고 3중 for문 , 뭐 딕셔너리까지 해서 돌려봤으나 통과를 못하더라..😭 사실 해시라는 자료구조에 대해서도 자세히 몰라서 아래 다른 분이 해시에 대해 작성한 파트를 보고 이해한 다음 문제를 해결할 수 있었다.
https://ablue-1.tistory.com/68

딕셔너리와 아주 유사한 형태를 띄지만 중복은 피하게 해주는 해시 자료구조는 상당히 좋은 장점을 가진 것같다.

처음에는 completion 리스트에 존재하는 사람이 participant리스트 내 명단이 있다면 결과에 해당 사람을 출력하는 code로 작성해봤으나, 참가자 명단이 동명이인일 경우를 해결하지 못하였다.
그래서 두번째로 딕셔너리를 이용하여 participant 개개인마다 고유 인덱스를 부여하여 해결해보려했으나 효율성을 통과하지 못했다.

Code review

def solution(participant, completion):
    member = {}
    value = 0
    for i in participant:
        member[hash(i)] = i
        value += hash(i)
    for i in completion:
        value -= hash(i)
    
    return member[value]

따라서 해시를 이용하여 이를 해결하였고 member라는 딕셔너리에 participant 명단에 있는 사람들마다의 고유 번호를 hash()함수를 통해 값을 추가하였고, completion 명단에도 존재한다면 값을 제거해주어 마지막에 남은 value를 이용하여 participant에는 존재하지만 completion에는 없는 사람을 출력해내는 코드를 작성하였다.

member[hash(i)] = i 코드로 만일 '홍길동 이라는 사람이 participant에 두명 이상 존재하면 어떡할 것인가'라는 문제는 해결할 수 있었다. 해시 자료구조를 통해 ex) 홍길동_1 : 12, 홍길동_2:15 의 방식으로 중복문제를 없앴기 때문이다.

[1차 다트게임]

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.
갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.
다트 게임은 총 3번의 기회로 구성된다.
각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
옵션으로 스타상() , 아차상(#)이 존재하며 스타상() 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
스타상()은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상()의 점수만 2배가 된다. (예제 4번 참고)
스타상()의 효과는 다른 스타상()의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상() 점수는 4배가 된다. (예제 4번 참고)
스타상(
)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
스타상(), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.
0~10의 정수와 문자 S, D, T,
, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

위 문제는 어떻게 구현할 것인가?를 묻고자 하는 문제였다. 이를 그대로 구현하는 것은 크게 어렵진 않았다.

Code review

def solution(dartResult):
    answer = []
    score = ''
    for i in dartResult:
        if i.isnumeric():
            score += i
        elif i == 'S':
            score = int(score)**1
            answer.append(score)
            score = ''
        elif i == 'D':
            score = int(score)**2
            answer.append(score)
            score = ''
        elif i == 'T':
            score = int(score)**3
            answer.append(score)
            score = ''
        elif i == '*':
            if len(answer) > 1:
                answer[-2] = answer[-2]*2
                answer[-1] = answer[-1]*2
            else:
                answer[-1] = answer[-1]*2
        elif i == '#':
            answer[-1] = answer[-1]*(-1)
            
    return sum(answer)

주어진 문자열 dartResult에서 각 문자열마다의 특징들을 뽑아내 코드로 구현하였다. 우선 숫자인 경우 score 문자에 포함시켜 대기 시킨 후 이후에 나오는 문자(S,D,T,*,#)등의 특징들을 if / elif 문을 이용하여 해결하였다.

1) 숫자 뒤에 나오는 문자가 S,D,T인 경우

앞서 대기 시켜놓은 score를 int형으로 변환한 후 제곱을 진행하여 answer 리스트에 추가하였다. 이때 score = '' 코드를 반드시 추가해주어야만 다음 번 숫자에 적용되지 않도록 반영시켰다.

2) 문자열에 * 또는 #이 있는 경우

#의 경우 그냥 answer에 저장된 끝 값에만 -1을 곱해주면 해결되는 문제였다.
그러나 *의 경우 앞선 2개의 숫자에 중복되어 반영될 수 있다는 조건이 있어 len(answer) > 1인 경우와 len(answer) == 1인 경우 2가지 경우의 수를 반영하여 코드를 작성하였다.

[1차] 비밀지도

네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.
지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
"지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

code review

def solution(n, arr1, arr2):
    answer = []
    for i in range(n):
        value = bin(arr1[i] | arr2[i])
        value = value[2:].zfill(n)
        value = value.replace('1', '#').replace('0', ' ')
        answer.append(value)
    return answer

위 문제를 해결하기 위해 이진법을 검색하던 도중, bin 함수에 대해서 알게 되었다. bin함수를 통해서 숫자 > 0b1111등의 형태로 형변환이 가능한 함수 임을 알게 됐다. 문제 풀이 과정은 아래와 같다.

1) 1차로 주어진 array들에 모든 행에 대해 주어진 숫자를 이진법 형태로 변환한다.
2) 앞서 출력되는 0b를 제외하고 n개의 문자 수에 맞게 zfill함수로 0을 채워준다.
3) 이진법으로 0과 1로만 구성된 value들을 1은 #으로 0은 공백으로 변환하여 준다.

위 문제를 해결하면서 이진법으로 변환하는 과정을 더 색다르게 알아갈 수 있었고, replace함수를 두줄이나 쓰기엔 좀 그래서 연속하여 사용하려면 어떡하지하다가 .으로 한번 더 해봤는데 되길래 이 부분도 알게 되었다.

오늘 문제풀이는 여기까지.
이것보다 문제를 더 풀긴했으나 LV1의 경우 단순 구현문제라 일일이 다 어떤방식으로 구현하였는지를 작성하기 보단, 문제를 풀면서 새로운 것을 알게된 부분? 이 강한 문제들만 추려 정리해보았다.

profile
To be a DataScientist

0개의 댓글