0315 TIL

looggi·2023년 3월 15일
2

TILs

목록 보기
36/114
post-thumbnail

빽준 문제풀기

➡️ 설탕배달

def solution(n):
    if n%5 ==0:
        return n//5
    elif n%5 in (1,3):
        return n//5+1
    elif n%5 in (2,4):
        if n in (4,7):
            return -1
        return n//5+2

N=int(input())
print(solution(N))

3,5로 구성할 수 없는 수는 4,7 뿐이고
구성할 때 최소 봉지 수를 표현하기 위해서는 5가 최대로 들어가는 게 좋다
5단위로 규칙이 있어서
kg이 5로 나누어 떨어질 때는 몫을,
나머지가 1,3 일때는 몫+1
나머지가 2,4 일때는 몫+2를 리턴한다

구성하는 수끼리의 차이가 2라서 가능했던 풀이인 것 같다

➡️ 설탕배달 다른 사람

cnt = 0

while n > 0:
    if n % 5 == 0:
        cnt += n // 5
        break
    
    n -= 3
    cnt += 1
    
    if n < 0:
        cnt = -1
print(cnt)

이게 정석 풀이인 것 같다
n이 0보다 클 때 n이 5의 배수라면 cnt에 몫만큼 더한 값을 리턴하고
아니라면 n에서 3을 빼고 3을 뺐으니까 cnt+=1
만약 3을 뺀 n의 값이 0보다 작다면 4나 7에 해당되므로 cnt에 -1을 넣어주고 n<0 이므로 반복문에서 탈출하게 된다

어떻게 보면 같다고 할 수 있는 조건이 반복돼서 밖에서 -1을 처리해주는 것도 괜찮을 것 같다

✔️ 정리

n=int(input())
cnt = 0

while n >= 0:
    if n % 5 == 0:
        cnt += n // 5
        print(cnt)
        break
        
    n -= 3
    cnt += 1
    
else: print(-1)

while문 조건에 0이 포함되지 않으면 else이하가 리턴값이 되어 틀린다
else가 없으면 while에서 cnt가 프린트 되고 난 후에-1이 또 프린트된다

✔️ 함수로 바꿔봄

def solution(n):
    cnt = 0
    while n >= 0:
        if n % 5 == 0:
            cnt += n // 5
            return cnt
        n -= 3
        cnt += 1
    return -1

n=int(input())
print(solution(n))

➡️ 1,2,3 더하기 재귀로

def solution(x):
    answer=0
    if x==1:
       return answer+1
    elif x==2:
        return answer+2
    elif x==3:
        return answer+4
    return solution(x-3)+solution(x-2)+solution(x-1)

T=int(input())
for _ in range(T):
    n=int(input())
    print(solution(n))

역시 재귀로 풀 수 있었던 문제였다
근데 더 줄일 수 있을 것 같은데.. 조건이 저 세가지를 더하는 거니까 안되려나??

다른 사람이 푼 재귀(완전탐색)

재귀: 현재 함수의 상태를 계속 넘기고 탈출조건을 만들어서 원하는 값을 출력한다

  • 탈출조건
    • 1,2,3으로 수뼟 만들어서 원하는 값 nęłź 일치한다면 성공
    • 아니라면 실패/ 추가 계산
def solution(sum,n):
    if sum>n:
        return 0
    elif sum == n: # 성공
        return 1
    curr =0
    for i in range(1,4):
        curr+=solution(sum+i,n)
    return curr

T=int(input())
for _ in range(T):
    n=int(input())
    print(solution(0,n))

한번에 이해하기가 어려워서 예를 들어보면
n=4일 때
solution(0,4)는 if문에는 걸리지 않고 curr이하의 for문에만 걸린다
결과로 리턴되는 curr은 solution(1,4)+solution(2,4)+solution(3,4)이다
solution(1,4)는 다시 if문에 걸리지 않고 curr이하에서 다시 curr을 반환한다 각각에 대해서 반환하는 값을 써보면

  • solution(1,4)->solution(2,4)+solution(3,4)+solution(4,4)
  • solution(2,4)->solution(3,4)+solution(4,4)+solution(5,4)
  • solution(3,4)->solution(4,4)+solution(5,4)+solution(6,4)

각각이 다시 solution함수를 돌 때 sum>n이면 0이고 같으면 1이므로 작은 것(블록처리한 것)에 대해서만 다시 반복문을 만들어준다

  • solution(2,4)->solution(3,4)+solution(4,4)+solution(5,4)
  • solution(3,4)->solution(4,4)+solution(5,4)+solution(6,4)
  • solution(3,4)->solution(4,4)+solution(5,4)+solution(6,4)

