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

 

코딩테스트 연습 - 조이스틱

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다

programmers.co.kr


내 풀이

 

def solution(name):
    original_l = 'a' * len(name)
    original_U = 'A' * len(name)
    answer= 0
    count = len(name) - 1
    
    for i in range(len(name)):
        answer +=min( abs( ord(name[i]) - ord(original_U[i]) ), abs( ord( original_l[i])-6-ord(name[i])))
        
        next_idx = i + 1
        while next_idx < len(name) and name[next_idx] == 'A':
            next_idx += 1
        
        count = min([count,2 *i + len(name) - next_idx, i + 2 * (len(name) -next_idx)])
            
    answer += count
    
    return answer

첫째로 구해야 할것은

알파벳을 몇개나 바꿔야 하는가.

이는 아스키코드로 알 수 있는데

A=65이다. 근데 우리가 하나 유념해야할것은, 비록 대문자만 받아들인다고 하더라도 거꾸로 갈 경우도 있다는것이다.

예를들어 A=65, Z=90 이므로 90 - 65 = 25로 총 25번을 움직여야하는데 실제로는 한번만 움직이면 된다.

그래서 내가 생각한 방법이 소문자 a에서 빼는것인데 소문자 a=97 이다.

근데 97 - 90 = 7이다. 그 이유는 대문자와 소문자 사이에 특수문자 6개가 있어서이다.

그래서 소문자 - 대문자 - 6을 해줘야한다. 

유니코드

(대문자 - 대문자),(소문자 - 대문자 - 6 ) 중에 더 작은 수를 택하면 된다.

 

두번째로 생각해볼 내용은

좌로 가는게 유리한지 우로 가는게 유리한지를 생각해봐야 한다.

가장 단순한 방법은 바꿔줘야 할 문자가 존재하든 존재하지 않든, 우로 쭉 가는것이다.

이 경우 문자열의 길이 - 1 만큼 바꿔주면 된다.

두번째로는 'A'를 만나기전까지 우측으로 가다가 'A'를 만나면 좌측으로 가고, 최초에 만난 'A'를 만나기전까지 좌측으로 가는 방법이다.

세번째는 두번째 방법과 동일한데 좌측을 먼저 탐색하는것이다.

 


다른사람의 풀이

 



 

'취준 > 프로그래머스' 카테고리의 다른 글

괄호 회전하기 - 파이썬  (0) 2022.07.25
게임 맵 최단거리 - 파이썬  (0) 2022.07.05
소수 찾기 - 파이썬  (0) 2022.07.02
가장 큰 수 - 파이썬  (0) 2022.07.01
프린터 - 파이썬  (0) 2022.06.27

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

 

코딩테스트 연습 - 소수 찾기

한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이

programmers.co.kr


내 풀이

 

from itertools import permutations
def solution(numbers):
    answer=0
    pem = []
    n = [k for k in numbers]
    
    for i in range(1,len(numbers)+1):
        pem += list(permutations(n,i))
    
    
    candi = [int(("").join(p)) for p in pem]
    new_candi = list(set(candi))
    

    for j in new_candi:
        
        if j<2:
            continue
        is_prim = True
        for i in range(2,int(j**0.5)+1):
            
            if j%i==0:
                is_prim=False
                break
                
        if is_prim:
            answer+=1
            
            
    return answer

 


예전에 풀었던 소수찾기를 응용한 버전이다.

문제를 풀면풀수록 permutation,combination은 쓸일이 정말 많다라는것을 느낀다.


다른사람의 풀이

from itertools import permutations
def solution(n):
    a = set()
    for i in range(len(n)):
        a |= set(map(int, map("".join, permutations(list(n), i + 1))))
    a -= set(range(0, 2))
    for i in range(2, int(max(a) ** 0.5) + 1):
        a -= set(range(i * 2, max(a) + 1, i))
    return len(a)

a |= 라는 표현을 처음봤는데

어느정도 예상이 되는 연산이였고 or 연산자를 이용한 union 연산이라고 생각하면 된다.

 

s1 = {"a", "b", "c"}
s2 = {"d", "e", "f"}

print(s1 | s2)
# {"a", "b", "c", "d", "e", "f"}
print(s1)
# {"a", "b", "c"}


