최근,카카오에서 쓰여서 

더 유명해진 사이트 프로그래머스!

여기서 코딩테스트 연습용으로 

모아준 문제들이 있어서 

시간날 때마다 하나씩

풀어보고 있다.

 

⬇ 문제확인하러 가기

https://programmers.co.kr/learn/challenges

 

 

코딩테스트를 보다보면 의외로 

키를 통해 매핑하는 문제나 문자열을

가공하여 푸는 문제들이 

자주 나온다.

 

이러한 문제들에서는 

정말 파이썬이 딱이다.

마치 코딩테스트를 풀라고 

나온 언어 같다라는 

생각이 들정도다.


 

 


문제 

 

코딩테스트 연습 - 완주하지 못한 선수 | 프로그래머스

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

programmers.co.kr

 

 

 

functools의 reduce와 같은

고차함수를 사용하면

엄청난 축약이 가능하고 

문법을 안다면 의미가 직관적으로

이해되기 때문에 로직을 짜는데 

상당히 유용하다.

 

이번 문제도 이를 활용하면

간결하게 해결 할 수 있다.

 

 

 

 

 

 

작성 코드

 

from functools import reduce
def solution(participant, completion):
    part = reduce(lambda temp,value : temp.update({value:temp.get(value, 0)+1}) or temp, participant, {})
    for a in completion:
        part.update({a:part.get(a,1)-1})
    answer = list(filter(lambda a : part.get(a) != 0,part))[0]
    return answer

 

 

 


 

 

 

도움이 되셨다면

로그인이 필요없는 공감 버튼 꾹 눌러주세요! 

 

 

 

 

 

 

 

지난 '오픈채팅방/후보키' 문제에 이어

2019 카카오 코딩테스트 '실패율' 문제를

파이썬으로 풀어봤다.

 

 

2019/09/01 - [알고리즘/심심풀이 문제풀기] - [2019 카카오 코딩테스트] 후보키 (파이썬3) / 자체 해설 및 풀이

 

[2019 카카오 코딩테스트] 후보키 (파이썬3) / 자체 해설 및 풀이

지난 '오픈채팅방' 문제에 이어 2019 카카오 코딩테스트 '후보키' 문제를 파이썬으로 풀어봤다. ⬇ [알고리즘/심심풀이 문제풀기] - [2019 카카오 코딩테스트] 오픈채팅방 (파이썬3) [2019 카카오 코딩테스트] 오..

kyome.tistory.com

 

 

 

파이썬은 미리 갖추어져 있는 모듈이 많아서

생각하는 로직대로 알고리즘을 만들기 편하다ㅎㅎㅎ

 

 

 

 

 

 

 

 

 

 

 

 

코딩테스트 연습 - 실패율 | 프로그래머스

실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다. 이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를

www.welcomekakao.com

 

 

 


 

자체 해설

 

시간초과로 테스트 케이스하나가 말썽을 부려서 고생한 문제이다.

 

처음 시도한 방법은 초반에 stages와 N으로 이중For문을 만드는

방식으로 구현했지만 시간제한으로 실패했다.

아래의 제한사항의 내용을 보니 이중 반복문에서 걸리는 듯하다.

 

  • 스테이지의 개수 N은 1 이상 500 이하의 자연수이다.
  • stages의 길이는 1 이상 200,000 이하이다.

 

 

 

 

 

 

