본문 바로가기

알고리즘풀이/프로그래머스

[11/22] Lv1.

👉 사용 언어 : PYTHON3

실패율

✅ Solution

 

def solution(N, stages):
    answer = []
    for i in range(1, N+1):
        nclear = 0
        reach = 0
        for j in stages:
            if i <= j:
                reach += 1
                if i == j:
                    nclear += 1
        if reach == 0:
            answer.append(0.0)
        else:
            answer.append(nclear/reach)
    for k in sorted(answer, reverse=True):
        answer.append(answer.index(k)+1)
        answer[answer.index(k)] = -1
    return answer[N:N*2]

 

👉 좀 더 간결하고 효율적인 코드를 위해 노력합시다..!

 

👉 아이디어

  • 중첩 반복문을 돌려서 각각의 stages 단계보다 크거나 같은 값일 경우 분모 변수 +1, 같은 값일 경우 분자 변수 +1
  • 분모가 0일 경우도 있기 때문에 (= 아무도 도달하지 못한 경우) 조건문을 통해 예외 처리해준다.
  • 각 실패율을 저장한 배열을 내림차순 정렬한 배열에서 하나씩 꺼내어 인덱스 +1 (= 스테이지 단계)을 추가해준다.
    • sorted(문자열명, reverse= True), 문자열명.sort(reverse=True) 둘 다 오름차순 정렬하는 방법!
    • reverse 조건의 값을 주지 않으면 기본적으로 내림차순 정렬(reverse=True)이 설정된다.
  • 동일한 실패율이 존재할 경우, .index()로 값을 통해 인덱스를 추출하면 제일 앞에 있는 인덱스만 나온다.
    • 따라서 인덱스를 추출한 후, 해당 원소값을 -1로 바꿔준다. (실패율이 -1일 경우는 없으므로)
  • 결과를 리턴할 때는 원래 answer에서 answer길이만큼 인덱스 값을 추가해줬기 때문에 [N:N*2]만큼 잘라서 해당 원소값들을 리턴한다.
    • 원래 answer : [실패율1, 실패율2, ..., 실패율N]
    • 마지막 반복문이 끝난 후 answer : [-1, -1, ..., N개의 -1. 인덱스, 인덱스, ..., N개의 인덱스]
    • 원래 N개만큼 원소가 있었고 각각의 값에 해당하는 인덱스를 추가했으므로 N개만큼 더 추가되는 것이다.

👉 주의해야 할 조건 ( 런타임 에러 원인 )

    0 으로 나눠질 경우를 처리해야한다.

👉 참고 _ 런타임 에러가 발생하는 경우

  • 배열에 할당된 크기를 넘어서 접근했을 때
  • 전역 배열의 크기가 메모리 제한을 초과할 때
  • 지역 배열의 크기가 스택 크기 제한을 넘어갈 때
  • 0으로 나눌 때
  • 라이브러리에서 예외를 발생시켰을 때
  • 재귀 호출이 너무 깊어질 때
  • 이미 해제된 메모리를 또 참조할 때
  • 프로그램(main 함수)이 0이 아닌 수를 반환했을 때

 다른 사람 풀이 참고

 

def solution(N, stages):
    result = {}
    denominator = len(stages)
    for stage in range(1, N+1):
        if denominator != 0:
            count = stages.count(stage)
            result[stage] = count / denominator
            denominator -= count
        else:
            result[stage] = 0
    return sorted(result, key=lambda x : result[x], reverse=True)

👉 .count( ) : 배열에서 해당 값의 개수를 찾아주는 함수

👉 딕셔너리 사용하여 실패율(value)을 기준으로 스테이지단계(key)를 정렬해줌 ( key = lamda x : result[x] )

👉 dominator가 len(stages)이고 stages는 변하지 않는데 어떻게 0일 경우와 0이 아닐 경우로 나눌 수 있지..?!

  • 아 ! for문 안에서 "denominator"가 바뀌니까 (= 이전 스테이지까지만 도달한 사람 수는 카운트하지 않아도 되니까 빼줌) 여기서 0인 경우와 0이 아닌 경우를 나눌 수 있구나!

옹알이

✅ Solution

 

def solution(babbling):
    answer = 0
    pron = {"aya":"0", "ye":"1", "woo":"2", "ma":"3"}
    for i in range(len(babbling)):
        for j in pron.keys():
            babbling[i] = babbling[i].replace(j, pron[j])
    for m in babbling:
        for n in range(len(m)):
            if (m[n] < "0" or m[n] > "3") or (n < len(m)-1 and m[n] == m[n+1]):
                answer += 1
                break
    return len(babbling) - answer

 