다시

  • solution(3,4)->solution(4,4)+solution(5,4)+solution(6,4)

결과적으로 sum<n이라면 반드시 1개 이상의 1값을 만들어내게 되고
정리해보면 sum<n이라면 sum과 n의 차이*1만큼 값을 내놓는다

무튼 따라서 solution(0,4)의 답은 7이 된다

시간은 내가 풀었던 재귀보다는 더 원초적으로 재귀라서 그런지 더 오래 걸렸는데 내가 원래 원하던 건 이거였다. 초기값을 하나도 주지 않고 1이 베이스가 돼서 타겟 값을 만드는 것🤓 최초의 비교값을 함수 자체에 넣어주면 되는데 그 생각을 못했던 것 같다 진짜 똑똑한 사람,,

➡️ 조건에 맞는 저자와 리스트 출력하기

SELECT B.BOOK_ID, A.AUTHOR_NAME, DATE_FORMAT(B.PUBLISHED_DATE,"%Y-%m-%d") AS PUBLISHED_DATE 
FROM BOOK B 
JOIN AUTHOR A
ON B.AUTHOR_ID = A.AUTHOR_ID
WHERE B.CATEGORY = "경제"
ORDER BY B.PUBLISHED_DATE

이 경우에는 조인을 쓴다면 LEFT JOIN, INNER JOIN 모두 가능하고
쓰지 않는다면 테이블 2개를 FROM 절에 그냥 나열하고

WHERE절에서 조건을 AND로 묶어서도 같은 결과를 얻을 수 있다

➡️ 조건에 맞는 다른 거

SELECT BOOK_ID, AUTHOR_NAME, DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d')
FROM BOOK as b, AUTHOR as a
WHERE b.author_id = a.author_id AND category = "경제"
ORDER BY PUBLISHED_DATE

AS PUBLISHED_DATE는 굳이 해주지 않아도 정답처리가 되는 것 같당

그리고 SQL은 대소문자를 구분하지 않는다

프로그래머스 문제풀기

➡️ 개인정보수집 유효기간

def solution(today, terms, privacies):
    terms=dict([x.split(' ') for x in terms])# 약관종류,유효기간
    # print(terms) # {'A': '6', 'B': '12', 'C': '3'}
    privacies=[x.split(' ') for x in privacies]# 날짜,약관종류
    # print(privacies) # [['2021.05.02', 'A'], ['2021.07.01', 'B'], ['2022.02.19', 'C'], ['2022.02.20', 'C']]
    today=[int(x) for x in today.split('.')]# y,m,d
    # print(today) #[2022, 5, 19]
    answer = []
    for i,p in enumerate(privacies):
        date, kinds = p
        y,m,d=map(int,date.split('.'))
        d=d+int(terms[kinds])*28
        if d>28:
            if d%28 != 0:
                m+=d//28
                d=d%28
            else:
                m+=d//28-1
                d=28
        if m>12:
            if m%12 != 0:
                y+=m//12
                m=m%12
            else:
                y+=m//12-1
                m=12

        if y<today[0]:
            answer.append(i+1)
        elif y==today[0] and m<today[1]:
            answer.append(i+1)
        elif y==today[0] and m==today[1] and d<=today[2]:
            answer.append(i+1)
            
    return answer

날짜 형태를 꼭 지킬 필요 없이 년, 월, 일을 다 일로 계산해서 비교해서 더 작은 경우에 출력하게 되면 훨씬 짧은 코드를 만들 수 있다 현타 씨게온당 핳

문제가 쉬운데 멘붕이 왔던 부분이 if m>12 if d>28 이하에서 이 변수들에 값을 재정의해줄 때였는데, m의 값을 먼저 바꾸면 뒤에 m이 들어가는 식의 값도 내가 의도한대로 나오지 않는다는 당연한 사실을 뭔가 완전히 까먹고 있었던 것 같다 ㅋㅋㅋ 진짜 갑자기 여기가 지구가 아닌가..? 하는 생각이 들었다 ㅋㅋㅋㅋ 프린트 찍으면서 너무 놀랬다 ㅋㅋㅋ

무튼 그래도 언패킹이랑 enumerate 요긴하게 써서 기분 좋게 자야겠다 🥱

profile
looooggi

1개의 댓글

comment-user-thumbnail
2023년 3월 17일

꾸준히 하는 모습 멋집니다

답글 달기