실패율 구하기

  1. 성공, 시도, 실패 배열을 만든다.
  2. 게임에 참여한 총 인원 수를 저장해둔다.
  3. stages 배열의 값을 보면 배열에 저장되어 있는 숫자들은 사실 실패한 스테이지이다.
  4. 성공한 스테이지는 배열에 저장되어있는 값 -1 이다.
    ex) stages = [2,1,2,6,2,4,3,3] 일 때, stages[0]는 2이다.
    즉, 2 스테이지를 시도했지만 실패했다, 실제 성공은 1 스테이지까지만 한게 된다.
  5. 스테이지별로 반복을 돌려 필요한 값을 얻어낸다.
  6. 반복부 끝에 스테이지에 머물러있는 사람들을 변수하나에 누적시켜서 실패자의 총합을 갖고 있는다.
  7. n스테이지 성공자 수  구하는 공식
    len(stages배열) /* 총 게임 참여자 수 */
       - stages배열.count(n)   /* n스테이지 실패자 */
       - { (n-1 스테이지 실패자 ) + (n-2 스테이지 실패자) + ... + (0 스테이지 실패자) }  /* 0~n-1 스테이지 실패자 합 */
  8.  시도 배열[n] = 성공자배열[n] + 실패자배열[n

 

 

 

 

작성 코드

def solution(N, stages):
    answer = []
    successCount = [0 for i in range(0,N)]
    tryCount = [0 for i in range(0,N)]
    failCount = [0 for i in range(0,N)]
    sumFailPeople = 0
    totalPeople = len(stages)
    for stage in range(1, N+1):
        failCount[stage-1] = stages.count(stage)
        successCount[stage-1] = totalPeople - failCount[stage-1] - sumFailPeople
        tryCount[stage-1] = successCount[stage-1] + failCount[stage-1]
        sumFailPeople += failCount[stage-1]
    result = [{'idx' : idx, 'fail' : f, 'try' : tryCount[idx]} for idx, f in enumerate(failCount)]
    failRatio = []
    for i in result:
        value = 0
        if i['fail'] != 0:
            value = i['fail']/i['try']
        failRatio.append({'idx' : i['idx'], 'value' : value})
    answer =[v['idx']+1 for v in sorted(failRatio, key=lambda x: x['value'], reverse=True)]
    return answer

 

 

 

 

 

 

 

 

참고 (시간 제한 오류난 케이스)

def solution(N, stages):
    answer = []
    successCount = [0 for i in range(0,N+1)]
    tryCount = [0 for i in range(0,N+1)]
    for man in stages:
        for i in range(0,man):
            tryCount[i] += 1
            if i != man-1:
                successCount[i] += 1
    failCount = [tryCount[idx]-i for idx,i in enumerate(successCount)]
    result =  [{'idx':idx,'fail':f,'try':tryCount[idx]} for idx,f in enumerate(failCount) if idx != len(failCount)-1]
    failRatio = []
    for i in result:
        value = 0
        if i['fail'] != 0:
            value = i['fail']/i['try']
        failRatio.append({'idx' : i['idx'], 'value' : value})
    answer =[v['idx']+1 for v in sorted(failRatio, key=lambda x: x['value'], reverse=True)]
    return answer

 

 

 

카카오 공식 해설 : https://tech.kakao.com/2018/09/21/kakao-blind-recruitment-for2019-round-1/

 

 

 


 

 

도움이 되셨다면

로그인이 필요 없는 공감 버튼 꾹 눌러주세요! 

 

 

 

지난 '오픈채팅방' 문제에 이어

2019 카카오 코딩테스트 '후보키' 문제를

파이썬으로 풀어봤다.

 

 

 

⬇ [알고리즘/심심풀이 문제풀기] - [2019 카카오 코딩테스트] 오픈채팅방 (파이썬3)

 

[2019 카카오 코딩테스트] 오픈채팅방 (파이썬3)

2019 카카오 코딩테스트에서는 자바로 '오픈채팅방'문제를 풀었는데 엄청 복잡하게 풀었던 기억이 난다. 라인수도 엄청나게 나오고 List 종류에 따라 성공과 실패가 나뉘었던 기억이 있다. 이번엔 파이썬으로 문..

kyome.tistory.com

 

 

또다시 느끼는 건 파이썬은 정말 

알고리즘 풀기 좋은 언어이다.

 

주석을 뺀 순수 라인수가 26줄!!

정말 말이 안 된다.

 

 

 

 

 

 

 

 

코딩테스트 연습 - 후보키 | 프로그래머스

[["100","ryan","music","2"],["200","apeach","math","2"],["300","tube","computer","3"],["400","con","computer","4"],["500","muzi","music","3"],["600","apeach","music","2"]] 2

www.welcomekakao.com

 

 

 


 

자체 해설

 

 

막연하지만 차근차근 정리해 보기로 했다.

내 방법은 반복문이 너무 많아서 사실 좋은 방법 같아 보이진 않지만

아래와 같은 제한사항이 있기에 마음 놓고 코드를 써 내려갔다.

 

  • relation의 컬럼(column)의 길이는 1 이상 8 이하이며, 각각의 컬럼은 릴레이션의 속성을 나타낸다.
  • relation의 로우(row)의 길이는 1 이상 20 이하이며, 각각의 로우는 릴레이션의 튜플을 나타낸다.
  • relation의 모든 문자열의 길이는 1 이상 8 이하이며, 알파벳 소문자와 숫자로만 이루어져 있다.

 

 

유일성 :

  1. 2차원 배열로 들어온 relation[row][col]의 값 중 col이 같은 값을 하나의 set에 넣어서 검증하면 된다고 생각했다.
  2. 여러 col의 조합이 유일한지 확인하기 위해서는 인위적인 조작이 필요하다고 생각했다.
  3. 컴럼들의 경우의 수를 모두 얻은 후에 각 값들의 유일성을 검증하기로 했다.
  4. itertools의 combinations를 사용해서 col의 모든 조합을 만든다.
  5. 반복문으로 col의 조합을 가져와서 합친 쳐서 하나의 tempCol을 만들고 set에 넣어서 개수를 확인한다.
      ex) 1,2 조합이라면 set(["100ryan","200apeach","300tube","400con","500muzi","600apeach"])
  6. 개수가 원래 row의 수와 동일하면 유일성이 보장된 것이기 때문에 따로 저장해둔다.

 

