programmers(8-19)level_1

level1 최대한 풀자.

level1은 이제 다 풀 수 있을 것 같다. level1 다 풀고, 알고리즘 강의 완강해서 level2에 도전하자.

문제: 8. 두 정수 사이의 합

level 1 두 정수 a,b가 주어졌을 때, a와 b사이에 속한 모든 정수의 합을 리턴하는 함수 작성

def solution(a, b):
    if a > b:
        a, b = b, a
    arr = sum([i for i in range(a, b+1)])
    return arr
  • 놓친 것은 , 굳이 배열 나열해서 sum해줄 필요 없이 바로
  • sum(range(a,b+1)) 해주면 된다.
def solution(a, b):
    if a > b:
        a, b = b, a
    return sum(range(a, b+1))

문제: 9. 문자열 내 마음대로 정렬하기

문자열로 구성된 리스트 strings와 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬. ["sun", "bed", "car"] 1 ["car","bed","sun"]

  • 각 문자열의 n번째 글자를 기준으로 정렬.
  • 같은 문자열이 여럿일 경우, 사전 순으로 앞선 문자열이 앞쪽에 위치하도록
  • sorted(key = arr[i][n])을 이용해주면 되지 않을까.
def solution(strings, n):
    strings.sort()
    return sorted(strings, key=lambda strings: strings[n:n+1])
print(solution(["abce", "abcd", "cdx"], 2))
  • 배운 것 -> sorted(strings, key=lambda strings: strings[n:n+1])
  • 구글링 안하고도 찾을 수 있을 정도로 암기하자. 지금까지 문제 풀면서 최소 10번은 사용했다.

문제: 10. 문자열 내 p와 y의 개수

  • 대문자와 소문자가 섞여있는 문자열 s가 주어짐.
  • s에 ‘p’의 개수와 ‘y’의 개수를 비교해 같으면 True, 다르면 False하는 solution 완성
def solution(s):
    # s.lower()
    result = 0
    for x in s:
        if x == 'p' or x == 'P':
            result += 1
        elif x == 'y' or x == 'Y':
            result -= 1
    return True if result == 0 else False
print(solution("pyy"))

다른 사람 풀이 - count() 함수

def numPY(s):
    # 함수를 완성하세요
    return s.lower().count('p') == s.lower().count('y')
  • count() 함수란 ? : 갯수를 세는 함수다.

문제 11. 문자열 내림차순으로 배치하기

  • 문자열 s에 나타나는 문자를 큰 것부터 작은 순으로 정렬, 새로운 문자열 리턴.
  • s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 간주

생각한 방법

  • 대문자 구별하는 isupper() 함수를 활용하여 (소문자는 islower())
  • 대소문자 따로 구별해서, 이를 작은 순으로 정렬해서 합친다.
  • 리스트를 문자로 변환해주려면 join함수 필요 "".join(lower)
  • "".join(lower) “” 안에 포함해줄 구분자가 들어간다.
  • split() 함수는 문자열을 특정 ‘구분자’로 나누어 리스트로 변환한다.
def solution(s):
    lower = []
    upper = []
    for i in s:
        if i.islower():
            lower.append(i)
        else:
            upper.append(i)
    lower.sort(reverse=True)
    upper.sort(reverse=True)
    lower += upper
    return "".join(lower)


print(solution("Zbcdefg"))

다른 사람들 풀이

def solution(s):
    return ''.join(sorted(s, reverse=True))
  • 문자열을 정렬하면 대문자 A가 소문자 z보다 먼저 나온다. 이걸 몰라서 길게 코드를 작성했다.
  • 문자열 순서를 기억하자.

12. 문자열 다루기 기본

문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요 예를 들어 s가 “a234”이면 False를 리턴하고, “1234”이면 True를 리턴하면 됩니다.

  • python에서는 주어진 문자열이 숫자로 되어 있는지 검사하는데, x.isdigit()을 사용할 수 있다.
  • 주의해야할 건, x = '3² 또한 isdigit()함수로는 True가 나오기 때문에
  • 정수형으로 안전하게 바꿔주기 위해서는 x.isdecimal()을 쓰는게 낫겠다.
def solution(s):
    return True if (len(s) == 4 or len(s) == 6) and s.isdecimal() else False
