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은 제거
- 지워지지 않은 수 중 제일 작은 2를 소수로 채택
- 나머지 2의 배수를 모두 지운다.
- 지워지지 않은 수 중 제일 작은 3을 소수로 채택
- 나머지 3의 배수를 모두 지운다.
- 지워지지 않은 수중 제일 작은 5를 선택.
- 나머지 5의 배수를 모두 지운다.
- (반복….)
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가지다.
- 문자열 전체의 짝 홀수가 아니라, 단어 별로 짝/홀수 인덱스를 판단한다
- 공백까지 포함해서 계산한다 -> 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