s1 |= s2

print(s1)
# {"a", "b", "c", "d", "e", "f"}

 


 

'취준 > 프로그래머스' 카테고리의 다른 글

게임 맵 최단거리 - 파이썬  (0) 2022.07.05
조이스틱 - 파이썬  (0) 2022.07.03
가장 큰 수 - 파이썬  (0) 2022.07.01
프린터 - 파이썬  (0) 2022.06.27
튜플 - 파이썬  (0) 2022.06.23

https://programmers.co.kr/learn/courses/30/lessons/42746?language=python3 

 

코딩테스트 연습 - 가장 큰 수

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요. 예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰

programmers.co.kr


내 풀이

def solution(numbers):
    answer = ""
    
    numbers.sort(key = lambda x : str(x) * 3, reverse = True)
    return str(int("".join((map(str, numbers)))))

 

우선 내 최초의 접근방법은 이랬다.

 

 

가장 큰 수를 만드려면 자리수와 상관없이 앞 자리수가 커야한다.

앞 자리수가 같다면 두번째 자리수를 비교한다.

두번 째 자리수도 같다면 세번째 자리수를 비교한다.

여기서 관건은 자리수가 다른애들의 비교였다.

 

두번 째 예시의 정답이

9534330 인데 앞자리가 다른 9 5 는 제외하고

34 30 3 을 어떻게 비교해야 최대 수가 나오는지를 생각해보면

4 0 ? 을 비교해야하는데 어떻게 비교할것인가 였다.

이에대해 34 3 30 순으로 정렬된것을 보고 아, 일의자리수를 비교하되 자리수가 맞지않으면 늘려주면 되겠구나 하고 생각했다.최초에는 필요한 자리수만큼 곱해줬는데 그럴 필요없이 그냥 3자리수를 만드는게 더 낫다 라는 생각이 들었다.


num_list = [-1, 0, 1, 3, 4, 5, 9]

print(num_list)
# [-1, 0, 1, 3, 4, 5, 9]
print(" ".join(map(str, num_list)))
# -1 0 1 3 4 5 9

 

추가로 int형을 join하는 방법이다.


다른사람의 풀이

 

def solution(numbers):
    numbers = list(map(str, numbers))
    numbers.sort(key=lambda x: x*3, reverse=True)
    return str(int(''.join(numbers)))

이렇게까지 유사한 풀이는 잘 없었는데 신기하다.


개인적으로 풀이는 짧아도 얻어갈게 많은 문제라고 생각한다.

 

'취준 > 프로그래머스' 카테고리의 다른 글

조이스틱 - 파이썬  (0) 2022.07.03
소수 찾기 - 파이썬  (0) 2022.07.02
프린터 - 파이썬  (0) 2022.06.27
튜플 - 파이썬  (0) 2022.06.23
뉴스 클러스터링 - 파이썬  (0) 2022.06.15

 

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

 

코딩테스트 연습 - 프린터

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린

programmers.co.kr


내 풀이

 

 

def solution(priorities,location):
    M = max(priorities)
    answer=1
    while True:
        tem = priorities.pop(0)
        if M == tem:
            if location ==0:
                return answer
            else:
                answer +=1
                location -=1
            M = max(priorities)
            
            
        else:
            priorities.append(tem)
            if location==0:
                location = len(priorities)-1
            else:
                location -=1
    return answer

최초의 문제를 봤을 때 생각나는 풀이법은, 우선순위 큐였다.

실제로 문제가 그걸 원하기도 했고 다만 다른점은 우선순위 큐는 우선순위대로 출력을 하는것이고

얘는 출력할 당시에 우선순위가 아니면 우선순위를 최하로 밀어버리는 방식이라서 우선순위 큐로는 풀지 못했고

스택을 이용해서풀었다.

조금 생각이 필요했던 부분은, 같은 값을 가질 때 우선순위를 정하는 방법이였는데 

전체 문자열의 길이로 우선순위를 주었다.


다른사람의 풀이

 

