오늘은 오전에 독서와 함께, 알고리즘 문제를 풀이하고, 하루 종일 어제 해결하지 못한 프로젝트 문제 해결을 위해 노력했다.. 오늘 날씨가 하눌에 구멍이 난것처럼 비가오고 했는데, 마치 내 마음같았다.. 뜨아아아아ㅏㅏ가!! 뭐가 문제일까?!!!! 하는 내 마음이랄까..? 그래도 포기하지 않고 계속할 수 있음에 감사한다..
알고리즘 문제 풀이
원래 목표였던 7월 알고리즘문제 풀이 및 코딩 테스트 대비를 제대로 해보려고한다. 언어는 파이썬을 사용하는 것이 아닌, 코틀린(혹은 자바)를 사용하여 풀이를 진행하고자 한다. 보통 주말에 SQL 문제만 풀었는데, 이것은 그대로 하고, 하루에 2~3시간은 알고리즘을 문제풀이하려고한다. 풀이시간은 난이도 별로 10분, 20분, 40분으로 정해놓고 풀고자한다. 시간 내에 못풀면 다른사람의 풀이를 보고 공부하는 방식으로 남은 7월을 보내고자한다.
오늘 풀어본 문제는 2309번: 일곱난쟁이 와 4344번: 평균은 넘겠지 문제를 풀어보았다. 기존 파이썬으로는 풀어본 경험이 있어서, 쉽게 풀릴 것이라고 생각했는데, 내 생각을 코틀린으로 옮기는 것이 어려웠다. 특히 입력 받는 것을 어떻게 하는지 몰라 애먹었다.
일곱 난쟁이
2309번: 일곱 난쟁이
아홉 개의 줄에 걸쳐 난쟁이들의 키가 주어진다. 주어지는 키는 100을 넘지 않는 자연수이며, 아홉 난쟁이의 키는 모두 다르며, 가능한 정답이 여러 가지인 경우에는 아무거나 출력한다.
www.acmicpc.net
문제를 보고서는 너무 쉽게 풀리겠는걸? 하는 생각이 들었었다. (하지만, 입력을 어떻게 받는지 몰라 한참을 헤맸다..) 아이디어는 완전 탐색이다. 합이 100이된다는 것을 참고하여, 기준을 두명을 선택하고 이를 계산했다.
fun main() {
val heights = Array(9) { 0 }
repeat(9) { heights[it]= readLine()!!.toInt() }
heights.sort()
val sum = heights.sum()
var target1 = -1
var target2 = -1
var isFinished: Boolean = false
for (i in 0 .. 8) {
for ( j in i .. 8) {
val seven = sum - heights[i] - heights[j]
if ( seven == 100) {
target1 = i
target2 = j
isFinished = true
break
}
}
if (isFinish) break
}
repeat(9) {
if ( it != target1 && it != target2) {
println(heights[it])
}
}
분명 이것이 효율적인 문제 풀이 방법은 아니겠다는 생각이 든다.(다른사람들의 풀이를 참고해봐야겠다.) 일단은 내 생각을 구현하는 것을 목표로 하였다.
평균은 넘겠지
4344번: 평균은 넘겠지
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다. 정답과 출력값의 절대/상대 오차는 10-3이하이면 정답이다.
www.acmicpc.net
이 문제도 어렵다는 생각은 들지 않았다. 하지만, 내 생각을 구현하기 위한 방법을 몰랐다..(파이썬이 자꾸만 생각났다...) 아이디어는 문제의 조건대로 평균을 구하고, 평균이 넘는 학생의 비율을 출력하면되는 문제이다.
나는 출력하는데 format을 어떻게 작성하는지, 셋째자리에서 반올림 하는 방법을 몰랐다.
import java.util.Scanner
fun main() = with(Scanner(System.`in`)){
val caseSize = nextInt()
repeat(caseSize) {
val students = nextInt()
val studentsGrades = Array(students) { 0 }
for ( i in 0 until students) {
studentsGrades[i] = nextInt()
}
val avg = studentsGrades.sum() / students
val overAvg = studentsGrades.filter { it > avg}.count()
val result = String.format("%.3f", (overAvg.toFloat() / students * 100).toDouble()) + "%"
println(result)
}
}
먼저, 이번 문제에서는 입력받는 방식을 이전 문제와는 다르게 받도록하였다. 대량의 입력을 받을 때, input 으로 하면 안된다는 기억에, 찾아보고선 이 방법을 사용해 보았다.
문자열 포매팅은 다른 언어들(PHP, Python) 와 비슷한것 같다. 그래서 좀 더 헷갈리기도 한다.. 그래도 크게 어렵지는 않았다.
프로젝트 오류
어제에 이어서 오늘도 문제 해결을 위해 열심히 머리를 굴렸다. 먼저 어제 파악한 ProductImageEntity 및 ProductImage 관련하여, 문제를 해결해보고자 하였다.
기존의 ProductImage 클래스에는 product 정보가 없었다. 해당 이미지가 어떤 상품의 이미지인지 알 수 없던 것이다. 도메인 계층을 개발할 때는 이것이 누락된 것을 인지하지 못했다가, ProductImageEntity(영속성 Entity)를 개발하면서 이 문제를 인지했다. ProductImage 클래스의 문제는 이뿐만이 아니였다.
ProductImage 클래스는 엔터티로 사용되며, 분류되었다. 그런데 나 엔터티야! 하고 이야기를 하고 있지 않았다. 이는 사소한 문제이지만, 클린 아키텍처 및 클린 코드를 위해 만들고 있는 지금 프로젝트에서는 중요한 부분이다..!(근데 내가 몰랐다는 사실에.. 쩝..)
근데 진짜 큰 문제(?)는 따로 있었다. 내가 언어적인 지식이 부족하여 문제를 해결하는데 오래걸렸다. Product 클래스 내에서 List<ProductImage> productImages 프로퍼티에서의 각 ProductImage 에 대하여, productId 를 어떻게 설정할 것인가에 대한 부분이었다.
처음에는 stream을 사용한 방법을 생각했었는데, 자꾸만 에러가 발생했다.
public void setProductIdToProductImages() {
this.productImages = productImages.stream()
.map(productImage -> productImage.setProductId(getId().getValue()))
.collect(Collect.toList())
}
당시 코드를 캡쳐해둔 것이 없어서, 기억으로 작성해본다.. 나는 반복문에 대해서 stream 을 많이 사용했었는데, 내가 stream 에 대해서 제대로 모르고 사용한다는 것을 이번에 제대로 알게 되었다. 이게 왜 안되는 것인지 알아보겠다고, 이것저것 다르게 해보는데 3시간 이상을 소모했다.. 생각하고.. 해보고.. 다시 고민하고.. 해보고... 그러다가 그냥 for 문 사용하면 쉽게 해결되는거아냐? 하는 생각에 하니깐 에러가 마법처럼(?) 사라졌다.
하지만 아쉽게도 이를 해결하고, 관련된 수 많은 파일을 수정하고도 기존의 문제는 해결되지 않았다. 그래서 나는 고민에 빠졌다.
여전히 productImageEntity가 원인이라고 하는데, 원인은 모르겠고.. 지금 이로인해 하루,그 이상을 소모할 이유가 있을까? 하는 생각에 빠졌다. 이에 대한 내 생각은 ProductImage 때문에 계속된 개발을 진행하지 못하는 것은 안되겠다는 판단으로 잠시 해당 프로퍼티 및 클래스는 주석으로 빼두고, 현 나머지 부분들을 개발 완료 후에 다시 해결해보기로 다짐했다.
그리고 ProductImageEntity 클래스 자체를 주석으로 처리 한 뒤에는 정상적으로 모든 테스트가 진행되기 시작했다. 드디어 다시 개발을 이어나갈 수 있게 된 것이다.
여기까지 오는데 하루 종일이 다 걸렸다.. 문제를 직면하면서, 정말 같이 공부하던 분들이 생각이 많이 났다. 회사에 있을 때에는 막힐 때면, 커피타임을 통해 리프레시를하고 아이디어도 얻고 다시 시작하기 좋았는데, 지금은 온전히 혼자라는 사실이 조금 속상했다..
오늘은 문자열 포매팅과 입력 방법을 공부할 수 있었다. 내일은 프로그래머스의 문제들을 풀어볼 것이다. 나는 프로그래머스와 백준 두 플랫폼에서 문제를 풀이해보려고한다. 7월동안 하루 최소 2문제씩.. 꾸준하게 한번 해보자 !!
프로젝트는 드디어 이제 DataTest를 진행하고, Adapter 계층의 out 포트중 하나인 DataAccess 를 마칠 수 있을 것 같다. 해당 계층을 어떻게 테스트하면 좋을지, 공부와 고민은 계속해서 해왔고, 테스트할 기능도 많지 않아 내일이면 작성을 마칠 수 있을 것 같다.
오늘은 비가 많이 왔다. 그리고 비가 많이오면서 책상앞에서 개발을 하고 있으니, 작년 여름 1개월, 2개월차의 내 모습이 생각이 났다. 작년과 비교하면 정말 많이 성장했다. 고민의 종류도 깊이도 많이 성숙해진 것 같다. 훌륭한 주니어 신입 개발자가 되어, 올해는 다른 개발자 동료분들과 개발을 하는 날이 왔으면 좋겠다.
'회고 > TIL' 카테고리의 다른 글
코드문제 해결, 새로운 기능 추가, 알고리즘 문제풀이 (0) | 2023.07.13 |
---|---|
만들면서 배우는 클린아키텍처 독서: 테스트, Product Adapter(out.dataaccess) 개발 및 테스트, 알고리즘 문제풀이 (1) | 2023.07.12 |
Product Adapter out 개발, 고민 (1) | 2023.07.10 |
Product DataAccess 계층 개발 시작 (1) | 2023.07.07 |
PR 피드백 반영, 편두통 (1) | 2023.07.06 |