👉 아이디어

  • "aya", "ye", "woo", "ma"에서 2개 조합, 3개 조합, 4개 조합 뽑아서 하나의 리스트로 만든다.
  • 전달받은 babbling 배열에서 하나씩 뽑아서 리스트에 값이 있는지 비교한다. (is not in ~ / is in ~)

👉 combinations 사용하여 조합을 뽑으면 순서가 반영안되는 문제가 발생..

  • babbling 배열에서 각 원소에 "aya", "ye", "woo", "ma" 를 공백문자로 replace한 후, 문자열 길이가 0인것만 카운트하는걸로
  • BUT 고려해야할 조건이 같은 발음이 연속된 것도 불가능하다!

👉 딕셔너리 로 가능한 발음(Key)들에 숫자(Value)를 맵핑한다.

👉 전달받은 babbling 배열의 각 원소에서 딕셔너리에 있는 키값에 해당하는 문자는 맵핑된 숫자 스트링 으로 바꾼다.

👉 바뀐 babbling 배열에서 다시 반복문을 돌려서 아래 조건에 해당하면 카운트한다.

    (1) 지정된 Value값 범위에 없거나

    (2) 연속된 문자열일 경우

이 때, 모든 문자의 (1)번 조건을 체크하기 위해 0부터 m의 길이만큼 반복문을 돌리는데 (2)번 중복 조건을 체크할 때 IndexError를 방지하기 위해 n < len(m) -1 조건을 추가한다.

👉 이 조건을 추가하지 않으면 m[len(m)-1+1]에서 원소가 없으므로 에러가 발생한다.

👉 카운트한 원소는 옹알이할 수 없는 문자열이기때문에 전체 babbling 원소 수에서 카운트한만큼을 빼서 반환한다.

 

 다른 사람 풀이 참고

 

def solution(babbling):
    answer = 0
    for i in babbling:
        for j in ['aya','ye','woo','ma']:
            if j*2 not in i:
                i=i.replace(j,' ')
        if len(i.strip())==0:
            answer +=1
    return answer

 

👉 not in 으로 연속 문자열을 체크할 수 있구나! 근데 *2이면 3번이상 연속되는 문자열은 없는건가..?

👉 .strip() : 공백제거한 문자열 반환 

숫자 짝꿍

✅ Solution

 

def solution(X, Y):
    common = []
    for i in range(10):
        cnt = min(list(X).count(str(i)),list(Y).count(str(i)))
        for j in range(cnt):
            common.append(i)
    if len(common) == 0:
        return "-1"
    elif sum(common) == 0:
        return "0"
    else:
        return ''.join(map(str,sorted(common, reverse=True)))

 

👉 아이디어

  • X와 Y 중 길이 짧은걸 먼저 반복문 돌린다. (시간효율 높이기 위해)
  • X, Y의 최대 길이가 300만이므로 짧은걸 돌린다해도 둘 다 길이가 길면 시간초과 ERROR 발생.. ( 결과값 길이도 모르므로 int( ) 변환 과정이 들어가면 시간초과 ERROR 발생 )
  • 그럼 set의 교집합 연산을 사용할까? 라고 생각했지만 중복된 원소를 체크할 수 없음
  • .count( ) 사용하여 0~9까지 X와 Y 배열에 있는 개수 카운트
    • 둘의 카운트 중 작은 값을 선택하여 카운트만큼 공통 배열에 해당 숫자를 추가한다.
    • 교집합이므로 작은 값을 선택하는 것
  • 경우의 수에 따라 조건문을 넣어준다.
    • 겹치는 값이 없을 때 (= 공통배열의 길이가 0일 때)
    • 겹치는 값이 "0"만 있을 때 (= 공통배열 원소의 합이 0일 때) _ sum( ) 사용하기 위해 공통배열을 정수 배열로 정의함
    • 그 밖의 경우
  • 그 밖의 경우 _ 큰 수부터 앞에 와야하므로 내림차순 정렬 한 후, map( ) 통해 각 정수 원소를 str으로 바꿔주고 .join( ) 사용하여 문자열로 반환한다.

? 숫자 배열을 문자열로 변환하여 출력하려면 ?

 

: map( ) 사용하여 숫자 배열의 원소값들을 str으로 바꾸고 .join( ) 통해 문자열로 출력한다.

 

? 리스트에서 특정 요소 개수 구하기 ?

 

: 배열명.count(특정 요소)

'알고리즘풀이 > 프로그래머스' 카테고리의 다른 글

[12/5] Lv1.  (0) 2023.12.02
[성격 유형 검사하기]  (2) 2023.11.28
[11/16] Lv1.  (0) 2023.11.10
[11/8] Lv1.  (0) 2023.11.04
[10/31] Lv1.  (0) 2023.11.01