본문 바로가기

Algorithm

[programmers] 코딩테스트 입문

https://school.programmers.co.kr/learn/challenges/beginner?order=acceptance_desc&page=1&languages=python3 

 

코딩테스트 입문 | 프로그래머스 스쿨

코딩테스트에 처음 도전하는 사람들을 위한 입문 문제 모음. 쉬운 문제부터 하나씩 도전해 보면서 코딩테스트에 자신감도 붙이고 문제 해결 능력을 키워보세요!

school.programmers.co.kr

방학동안 파이썬으로 도장깨기 하겠음. 다들 파이팅.


숫자 비교하기

같으면 1, 다르면 -1

def solution(num1, num2):
	return 1 if num1 == num2 else -1

나는 걍 조건문 사용했음


분수의 덧셈

from fractions import Fraction

def solution(denum1, num1, denum2, num2):
    num = Fraction((denum1*num2 + denum2*num1), num1*num2) # 첫번째 인자에 분자, 두번째 인자에 분모
    answer = [num.numerator, num.denominator] # 분자, 분모 추출
    return answer

Fraction() : 자동으로 기약분수로 바꿔줌

https://zephyrus1111.tistory.com/330

 

파이썬(Python) fractions 모듈을 이용한 분수 표현, 분수 연산하기(feat. Fraction)

파이썬(Python) 코딩 중에 분수를 다뤄야 할 일이 있었는데 fractions라는 좋은 모듈이 있었다. fractions 모듈은 분수를 다룰 수 있는 훌륭한 모듈이라고 생각한다. 따라서 이번 포스팅에서는 fractions

zephyrus1111.tistory.com

 

다른 풀이

분자, 분모 각각 구해서, 둘의 최대공약수 math.gcd() 로 각각 나누면 기약분수 됨.


배열 두 배 만들기

def solution(numbers):
    for i in range(0, len(numbers)):
        numbers[i] = numbers[i] * 2
    return numbers

나는 numbers 배열을 그대로 바꿔서 리턴함

 

다른 풀이

answer 리스트를 새로 만들어서, answer.append()로 갖다 붙이는 방법도 있음

람다식 .. 근데 먼 list랑 map ..? 흠 ..

리스트 컴프리헨션? 이라는 것두 있음


최빈값 구하기

처음에는 .. 리스트를 하나 더 만들고 이중 반복문을 이용해서 만약 앞에 동일 숫자가 나오면 횟수에 +1 해주는 식으로 하려 했는데, 횟수를 어떻게 늘리면서 저장할지 모르겠어서 결국 찾아봄.

 

collections 모듈의 Counter 클래스

: 사전(dict) 클래스의 하위 클래스로, 리스트나 튜플에서 각 데이터가 등장한 횟수를 사전 형식으로 반환함.

from collections import Counter

def solution(array):
    c = Counter(array)
    order = c.most_common() # 내림차순으로 저장
    
    if len(array) == 1: # 원소가 1개일 경우를 고려해야 함. 아니면 아래 조건문 수행할 때 인덱스 넘어간다는 에러 발생
        answer = array[0]
    elif order[0][1] == order[1][1]: # order에서 첫번째 두번째의 횟수가 동일한 경우 즉 최빈값이 2개인 경우
        answer = -1
    else: # 최빈값이 2개가 아니고 원소가 1개만 있는 것도 아니라면
        answer = order[0][0] # 걍 최빈값 리턴
        
    return answer

첨에 한 것

다시 하라 함 ..........

뭐냐 이거

 

결국 다른 풀이들 찾아봄.

 

다른 풀이 1

https://velog.io/@jjing9/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EB%B9%88%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0

 

[ 프로그래머스 ] 최빈값 구하기

문제 설명 > 최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을

velog.io

1) 새로운 배열 num_array 를 만든다. 만약 array가 [1, 2, 3, 3, 3, 4] 라면, num_array[1] 에는 1, num_array[2]에도 1, num_array[3] 에는 3, num_array[4] 에는 1이 저장되도록 만든다. 즉, 원소를 새로운 배열의 인덱스로 생각하고, 원소의 개수를 새로운 배열의 원소로 생각한다.

2) num_array에서 처음부터 끝까지 인덱스를 돌면서 가장 큰 값과 해당 인덱스를 찾는다.