print(solution("1233"))

  • 여기서 더 줄일 수 없을 줄 알았는데, 이런 방법이 있었다.
def solutions(s):
    return s.isdigit() and len(s) in (4, 6)
  • len(s) 또한 in을 써서 판별할 수 있다.
  • 또한 True를 쓰지말고 그냥 입력해도 된다.
  • (len(s) == 4 or len(s) == 6) and s.isdecimal()

13. 서울에서 김서방 찾기

  • String 배열 seoul의 element 중 “Kim”의 위치 x를 찾아 “김서방 x에 있다”는 String을 반환하는 함수 solution을 완성하시오
def solution(s):
    return "김서방은 " + s.index("Kim") + "에 있다"
  • 다 풀고 나서야 find method를 활용할 수 있을 거란 생각이 들었다.
  • find는 문자열에서 쓰이는 함수이다. a.find('b') # 14 # a = "python..."
  • index 함수를 쓰면 된다.
def solution(s):
    return "김서방은 " + str(s.index("Kim")) + "에 있다"
print(solution(["Jane", "Kim"]))

다른 사람 풀이

def solution(s):
    return "김서방은 {}에 있다".format(s.index("Kim"))
print(solution(["Jane", "Kim"]))
  • format함수를 쓰는게, 굳이 str() 함수를 불러오지 않으므로 속도가 더 빠를 것이다.

14. 소수 찾기

1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수

소수는 1과 자기 자신으로만 나누어지는 수를 의미한다.

생각한 방법

  • for문 두개 돌린다.
  • 첫 번째 for문에서는 1부터 n까지
  • 두 번째 for문에서도 1부터 n까지 돌리면서
  • 첫 번째 for문의 i번째 수가, 약수의 자기 자신외에도 나누어 떨어지는 수인지 확인.

시간초과

def solution(n):
    result = 0
    for i in range(1, n+1):
        arr = []
        for j in range(2, i+1):
            print(i, j)
            if i % j == 0 and i != j:
                break
            if(i == j):
                result += 1
    return result
solution(10)
  • 에라토스테네스의 체를 이용해야 한단다.
  • 전에 풀었는데 잊어버렸었다.

    1. 1은 제거
    2. 지워지지 않은 수 중 제일 작은 2를 소수로 채택
    3. 나머지 2의 배수를 모두 지운다.
    4. 지워지지 않은 수 중 제일 작은 3을 소수로 채택
    5. 나머지 3의 배수를 모두 지운다.
    6. 지워지지 않은 수중 제일 작은 5를 선택.
    7. 나머지 5의 배수를 모두 지운다.
    8. (반복….)
def solution(n):
    # 10개라면 총 11개가 생긴다. - 인덱스를 맞춰주기 위해 한개 더 넣어준듯
    a = [False, False] + [True]*(n-1)
    primes = []
    for i in range(2, n+1):  # 2부터 10까지
        if a[i]:  # a[i]가 True 라면
            primes.append(i)
            for j in range(2*i, n+1, i):  # i=2이면 4부터 10까지 2씩 커지면서 i=3이면 6부터 10까지 3씩 커지면서
                a[j] = False
    return (len(primes))
print(solution(10))

다른 사람들 풀이

def solution(n):
    num=set(range(2,n+1)) # set으로 2부터 집합 만들어서 num에 대입

    for i in range(2,n+1):
        if i in num:
            num-=set(range(2*i,n+1,i)) ## num에서 하나씩 뺀다.
            # i가 2일 땐, 4부터 2의 배수 제거, 3일 땐, 6부터 3의 배수 제거
    return len(num)

15. 수박수박수박수박수?

길이가 n이고 “수박수박수…“와 같은 패턴을 유지하는 문자열을 리턴하는 함수, 솔루션을 완성하세요

def solution(n):
    result = ""
    mok = n//2
    if n % 2 == 0:
        result = "수박"*mok
    else:
        result = "수박"*mok+"수"
    return result

다른사람들 풀이

def solution(n):
    return ("수박"*n)[0:n]

문자열이기 때문에, 슬라이스 연산을 잘 활용해주면 간단히 풀린다.

16. 문자열을 정수로 바꾸기

문자열 s를 숫자로 변환한 결과를 반환하는 함수 완성

def solution(s):
    return(int(s))

17. 시저암호