def solution(priorities, location):
    queue =  [(i,p) for i,p in enumerate(priorities)]
    answer = 0
    while True:
        cur = queue.pop(0)
        if any(cur[1] < q[1] for q in queue): //q[1]의 요소중 단 하나라도 cur[1]보다 크다면
            queue.append(cur) 
        else:
            answer += 1
            if cur[0] == location:
                return answer

공부를 똑바로 안한 티가난다.

부끄럽지만 any라는 문법을 처음보았다.

그래서 정리해본 any 의 뜻과 사용법

 


단 하나의 요소라도 조건을 만족하면 참을 리턴한다. 비어있으면 거짓을 리턴한다.
모든 요소가 조건을 만족할 때만 참을 리턴한다.


전체적으로 문제가 어렵지는 않았는데 소요시간이 너무 오래걸렸다.

한시간 이상은 쓴거같다. 다시 좀 공부에 매진해야 할 시간이 돌아온거같다.

'취준 > 프로그래머스' 카테고리의 다른 글

소수 찾기 - 파이썬  (0) 2022.07.02
가장 큰 수 - 파이썬  (0) 2022.07.01
튜플 - 파이썬  (0) 2022.06.23
뉴스 클러스터링 - 파이썬  (0) 2022.06.15
괄호 변환 - 파이썬  (0) 2022.06.13

코딩테스트 연습 - 튜플 | 프로그래머스 (programmers.co.kr)

 

코딩테스트 연습 - 튜플

"{{2},{2,1},{2,1,3},{2,1,3,4}}" [2, 1, 3, 4] "{{1,2,3},{2,1},{1,2,4,3},{2}}" [2, 1, 3, 4] "{{4,2,3},{3},{2,3,4,1},{2,3}}" [3, 2, 4, 1]

programmers.co.kr


내 풀이

def solution(s):
    answer = []
    s = s[2:-2]
    s = s.split("},{")
    s.sort(key=len)
    
    for i in s:
        j = i.split(',')
        for k in j:
            if int(k) not in answer:
                answer.append(int(k))
    return answer

"{{2},{2,1},{2,1,3},{2,1,3,4}}" 

 

위에 친구를 예로 들어서 생각하면 들어오는 문자열의 처음과 끝 '{','}' 를 제거해준다.

가령 위에 친구를 기준으로