최소성 : 

  1. 유일함이 보장된 조합에서 최소성을 검증한다.
  2. 리스트 내에서 부분집합을 갖고 있다면 최소성 조건에 맞지 않기 때문에 삭제 대상 set에 넣는다.
  3. 유일성이 보장된 그룹의 수에서 삭제 대상의 수를 뺀다.

 

 

 

 

 

 

 

작성 코드

from itertools import combinations
def solution(relation):
    answer = 0
    # 모든 컬럼의 조합 리스트
    all = list()

    #유일성 만족하는 조합 리스트
    uniqeIndex = []

    if len(relation) > 0:
        # 컬럼의 개수
        colSize = len(relation[0])
        # 로우의 개수
        rowSize = len(relation)

        # 모든 컬럼의 조합 구하기 (Set형태)
        for i in range(1, colSize + 1):
            # append는 런타임에러가 뜸 append와 extend 비교하여 알아둘 것
            all.extend([set(k) for k in combinations([j for j in range(colSize)], i)])

        # 조합들의 유일성 검증
        for comb in all:
            #set에 추가하여 사이즈 비교로 검증
            vaildSet = set()
            # 조합에 해당되는 로우를 하나의 str로 합쳐서 set에 넣음
            for row in range(rowSize):
                temp = ''
                for col in comb:
                    temp += relation[row][col]
                vaildSet.add(temp)
            # 유일성 확인하여 리스트에 추가
            if len(vaildSet) == rowSize:
                uniqeIndex.append(comb)

        # 최소성 검증
        # 삭제대상 Set (최소성 위배)
        delSet = set()
        #부분집합 여부 확인
        for stdMinElem in uniqeIndex:
            for idx, compMinElem in enumerate(uniqeIndex):
                # 부분집합이면서 자기 자신이 아니라면 상위집합을 삭제 대상에 추가
                if stdMinElem.issubset(compMinElem) and stdMinElem != compMinElem:
                    delSet.add(uniqeIndex.index(compMinElem))
        # 유일성 - 최소성 위배
        answer = len(uniqeIndex)-len(delSet)
    return answer

 

 

카카오 공식 해설 : https://tech.kakao.com/2018/09/21/kakao-blind-recruitment-for2019-round-1/

 

 

 


 

 

도움이 되셨다면

로그인이 필요 없는 공감 버튼 꾹 눌러주세요! 

 

2019 카카오 코딩테스트에서는

자바로 '오픈채팅방'문제를 풀었는데 

엄청 복잡하게 풀었던 기억이 난다.

 

라인수도 엄청나게 나오고 

List 종류에 따라 성공과 실패가 나뉘었던 기억이 있다.

 

 

 

 

 

 

이번엔 파이썬으로 문제를 풀어보았다.

무엇보다 라인 수가 말도 안되게 줄었고

확실히 코드가 깔끔하다.

파이썬 알고리즘에 입문해보는걸

고려해보아야겠다.

 

 

 

코딩테스트 연습 - 오픈채팅방 | 프로그래머스

오픈채팅방 카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다. 신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만들기로 했다. 채팅방에 누군가 들어오면 다음 메시지가 출력된다. [닉네임]님이 들어왔습니다. 채팅방에서 누군가 나가면 다음 메시지가 출력된다. [닉네임]님이 나갔습니다. 채팅

www.welcomekakao.com

 

 

 


 

작성 코드

idDict = dict()

def solution(record):
    answer = []
    logList = []
    for e in record:
        dataList = e.split(" ")
        if dataList[0] == "Leave":
            logList.append([dataList[1], "님이 나갔습니다."])
        elif dataList[0] == "Enter":
            idDict[dataList[1]] = dataList[2]
            logList.append([dataList[1],  "님이 들어왔습니다."])
        elif dataList[0] == "Change":
            idDict[dataList[1]] = dataList[2]
    print(logList)
    for log in logList:
        answer.append(idDict[log[0]] + log[1])
    return answer

 

 

 

카카오 공식 해설 : https://tech.kakao.com/2018/09/21/kakao-blind-recruitment-for2019-round-1/

 

 


 

 

 

도움이 되셨다면

로그인이 필요없는 공감 버튼 꾹 눌러주세요! 

+ Recent posts

"여기"를 클릭하면 광고 제거.