다사다난했던 2023년이 지나가고, 2024년 새해가 밝았다.
이제 새해가 밝았으니 새 마음 새 뜻으로 다시 마음을 다잡고 시작해보도록 하자.
1. 코드카타
오늘 푼 알고리즘 문제는 '체육복' 이다.
체육복 |
![]() |
![]() |
참고로, 위에는 너무 길어질까봐 넣어놓지는 않았지만 역시나 제한사항이 존재하는데, 이런 이야기를 꺼내는 데에는 제한사항에 중요한 조건이 있다는 걸 알 수 있다.
여기서 중요하게 봐야할 점은 바로 '여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다.' 이다.
이는 위의 입출력 예에서는 구현되지 않은 제한사항이라 이를 간과하고 코드를 짜다가는 오답에 도달할 가능성이 굉장히 높아지게 되므로 잘 생각하고 코드를 짜야 한다.
그렇다면 기본적인 단계부터 하나하나 밟아보자.
우선, 답을 도출해내는 방법은 2가지가 있다.
학생의 수 n에서 여벌의 체육복들을 다 돌린 뒤에 남아있는 lost의 수만큼 제외시키거나.
혹은 처음부터 학생의 수 n에서 lost의 수만큼 제외시킨 뒤에 여벌의 체육복을 돌릴 수 있는 만큼 다시 더하거나.
어떤 방식을 채택할지는 우선 제쳐두고, 이를 간단하게 표현하면 다음과 같은 식이 나온다.
answer += n - lost.size
그 다음으로는 여벌의 체육복을 처리하는 방법을 알아보자.
여기서 두 가지 경우가 있다.
1. 여벌의 체육복을 가진 학생이 도난당한 경우
2. 여벌의 체육복을 가진 학생 앞 번호 혹은 뒷 번호가 도난당한 경우
이 때, 1번의 경우가 일어나면 2번은 진행할 수 없기 때문에 순서대로 처리해야 한다.
위에서 어떤 방식을 택할지에 따라서 여기에 적을 식도 약간은 달라지지만 기본 골자는 같다.
그래서 우선은 기본 골자부터 알아보도록 하겠다.
기본 골자는 다음과 같다.
1. 여벌의 체육복을 가진 학생이 도난당한 경우
if (lost == reserve)
2. 여벌의 체육복을 가진 학생 앞 번호 혹은 뒷 번호가 도난당한 경우
if (reserve - 1 == lost || reserve + 1 == lost)
그리고 1번과 2번 공통적으로 일단 여벌의 체육복을 한 번 썼다면 그 다음에는 사용할 수 없기 때문에 목록에서 제거해야 한다.
하지만, 이 과정을 Array로는 해결할 수 없기 때문에 List로 변환해야 한다.(문제에서는 reserve와 lost 둘 다 IntArray형으로 줬다)
그리고 List로 변환한 것을 이용하여 위의 조건들을 만족하면 조건에 만족하는 lost와 reserve의 인덱스를 각각 지운다.
이를 코드로 나타내면 다음과 같다.
class Solution {
fun solution(n: Int, lost: IntArray, reserve: IntArray): Int {
var answer = 0
answer += n - lost.size
val reserveList = reserve.toMutableList()
val lostList = lost.toMutableList()
for (i in reserveList.indices) {
for (j in lostList.indices) {
if (reserveList[i] == lostList[j]) {
answer++
reserveList.removeAt(i)
lostList.removeAt(j)
break
}
}
}
for (i in reserveList.indices) {
for (j in lostList.indices) {
if (reserveList[i] - 1 == lostList[j] || reserveList[i] + 1 == lostList[j]) {
answer++
reserveList.removeAt(i)
lostList.removeAt(j)
break
}
}
}
return answer
}
}
참고로 이건 '학생의 수 n에서 lost의 수만큼 제외시킨 뒤에 여벌의 체육복을 돌릴 수 있는 만큼 다시 더하는 경우'이다.
이와 반대로 '학생의 수 n에서 여벌의 체육복들을 다 돌린 뒤에 남아있는 lost의 수만큼 제외하는 경우'는 다음과 같다.
class Solution {
fun solution(n: Int, lost: IntArray, reserve: IntArray): Int {
var answer = 0
val reserveList = reserve.toMutableList()
val lostList = lost.toMutableList()
for (i in reserveList.indices) {
for (j in lostList.indices) {
if (reserveList[i] == lostList[j]) {
reserveList.removeAt(i)
lostList.removeAt(j)
break
}
}
}
for (i in reserveList.indices) {
for (j in lostList.indices) {
if (reserveList[i] - 1 == lostList[j] || reserveList[i] + 1 == lostList[j]) {
reserveList.removeAt(i)
lostList.removeAt(j)
break
}
}
}
answer += n - lost.size
return answer
}
}
2. 팀 프로젝트 결산 (영상 첨부)
1주일 간 진행했던 첫 팀 프로젝트가 오늘 발표를 끝으로 끝맺음을 했다.
코드를 집중적으로 만들고 수정했던 기간은 지난주 금요일까지였지만, 세부적으로 추가하고 싶은 기능이나 수정할 부분 등의 이유로 연휴 동안에도 수시로 수정했고 그렇게 새해가 지나고 나서야 최종 완성되었다.
오늘은 지난 1주일 동안 만들었던 팀 프로젝트의 결과물을 한 번 알아보기로 하자.
최종 결과물
우선 우리 조가 완성시킨 최종 결과물을 실제로 돌린 영상부터 보도록 하자.
원래는 로그아웃 기능이 없었는데 마지막에 팀원이 직접 로그아웃 기능까지 구현하였다. (대단한 솜씨)
다만, 최종 결과물을 직접 가동하고나서야 깨달은 사실이 하나 있는데 현재 마이페이지에는 각 트랙마다 다른 글을 노출시키도록 구현되어 있고, 마이페이지에 자신이 쓴 글을 누르면 똑같이 DetailPage로 이동하도록 구현시켰지만, 분명 다른 글인데 같은 글로 이동하는 치명적인 결함이 있었다. 예를 들어서, 트랙은 iOS, 혹은 Unity이고 글제목 또한 그에 맞게 노출되어 있는데 막상 눌러서 이동하면 Android의 게시글로 이동한다던가.
이는 코딩에서 각 경우마다 다른 액티비티로 이동시켜야 하는 구문을 추가했어야 했는데 실수로 그걸 빠뜨려먹었다.
(이 다음에 피드백 파트가 있지만 이건 내 자체적인 피드백이므로 여기다가 적었다.)
피드백
다음은 우리 조의 최종 결과물을 발표한 뒤에 받은 피드백들이다.
- 익명 커뮤니티 컨셉은 꽤나 좋은 아이디어였음.
- 로그인화면부터 노출시키지 않고 메인화면부터 노출시키는 점이 좋았음.
- UI 디자인이 아쉬웠음.
- 유효성 검사 메시지를 hint 형식으로 보여주는 것이 좋을 듯.
- 비밀번호 확인 메시지도 추가하면 좋을 듯.
- Figma 활용을 조금 더 잘 하면 좋을 듯. (앱 외적)
그 중에서도 가장 많이 받은 피드백은 역시 '상대적으로 빈약한 UI 디자인'이었다.
다른 조와 비교했을 때, 기능적으로나 완성도 측면에서는 좋은 평가를 받았지만 UI 디자인이 굉장히 날것의 무언가라는 느낌을 받았다. 마치 다른 조는 앱을 만들었다는 느낌이라면 우리 조는 과제를 만들었다는 느낌이라고 하시더라.
UI 설계 자체는 나쁘지 않았다는 의견을 받았으니 다음번에는 디자인에 좀 더 신경을 쓰기로 마음먹었다.
'[TIL][내일배움캠프]' 카테고리의 다른 글
[내일배움캠프][TIL] 24.01.04 (목) - Android 앱개발 숙련 - RecyclerView (1) | 2024.01.04 |
---|---|
[내일배움캠프][TIL] 24.01.03 (수) - Android 앱개발 숙련 - ViewBinding (1) | 2024.01.03 |
[내일배움캠프][TIL] 23.12.29 (금) - 팀 프로젝트 4일차 : 팀 프로젝트 앱 완성시키기 (1) | 2023.12.29 |
[내일배움캠프][TIL] 23.12.28 (목) - 팀 프로젝트 개발 3일차 : 다른 Activity와 상호작용 (0) | 2023.12.28 |
[내일배움캠프][TIL] 23.12.27 (수) - 팀 프로젝트 개발 2일차 : 개발 초기 (1) | 2023.12.27 |