3) 다시 처음부터 끝까지 인덱스를 돌면서 2)에서 찾은 가장 큰 값과 동일한 값이 또 존재한다면, 미리 선언해둔 count 변수를 증가시킨다.

4) count 변수가 1보다 크다면 -1을 리턴하고, 그 외의 답은 2)에서 찾은 인덱스 값을 리턴하면 된다.

 

의문점

- 처음에 num_array 배열을 만들 때 배열의 크기를 지정해야 하는데, 만약 2000으로 했다가 array 배열에서 가장 큰 원소가 2000보다 크다면 문제가 되지 않나? 이렇게 원소의 값이 매우 크다면 위의 방법을 사용 가능할지

- 2단계와 3단계를 합칠 수는 없었나?

 

다른 풀이 2

https://obinstory26.tistory.com/m/97

 

프로그래머스 lv0. 최빈값 구하기

https://school.programmers.co.kr/learn/courses/30/lessons/120812 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞

obinstory26.tistory.com

1) count라는 이름의 딕셔너리를 생성한다.

2) array의 원소를 count에 하나씩 추가하는데, count에 없는 경우에만 추가하고, 이미 있다면 value를 1씩 증가시킨다.

3) 딕셔너리를 돌면서 value가 가장 큰 자료를 찾는다.

4) 3)에서 찾은 가장 큰 value 값을 가진 키를 찾아서 새로운 배열 max_cnt에 넣는다.

5) max_cnt 의 원소 개수가 1개 이상이라면 즉 최빈값이 2개 이상이라면 -1을 리턴하고

6) 그게 아니라면, max() 사용해서 count에서 가장 키를 리턴

 

결국 두 번째 풀이 참고함

언니 고마워 .. //.// ..

def solution(array):
    count = {} # 딕셔너리 생성

    for num in array: # array의 모든 원소를 돌면서
        if num not in count: # 해당 원소가 count에 존재하지 않다면,
            count[num] = 0 # count에 새로 추가하고 value는 0으로 초기 설정
        count[num] += 1 # 이미 count에 존재하는 원소라면 value를 1 증가

    max_val = 0

    for k, v in count.items(): # .items()를 통해 key, value 쌍을 얻을 수 있음.
        if v > max_val: # 가장 큰 value 찾기
            max_val = v

    max_cnt = [k for k, v in count.items() if v == max_val] # 가장 큰 value일 경우의 key 즉 최빈값 k를 max_cnt 배열에 넣기
    if len(max_cnt) > 1: # 최빈값이 1개 이상일 경우 즉 위에서 max_cnt 배열에 여러 개의 key가 저장되었을 경우
        return -1
    else:
        return max_cnt[0]

다만 맨 마지막 부분에서 max() 사용하지 않고 걍 max_cnt의 원소를 리턴했다.


짝수는 싫어요

def solution(n):
    answer = [num for num in range(1, n+1) if num % 2 == 1]
    return answer

이전 문제에서 max_cnt 리스트 만들었을 때 사용했던 방법 응용해서 풀어봄.

근데 다른 풀이 보니까 아예 range(1, n+1, 2) 해서 2씩 증가를 이용해서 출력하는 방법도 있었다.

오 ..

ㅎㅎ


피자 나눠 먹기 (1)

def solution(n):
    if n < 7: # 1 ~ 6명일 때는 1판
        answer = 1
    elif n % 7 == 0: # 7의 배수일 때는 n/7판
        answer = n / 7
    elif n // 7 > 0: # 그 외에는 n//7 +1판
        answer = n // 7 + 1

    return answer

처음에 한 건 위인데,

def solution(n):
    if n % 7 == 0: # 7의 배수일 경우 n/7판
        answer = n / 7
    elif n // 7 >= 0: # 그 외에는 n//7 +1판
        answer = n // 7 + 1
    
    return answer

걍 이렇게만 해도 됐음.

def solution(n):
    if n % 7 == 0: # 7의 배수일 경우 n/7판
        answer = n / 7
    else: # 그 외에는 n//7 +1판
        answer = n // 7 + 1
    
    return answer

더 줄여서 걍 이렇게만 해도 됐음 .. ^^ ..

