문제는 다음과 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

 

풀이과정

 

 

코드

 

progresses=[933055

speeds=[1305]

a=[]

b=[]

c=[]

 

#남은 처리 기간을 계산해서 리스트 a에 추가한다.

while progresses:

  if (100-progresses[0])%speeds[0]==0:

    a.append((100-progresses.pop(0))//speeds.pop(0))

  else:

    a.append(((100-progresses.pop(0))//speeds.pop(0))+1)

 

#처리 기간별 배포되는 기능의 수를 계산한다.

while a:

  b.append(a.pop(0))

  if len(b)==1:

    c.append(1)

  elif max(b[:-1])<b[-1]:

    c.append(1)

  else:

    c[-1]+=1

c

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/12899

 

코딩테스트 연습 - 124 나라의 숫자

 

programmers.co.kr

 


풀이는 다음과 같습니다.

 

1. 124나라는 우리가 사용하는 10진법 체계에서 3진법으로 바꾼 후 새로운 규칙을 더해 변형된 숫자를 이용한다.

 

2. 10진법에서 3진법으로 바꾸는 방식은 아래와 같다. 

(10진법 숫자 45를 3진법 숫자 1200으로 바꾸는 과정이다.)

 

[10진법->3진법]

 

그림에서 45를 3으로 나눈 몫(15)는 아래에, 나머지(0)은 왼쪽에 둔다. 몫을 3으로 다시 나눠서 나온 몫(5)는 아래에, 나머지(0)은 왼쪽에 둔다. 이와 같은 과정을 반복한다.

 

3. 124나라는 1은 1, 2는 2, 3은 4로 표현한다. 이것을 참고해 1200을 변환한다.

여기서 0은 어떻게 변환되는지 알 수 없다. 이 때 새로운 규칙이 도입된다.

 

새로운 규칙: 나머지가 0인 경우, 몫에서 1을 빼고, 나머지는 3으로 바꾼다.

 

새로운 규칙을 적용해 45라는 숫자를 변형하는 과정은 아래와 같다.

 

[10진법 -> 3진법+새로운 규칙]

 

4. 마지막으로 1123에서 3을 4로 바꾸면, 최종적으로 1124가 나온다.


제 CODE는 다음과 같습니다.

dic={1:'1',2:'2',3:'4',0:''}

n=45

s=[]

ss=''

 

while n>=3:

 

  if n%3==0 and (n//3==3 or n//3==2 or n//3==1):

    n=n//3-1

    s.append(3)

    s.append(n)

  elif n%3==1 and (n//3==2 or n//3==1):

    n=n//3

    s.append(1)

    s.append(n)

  elif n%3==2 and (n//3==2 or n//3==1):

    n=n//3

    s.append(2)

    s.append(n)

 

  elif n%3==0:

    n=n//3-1

    s.append(3)

  elif n%3==1:

    n=n//3

    s.append(1)

  elif n%3==2:

    n=n//3

    s.append(2)  

 

while s:

  ss+=dic[s.pop()]

ss

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/17676

 

코딩테스트 연습 - [1차] 추석 트래픽

입력: [ "2016-09-15 20:59:57.421 0.351s", "2016-09-15 20:59:58.233 1.181s", "2016-09-15 20:59:58.299 0.8s", "2016-09-15 20:59:58.688 1.041s", "2016-09-15 20:59:59.591 1.412s", "2016-09-15 21:00:00.464 1.466s", "2016-09-15 21:00:00.741 1.581s", "2016-09-1

programmers.co.kr

풀이

def solution(lines):

    from datetime import datetime
    temp_1=[]
    answer=0
	
    #1초라는 범위 안에서 겹치는 과정이 몇 개인지 찾는 함수이다.
    def func(log, start, end): 
        cnt = 0 
        for x in log: 
            if x[0] < end and x[1] >= start: 
                cnt += 1 
        return cnt

    for e in lines:
        a=datetime.strptime(' '.join(e.split(' ')[0:2]), '%Y-%m-%d %H:%M:%S.%f') 
        #문자열을 날짜 및 시간 형태로 변환(1)
        
        b=datetime.strptime('2016-09-15 00:00:00.000', '%Y-%m-%d %H:%M:%S.%f') 
        #문자열을 날짜 및 시간 형태로 변환(2) - 기준 시간[원점]
        
        c=int((a-b).total_seconds() * 1000) 
        # a시간과 b시간의 차이를 '초'로 구한다. 밀리초로 변환하기 위해 1000을 곱한다.float 형태 -> integer 형태, 이것은 끝나는 시간이다
        
        d=c-int(float(e.split(' ')[2][:-1])*1000)+1 
        #시작 시간을 구하기 위해 c에서 그만큼을 뺀다. 
        
        temp_1.append([d,c]) 
        #[[시작시간1, 끝나는시간1],[시작시간2, 끝나는시간2], [시작시간3, 끝나는 시간3]] 식으로 정리된다.

    for x in temp_1: 
        answer = max(answer, func(temp_1, x[0], x[0] + 1000), func(temp_1, x[1], x[1] + 1000))  
        
    return answer
 

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/67257

 

코딩테스트 연습 - 수식 최대화

IT 벤처 회사를 운영하고 있는 라이언은 매년 사내 해커톤 대회를 개최하여 우승자에게 상금을 지급하고 있습니다. 이번 대회에서는 우승자에게 지급되는 상금을 이전 대회와는 다르게 다음과

programmers.co.kr

풀이

def solution(expression):

    from functools import reduce
    import re

	#세 개의 연산자가 있을 때 경우의 수
    cal1=[['*','+','-'],['*','-','+'],['+','*','-'],['+','-','*'],['-','+','*'],['-','*','+']]
    s=expression
	
    #세 종류의 연산자가 주어질 때 연산하기
	def func3(A,s):
        for i in re.split('['+str(A[1])+str(A[2])+']',s):
            if A[0] in i:
                s=s.replace(i,str(eval(A[0].join([str(n) for n in i.split(A[0])])))) 
        for i in re.split('['+str(A[2])+']',s):
            if A[1] in i:
                s=s.replace(i,str(eval(A[1].join([str(n) for n in i.split(A[1])]))))
        return abs(eval(A[2].join([str(n) for n in s.split(A[2])])))
	
    #두 종류의 연산자가 주어질 때 연산하기
	def func2(A,s):
        for i in re.split('['+str(A[1])+']',s):
            if A[0] in i:
                s=s.replace(i,str(eval(A[0].join([str(n) for n in i.split(A[0])])))) 
        return abs(eval(A[1].join([str(n) for n in s.split(A[1])])))
    
    #한 종류의 연산자가 주어질 때 연산하기
    def func1(A,s):
        return abs(eval(A.join([str(n) for n in s.split(A)])))
    
    #연산자가 몇 종류 있는지 알아보기
    cal0=[]
    if '-' in s:
        cal0.append('-')
    if '+' in s:
        cal0.append('+')
    if '*' in s:
        cal0.append('*')
    
    #계산된 값들 중 최대값 반환하기
    b=[]
    if len(cal0)==3:
        for a in cal1:
            b.append(func3(a,s))
        return max(b)
    if len(cal0)==2:
        for a in [cal0[::-1],cal0]:
            b.append(func2(a,s))
        return max(b)
    if len(cal0)==1:
        return func1(cal0[0],s)

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/62048

 

코딩테스트 연습 - 멀쩡한 사각형

가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을

programmers.co.kr

풀이

#규칙성 찾기가 가장 중요함
def solution(w,h):
    def GCD(A,B): return B if (A==0) else GCD(B%A,A)   #최대공약수구하기
    def func(A,B):return func(A//GCD(A,B),B//GCD(A,B))*GCD(A,B) if GCD(A,B)!=1 else A+B-1
    #재귀함수이용하기
    return w*h-func(w,h)

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/60057

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문

programmers.co.kr

풀이

def solution(s):
    a=1
    k=[]
    b=''
    if len(s)==1:
        return 1
    for j in range(1,len(s)//2+1):
        b=''
        for i in range(0,len(s)-j+1,j) if len(s)%2==j else range(0,len(s),j):
            if s[i:i+j]==s[i+j:i+j+j]:
                a+=1
            else:
                if a>1:
                    b+=str(a)+s[i:i+j]
                    a=1
                else:
                    b+=s[i:i+j]
        k.append(len(b))
    return min(k)

 

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/81301

 

코딩테스트 연습 - 숫자 문자열과 영단어

네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다. 다음은 숫자의 일부 자

programmers.co.kr

풀이

 

def solution(s):
    kk={}
    kk_sorted=[]
    string=['zero','one','two','three','four','five','six','seven','eight','nine']
    import re
    for aa in range(len(string)):
        for i in [m.start() for m in re.finditer(string[aa], s)]:
            kk[i]=aa
        for j in [m.start() for m in re.finditer(str(aa), s)]:
            kk[j]=aa
    for i in sorted(kk.items()):
        kk_sorted.append(str(i[1]))
    return int(''.join(kk_sorted))

 

1단계. string에 해당하는 문자열의 위치를 찾고 딕셔너리 형태로 변환합니다.

Ex) {3: 'one'} : 세번째 위치에 one이 있다.

2단계. number에 해당하는 문자열의 위치를 찾고 딕셔너리 형태로 변환합니다.

Ex) {4: 1} : 네번째 위치에 1이 있다.

3단계. 위치 기준으로 딕셔너리를 정렬합니다.

4단계. 정렬한 딕셔너리의 값을 합쳐서 숫자로 반환합니다.

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/77484

 

코딩테스트 연습 - 로또의 최고 순위와 최저 순위

로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1 순위 당첨 내용 1 6개 번호가 모두 일치 2 5개 번호

programmers.co.kr

풀이

 

def solution(lottos, win_nums):
    count_same=0
    count_mask=0
    answer=[]
    for i in range(len(lottos)):
        if lottos[i] in win_nums:
            count_same+=1
        elif lottos[i]==0:
            count_mask+=1
    return [len(lottos)+1-(count_same+count_mask) if len(lottos)+1-(count_same+count_mask)<=6 else 6,
    len(lottos)+1-count_same if len(lottos)+1-count_same<=6 else 6]

 

1단계. 로또 점수와 일치하는 점수의 수를 구합니다.

2단계. 로또 점수에서 0의 개수를 구합니다.

3단계. 로또 총 개수에서 일치하는 점수, 0의 개수를 뺀 것이 최고의 순위가 됩니다.

4단계. 로또 총 개수에서 일치하는 점수를 뺀 것이 최저의 순위가 됩니다.

문제는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/72411

 

코딩테스트 연습 - 메뉴 리뉴얼

레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서

programmers.co.kr

 

풀이

 

def solution(orders, course):
    
    from itertools import combinations 
    from collections import Counter

    total=[]
    result=[]
    value_1=[]
    
    for j in course:
    
        total=[]
        value_1=[]
        
        for i in orders:
            total+=list(combinations(i, j))
    
        for idx, value in enumerate(total):
            value_1.append(''.join(sorted(list(value))))
        
        for common in Counter(value_1).most_common():
            if common[1]==Counter(value_1).most_common()[0][1] & Counter(value_1).most_common()[0][1]>1:
                result.append(common[0])
    
    return sorted(list(set(result)))

 

1단계: itertools.combinations 함수로 음식 조합을 구성합니다.

 

2단계: 1단계의 결과가 튜플 형식으로 나옵니다. 그리고 ('A', 'B'), ('C', 'D') 형식이기 때문에 'AB', 'CD'로 변환합니다.

 

3단계: 두 명 이상이 주문한 음식 조합을 선택해야 됩니다. 또한 만약에 같은 개수의 음식 조합이 존재한다면, 주문한 수가 가장 많은 음식 조합을 선택해야 합니다. 예를 들면, 네오와 어피치가 'ABC' 음식 조합을 먹었고 네오, 어피치, 프로도가 'ACE' 음식 조합을 먹었다면 'ACE'를 선택해야 합니다. 주문한 수가 더 많았기 때문입니다. 

따라서 collections.Counter 함수를 이용해서 2번 이상 주문하고 가장 많이 주문한 조합 위주로 선택해야 합니다.

 

4단계: set 함수를 이용해 중복된 결과를 제거하고 list 변환한 후 sorted 함수로 알파벳순 정렬합니다. 

 

 

 

 

 

 

 

문제

카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.

  • 아이디의 길이는 3자 이상 15자 이하여야 합니다.
  • 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
  • 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.

"네오"는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
     만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

 

풀이

[정규표현식을 이용했습니다]

def solution(new_id):
    import re
    new_id=''.join(list(re.sub('^[.]|[.]$','',re.sub('[.]{2,}','.',re.sub('[^0-9a-z._-]','',new_id.lower())))))   
    if len(new_id)==0: new_id='a' 
    elif len(new_id)>=16: new_id=re.sub('[.]$','',new_id[:15])  
    while len(new_id)<3: new_id=new_id+new_id[-1]
    return new_id

 

문제의 1~7단계 순서대로 설명드리겠습니다.

 

1단계: lower() 함수로 대문자->소문자 변경

 

2단계: re 의 sub() 함수로 숫자, 소문자, . , _ , -  제외한 나머지 문자는 공백처리

 

3단계:  . 이 두 개 이상인 경우 . 하나로 처리 re.sub('[.]{2,}','.', 문자열)

 

4단계:  ^[.] 이용,  . 이 앞에 있으면 공백처리, [.]$ 이용, . 이 끝에 있으면 공백처리

 

5단계: 문자열의 개수를 세어야 된다. 파이썬에서 길이를 재는 len함수는  '                 ' 를 0이 아닌, 칸 수만큼 개수를 내보낸다.

따라서 ''.join(list(...))를 이용해 문자열 -> 리스트 -> 공백이 없는 문자열로 변환한다.

 

6단계: 문자열의 개수가 16개 이상이면 15개까지 잘라낸다. 이후   [.]$ 이용, . 이 끝에 있으면 공백처리

 

7단계: 문자열의 개수가 3보다 작으면 문자열 개수가 3이 될때까지 마지막 문자열을 문자열 끝에 붙인다.

+ Recent posts