알파벳을 일정한 거리만큼 밀어서 다른 알파벳을 바꾸는 방식을 시저 암호라고 한다. “AB”는 1만큼 밀면 “BC”가 되고 3만큼 밀면 “DE”가 된다. “z”는 1만큼 밀면 “a”가 된다.

def solution(s, n):
    lower = "abcdefghijklmnopqrstuvwxyz"
    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    result = ""

    for x in s:
        if x in lower:
            result += lower[(lower.index(x)+n) % 26]
        elif x in upper:
            result += upper[(upper.index(x)+n) % 26]
        else:
            result += " "
    return result
  • 문자열 인덱스 뽑아낼 때 사용하는 내장 함수 - "".index("")

18. 약수의 합

  • 자연수 n을 입력 받아 n의 약수를 모두 더한 값을 리턴하는 함수, solution을 완성
  • n을 i로 나눈 나머지가 0인 수 모두 약수
def solution(n):
    return sum([i for i in range(1, n+1) if n % i == 0])

사용자 코드

# num/2 수들만 검사하면 성능이 2배 향상된다
def solution(n)
    return num + sum([i for i in range(1, (num // 2) + 1) if num % i == 0])

  • 이 사실을 나도 알고 있었다. 그렇지만 구현에 반영하지 않았던 것 같다.

19. 이상한 숫자 만들기

문자열 s는 한 개 이상의 단어로 구성되어 있다. 각 단어는 하나 이상의 공백문자로 구분 되어 있다 각 단어의 짝수번째 알파벳은 대문자로 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성

  • 문자열 전체의 짝수 홀수가 아닌, 단어 공백을 기준으로 짝수 홀수 인덱스를 판단해야 한다.
  • 즉 문자열을 나눠서 판단해야한다.

  • 공백이 ‘‘한칸만 입력되는 것이 아니기 떄문에, 긴 공백들을 처리해줘야 한다. 그걸 못해줘서 실패했다.
def solution(s):
    arr = s.split(" ")
    result = ""
    for i, y in enumerate(arr):
        for idx, x in enumerate(y):
            if idx % 2 == 0:
                result += x.upper()
            else:
                result += x.lower()
        if(i != len(arr)-1):
            result += " "
    return result

결국 이 문제에서 함정은 2가지다.

  1. 문자열 전체의 짝 홀수가 아니라, 단어 별로 짝/홀수 인덱스를 판단한다
  2. 공백까지 포함해서 계산한다 -> split()함수 괄호안 구분자에 “ “을 넣어줘야 한다.

참고 코드

res = []
    for x in s.split(' '):
        word = ''
        for i in range(len(x)):
            c = x[i].upper() if i % 2 == 0 else x[i].lower()
            word = word + c
        res.append(word)
    return ' '.join(res)
  • for x in s.split(' ') 이렇게 사용해줌으로써, list에 넣어서 사용해줄 필요가 없어졌다. 애초에 리스트를 반환하기 때문이다. 변수 하나 줄일 수 있는 것
  • if, else문 삼항연산자로 간결하게 표시해줬다.
  • 마지막에 리스트에 넣어준 뒤, 내 경우는 예외 처리를 통해서 마지막의 경우에는 “ “ 공백을 제거해줬다.
  • 이 분은 for문 바깥에서 전체 리스트를 선언한 뒤, for문 안에 word를 넣어주고 이를 전체리스트에 더해주는 방식을 사용했다.
  • 위의 방법을 사용하면, index를 통해 예외처리를 해줄 필요가 없다.
  • 이 분은 ' '.join(res)을 통해서 이를 처리해줬다. 리스트에서 문자열로 변환해주는 함수다.

내 코드를 변환시키면 이렇게 되겠다.

def solution(s):
    arr = []
    for i in s.split(" "):
        word = ""
        for idx, x in enumerate(i):
            c = x.upper() if idx % 2 == 0 else x.lower()
            word += c
        arr.append(word)
    return " ".join(arr)

참고자료 [프로그래머스]https://programmers.co.kr/learn/challenges [sorted(key=lambda arr: arr[2])]https://wayhome25.github.io/python/2017/03/07/key-function/ [파이썬_문자열_숫자판별함수]https://soooprmx.com/archives/10159 [에라토스테네스의 체]https://wikidocs.net/21638

0%