2,},{2,1},{2,1,3},{2,1,3,4 가 남게된다.

다음으로

split으로 }{를 기준으로 나눠주면

'2', '2,1', '2,1,3', '2,1,3,4' 남게되고 길이를 기준으로 다시 정렬해준다.

그 다음 , 를 기준으로 나눠주고 그 안에 요소들이 answer 에 없으면 더해준다.

 

 


다른사람의 풀이

def solution(s):

    s = Counter(re.findall('\d+', s))
    return list(map(int, [k for k, v in sorted(s.items(), key=lambda x: x[1], reverse=True)]))

import re
from collections import Counter

정규식으로 표현한 파이써닉한 풀이.


종강하고 오히려 더 바빠진탓에 문제를 한동안 못풀었는데 꼭 하루에 한문제는 풀어야겠따..

'취준 > 프로그래머스' 카테고리의 다른 글

가장 큰 수 - 파이썬  (0) 2022.07.01
프린터 - 파이썬  (0) 2022.06.27
뉴스 클러스터링 - 파이썬  (0) 2022.06.15
괄호 변환 - 파이썬  (0) 2022.06.13
메뉴 리뉴얼 - 파이썬  (0) 2022.06.06

내 풀이

 

def solution(str1, str2):
    comp1=[]
    comp2=[]
    a=[]
    b=[]
    str1 = str1.lower()
    str2 = str2.lower()
    
    for i in range(0,len(str1)-1):
        if (str1[i]+str1[i+1]).isalpha():
            comp1.append(str1[i]+str1[i+1])

    for i in range(0,len(str2)-1):
        if(str2[i]+str2[i+1]).isalpha():
            comp2.append(str2[i]+str2[i+1])

   
    for i in comp1: 
        temp= min(comp1.count(i),comp2.count(i))
        if i in comp2:
            if a.count(i) == temp:
                continue
            else:
                a.append(i)
    for i in comp1:
        maxs = max(comp1.count(i),comp2.count(i))
        if b.count(i) == maxs:
            continue
        else:
            b.append(i)
    for i in comp2:
        maxs = max(comp1.count(i),comp2.count(i))
        if b.count(i) == maxs:
            continue
        else:
            b.append(i)    
    print(a,b)


    hap = len(a) / len(b)
    if len(a) == len(b) == 0:
        return 65536
    answer= int(65536*(hap ))
    return answer

 

def solution(str1, str2):
    comp1=[]
    comp2=[]
    str1 = str1.lower()
    str2 = str2.lower()
    
    for i in range(0,len(str1)-1):
        if (str1[i]+str1[i+1]).isalpha():
            comp1.append(str1[i]+str1[i+1])

    for i in range(0,len(str2)-1):
        if(str2[i]+str2[i+1]).isalpha():
            comp2.append(str2[i]+str2[i+1])

    
    gyo = set(comp1) & set(comp2)
    hap = set(comp1) | set(comp2)
    
    
    if len(gyo) == len(hap) == 0:
        return 65536
    
    gyo_s = sum([min(comp1.count(i),comp2.count(i)) for i in gyo])
    hap_s = sum([max(comp1.count(i),comp2.count(i)) for i in hap])
    
    answer= int(65536*(gyo_s/hap_s ))
    return answer

두가지 정도로 풀어봤다.

결과적으로 둘다 어지러운 코드인건 맞는데 

첫 번째 풀이는 그냥 어거지로 푼 느낌이다. 주어진 조건에 따라서 그냥 코딩한거 느낌이 물씬난다.

하나도 파이써닉하지 않다.

 

그렇다고 두번째가 파이써닉하단건 아닌데, 나름대로는 머리를 쓴 풀이다.

최초에 문제풀때는

ab bc cd 가 아니라

ab cd 이런식인줄 알고 실컷 풀었더니 자꾸 오류나서 정규화로는 안되나? 하고 포기했었는데

나중에 보니까 문제를 잘못 읽은거였다. 시간이 난다면 정규화로 푼 버전도 업데이트 해봐야 겠다. 


다른사람의 풀이

import re
import math

def solution(str1, str2):
    str1 = [str1[i:i+2].lower() for i in range(0, len(str1)-1) if not re.findall('[^a-zA-Z]+', str1[i:i+2])]
    str2 = [str2[i:i+2].lower() for i in range(0, len(str2)-1) if not re.findall('[^a-zA-Z]+', str2[i:i+2])]

    gyo = set(str1) & set(str2)
    hap = set(str1) | set(str2)

    if len(hap) == 0 :
        return 65536

    gyo_sum = sum([min(str1.count(gg), str2.count(gg)) for gg in gyo])
    hap_sum = sum([max(str1.count(hh), str2.count(hh)) for hh in hap])

    return math.floor((gyo_sum/hap_sum)*65536)

 

from collections import Counter
def solution(str1, str2):
    # make sets
    s1 = [str1[i:i+2].lower() for i in range(len(str1)-1) if str1[i:i+2].isalpha()]
    s2 = [str2[i:i+2].lower() for i in range(len(str2)-1) if str2[i:i+2].isalpha()]
    if not s1 and not s2:
        return 65536
    c1 = Counter(s1)
    c2 = Counter(s2)
    answer = int(float(sum((c1&c2).values()))/float(sum((c1|c2).values())) * 65536)
    return answer

1번 풀이가 가장 좋아요를 많이 받은풀이인데

개인적으로는 이게 더 깔끔해보여서 갖고 와봤다.

풀면 풀수록 Counter는 활용할 곳이 많은 모듈같다.


솔직히 레벨 2 푼거 중에 젤 오래걸렸다 시험기간인데 시간을 너무 오래 버린거같다는 생각이 들기도 하지만..

이거 안했어도 공부 안했을꺼라고 생각하니까 나쁘진 않은거 같기도하다.

'취준 > 프로그래머스' 카테고리의 다른 글

프린터 - 파이썬  (0) 2022.06.27
튜플 - 파이썬  (0) 2022.06.23
괄호 변환 - 파이썬  (0) 2022.06.13
메뉴 리뉴얼 - 파이썬  (0) 2022.06.06
행렬 테두리 회전하기 - 파이썬  (0) 2022.06.06

+ Recent posts