7의 배수일 경우에만 신경 쓰면 되고 나머지는 걍 한 번에 (n // 7 + 1)판으로 해도 괜찮아서!

 

다른 풀이

return (n - 1) // 7 + 1

이렇게 한 줄이면 됨 ..

왜냐면, 7의 배수일 경우에는 어차피 뒤에 +1 이 있으니까 딱 나누어 떨어짐

7의 배수가 넘어갈 경우에도 1판이 더 필요해지고

1 ~ 7 => 1판

8 ~ 14 => 2판

15 ~ 21 => 3판


피자 나눠 먹기 (2)

6 -> 1판 (6*1조각)

10 -> 5판 (6*5조각)

4 -> 2판 (6*2조각)

def solution(n):
    if n % 6 == 0: # 6의 배수일 경우
        return n / 6
    else: # 그 외에
        for answer in range(1, 200):
            if 6 * answer % n == 0: # 피자 전체 조각 % n이 0이면 됨
                return answer

이렇게 풀었는데, for문 범위를 (1, 200) 이라고 했지만 뭔가 자꾸 걸렸음.

 

다른 풀이
def solution(n):
    i=1
    while(1):
        if (6*i)%n==0:
            return i
        i+=1
        
# 위랑 동일
def solution(n):
    answer = 1
    while 6 * answer % n:
        answer += 1
    return answer

while문을 쓰는 게 깔끔한 것 같다.


피자 나눠 먹기 (3)

n을 slice로 나눈 몫에 + 1 하면 되는데

만약 slice와 n이 동일하다면, 걍 몫임. +1 안해도 됨.

만약 slice보다 크다면, 나눈 몫에 +1 하면 됨.

근데 그럼 피자 나눠 먹기 (1) 이랑 같은 거 아닌가?? 

def solution(slice, n):
    return (n - 1) // slice + 1

옷가게 할인 받기

def solution(price):
    if price < 100000: # 10만원 미만
        return int(price)
    elif price < 300000: # 30만원 미만
        return int(price*0.95)
    elif price < 500000: # 50만원 미만
        return int(price*0.9)
    else: # 50만원 이상
        return int(price*0.8)

문제 푸는 데는 어려운 점이 없었는데 다른 풀이가 신기해서

 

다른 풀이
def solution(price):
    discount_rates = {500000: 0.8, 300000: 0.9, 100000: 0.95, 0: 1} # 딕셔너리
    for discount_price, discount_rate in discount_rates.items(): # 키, 값에 변수 지정
        if price >= discount_price:
            return int(price * discount_rate)

배열 뒤집기

배열 뒤집어서 리턴하는 문제였고, 나는 그냥 list.reverse() 해서 반환함.

다른 풀이

그냥 list[::-1] 을 반환했음.

list[A:B:C] 의미는 인덱스 A부터 B까지 C의 간격으로 배열을 만들라는 의미로,

A가 none일 경우 처음부터,

B가 none일 경우 가능한 데까지,

C가 none일 경우 1 간격임.

따라서 list[::-1]은 처음부터 끝까지 -1칸 간격으로 반환을 의미하므로 역순과 동일함.

ex) list[::2] 는 처음부터 끝까지 두 칸 간격으로 배열 반환

ex) list[3::-1] 은 인덱스 3부터 끝까지 -1칸 간격으로 즉 인덱스 3부터 역순으로 반환

++ 문자열에도 적용 가능함 !


짝수 홀수 개수

난 그냥 함.

다른 풀이

answer = [0,0]

for n in num_list:

   answer[n%2]+=1

return answer

오 ...


etc.

딕셔너리

dic = {'2':'0', '0':'5', '5':'2'} # 키:값

dic[키] 로 사용

 

---

 

문자열 붙이기

answer = ''

answer = answer + dic[키] # 변수여도 그냥 + 연산자로 가능

 

위 둘을 합치면

rsp는 변수, d라는 딕셔너리

=> return ''.join(d[i] for i in rsp)

 

---

 

append()로 다차원 배열을 만들 수 있음

 

---

 

길이가 3인 box 배열이 있을 때, 각 원소에 대해 변수를 바로 지정 가능함.

ex) x, y, z = box

 

---

 

합성수 찾기

뭔지알기

 

---

 

⭐ 소인수분해

'Algorithm' 카테고리의 다른 글

배열 채우기  (0) 2021.12.06
진수 변환  (0) 2021.11.12