오늘은 아침부터 실시간 수업이 있었다. 자바 강의에서 보충을 해주는? 그런 수업이었는데 아직도 자바와 친하지 않은 탓인지 들을수록 정신이 안드로메다로 빠지는 걸 느낄 수 있어서 내일 수업이 끝난 후 녹화된 걸 한 번 더 봐야할 듯 하다.
어제 타임어택 코딩테스트를 본 이후 매일 코딩 테스트 4개를 풀기로 했다. 낮은 레벨부터 매일 불다보면 4개월뒤면 2레벨까지는 가지 않을까?
내일배움캠프에 집중하다보니 앱개발 강의를 뒷전으로 둬서 오늘은 거의 그 강의를 보는데 시간을 쓴 것 같다. 리액트 네이티브라는 자바와 전혀 상관이 없는 언어를 공부하다보니 헷갈려서 그냥 이런 식으로 쓰이는구나 정도로 만족하고 넘어가야할 것 같다. 나한테 중요한 건 자바니까.
어제 TIL에도 적었는지 모르겠는데 코딩테스트를 파이썬으로 풀다보니 자바 공부를 거의 못하는 것 같아서 파이썬으로 푼 코딩테스트 문제를 자바로도 풀려고 자바로 자료구조를 구현하는 내용이 담긴 책을 샀는데 Interface 기능이 잘 대응된다는 내용을 보고 내가 험난한 길을 골랐구나 싶었다.
Interface... 중요하고 자주 쓰인다 하지만 내게는 아직 너무 어려운 친구 하루하루 친해지기를 바란다.
깃 강의 역시 계속해서 듣고 있다. TIL을 깃으로 관리하는게 좋다고는 하시는데 나는 이미 이 벨로그에 익숙해져서 그건 일을 두 번 하는 것 같고 공부할 시간을 TIL 작성에 소비할 수 없으니 그냥 나중에 팀 프로젝트를 하거나 프로그래머스 문제를 푼 걸 자바로 구현한 걸 올리지 않을까 싶다.
아래에는 오늘 푼 프로그래머스 코딩테스트와 다른 분들이 구현한 코드를 비교한 것이다. 자바 버전은 이 TIL 작성이 끝난 후 해보긴 할건데 한문제나 가능할런지는 미지수
문자열 자르기
def solution(A, B): answer = 0 for i in range(len(A)): if A == B: break A_a = A[:-1] A_b = A[-1:] A = A_b + A_a answer += 1 if answer == len(A): answer = -1 return answer
A문자열의 맨 뒤의 글자를 앞으로 옮기는 걸 반복할 때 몇 번을 반복하면 문자열 B와 같아지는지 횟수를 반환하고 같아질 수 없으면 -1을 반환하라는 문제였다.
문자열 자르기를 까먹어서 slice라는 글자로 뻘짓을하다가 안 되서 split이었나? 아닌데 이거는 원하는 문자열 기준으로 자르는 거잖아. 하면서 구글링을 했더니 slice를 뺀 나머지는 다 맞았더라. 그냥 문자열[:-1] 이런식으로 하면 됐는데 왜 앞에 slice로 감싸서는... 슬라이스라고 부른다고 그런 함수가 있다고 생각한 바보가 나였다.
그리고 풀면서 문제를 잘 읽어야겠다는 생각이 들었다. 맨 뒤의 문자를 잘라서 앞으로 옮기는 문제였는데 처음에는 맨 앞의 문자를 잘라서 뒤로 옮기는 걸로 구현을 해서 수정을 좀 해야했다. 이게 연습이었으니 망정이지 실제였으면 완전 다른 값을 뽑아낸 거였으니 주의할 것
이번 문제 역시나 능력자는 있으셨다. 프로그래머스는 다른 사람의 풀이를 보러가면 풀이 밑에 댓글이 달리는 기능이 있는데 감탄하는 댓글들이 쭉 달린 보자마자 와 대단하다 소리가 나오는 답이었다.
solution=lambda a,b:(b*2).find(a)
find 함수는 찾는 문자열이 존재하면 첫 글자의 인덱스를 반환하고 존재하지 않으면 -1을 반환하는 함수다. 나는 위 식을 구현하신 분들은 찾는 문자열 b를 2번 곱해서 문자열 b역시 a처럼 문자를 잘라 옮겼을 때 나올 수 있는 모든 경우의 수가 다 담기도록? 하고 그 안에서 a를 찾으셨다고 이해했다. 그리고 람다식을 써서 a, b를 매개변수로 받아 : 뒤의 식을 실행한 후 그 결과값을 solution에 넣었다고 이해했다.
역시 남의 코드를 구경하면 새로운 걸 많이 배운다고 느꼈다. 나한테는 람다가 어려운데 말이다.
잘라서 배열로 저장하기
def solution(my_str, n): answer = [] while len(my_str) > n: answer.append(my_str[:n]) my_str = my_str[n:] answer.append(my_str) return answer
문자열을 처음부터 n개 단위로 잘라 배열로 저장하라는 문제였다. 이 문제는 비교적 수월하게 푼 편이었다. 역시나 앞의 교훈을 잊고 slice 개뻘짓을 했지만 코드 수정 없이 한 번에 통과했다.
다른 분들은 역시나 한 두 줄로 끝내버리셨다.
def solution(my_str, n):
return [my_str[i: i + n] for i in range(0, len(my_str), n)]
for문을 한줄로 만든 것인데 range의 3번째 인자는 몇 개 단위로 띄어서 돌리겠다는거고 i는 range의 값이 for 앞에는 수행할 구문이 들어가는데 그 결과 값이 리스트의 형태로 저장된다고 한다. 근데 마지막에 남는 값은 어떻게 들어가지 의문이 들어서 찾아봤더니 slicing을 할 때 end의 값이 문자열보다 길어지면 문자열의 길이와 같이 취급을 한다고 한다. 싱기!
7의 개수
def solution(array): answer = 0 for i in range(len(array)): answer += str(array[i]).count('7') return answer
배열 안에서 7의 개수가 몇 개인지 구하는 문제였다. count가 특정 문자의 개수를 구하는 함수라는 건 알아서 써봤는데 int 형은 사용이 불가능하더라. 그래서 찾아보니 배열은 가능하다 해서 array.count(7)을 해봤더니 7의 개수만 나오고 77과 같이 7이 2개인 경우는 포함을 시키지 않았다.
아무리 생각해도 문자열로 바꿔서 구하는 방법 밖에 떠오르지 않아 위와 같이 구현하게 되었다.
아래는 다른 분들이 구현한 방식인데 여러 종류가 있어서 전부 가져왔다.
def solution(array):
return str(array).count('7')
얘는 아무리 찾아봐도 이해가 되지 않고 있다. 보통 배열의 요소의 형 변환이 필요할 때는 아래 코드처럼 map을 사용한다는데 list(str)과 같은 원리인걸까?
def solution(array):
return ''.join(map(str, array)).count('7')
가장 맨 위에 있던 코드고 가장 정석인 코드이다. map을 사용해 array의 요소를 꺼내와 str로 변환해주고 join으로 모두 합쳐 문자열로 만든 후 7의 개수를 count 해준 코드였다. 리스트를 문자열로 변환하는 코드를 찾다보니 map과 join이 함께 따라 나왔는데 join은 합치려는 배열 안에 숫자형이 있으면 오류가 나기 때문에 전부 문자형으로 바꿔주어야 한다고 한다.
리스트를 문자열로 변환해주는 것에 대해 찾다보니 한 블로그에서 for문을 한줄로 쓴 것과 map을 쓴 것을 다 보여줬는데 확실히 map이 훨씬 간결했다.
def solution(array):
answer = sum([str(i).count("7") for i in array])
return answer
이건 내가 위에서 언급한 것과 같이 for문을 사용해 리스트들의 요소들을 문자열로 바꿔준 것인데 이 분의 경우에는 리스트들을 join으로 합치지 않고 각 요소마다 count를 해서 7의 개수를 sum으로 합친식으로 구현하셨다. 아마 내가 여기서 조금 더 발전하면 이 분과 같은 식으로 구현하지 않을까?
문자열 정렬하기
def solution(my_string): return ''.join(sorted(my_string.lower()))
매개변수로 받은 문자열을 전부 소문자로 변환후 알파벳순으로 정렬해서 출력하라는 문제였다.
그동안 프로그래머스 코딩테스트 문제를 풀면서 가장 쉬운 문제였다고 생각이 드는데 다른 분들의 풀이 역시 여기서 크게 벗어나지 않아 가져오지 않았다.
다만 쉬웠다 해도 내게는 문자열을 소문자로 변환하는 lower부터 구글링을 해야했으니 금방 푼 건 아니다. lower을 하고 sort를 해주려니 sort가 아니라 sorted여서 아하 하고 그대로 return 하려니 배열로 출력이 되서 join을 써야 한다는 걸 알았다. 이 역시 위의 문제를 풀고 다른 분들이 풀이 한 것을 보면서 이렇게 쓰이는구나를 안 덕에 푼 것이니 아마 위와 같은 과정이 없었다면 개고생을 좀 하지 않았을까?