20231207 TIL
1. 코드카타
오늘부터 조금씩 어려워지는 것 같다. 원래 코드카타는 아예 안 보고 풀려고 했는데 이젠 내가 배웠던 기초들만으로는 바로 풀기에 무리가 있다고 판단해서 부분적으로 검색하고 적용하며 사용법을 익히는 방식으로 풀었다.
그리고 앞으로는 모르는걸 공부하고 따로 정리해야할 필요를 느꼈다.
짝수의 합
class Solution {
fun solution(n: Int): Int {
var answer: Int = 0
for (e:Int in 1 .. n) {
if (e % 2 == 0) {
answer += e
}
}
return answer
}
}
for 안에 e를 int 로 지정하고 1부터 .. n까지를 반복한 뒤 if에서 e를 2로 나눈 나머지의 값이 0과 같을경우 정답을 전부 더하라는 의미로 이해했다. for 문을 쓰는것까지는 생각했는데 나머지를 응용하는데까지 떠올리기가 오래 걸렸다.
배열의 평균값
class Solution {
fun solution(numbers: IntArray) = numbers.average()
}
여기서 처음으로 average() 를 배웠다. 다른 사람이 푼 해답을 보니 size도 있었는데 풀고나서 궁금해서 찾아봤다.
average() 자체가 평균값을 구해주는 함수라고 한다.
size는 array 와 list 의 크기를 찾아준다고 한다. 이 말만 봤을때는 바로 이해가지 않았는데 검색해본 예제를 내가 직접 테스트해보니 무슨 의미인지 알 수 있었다.
fun main() {
val array = IntArray(12)
val array_size = array.size
println(array_size)
// 답은 12
val list = listOf(1, 2, 3, 4, 5, 6, 7)
val list_size = list.size
println(list_size)
// 답은 7
}
신기하게도 IntArray 를 입력하고 나니 옆에 주석처럼 size가 붙었다. 이것 덕분에 더 이해하기 쉬웠다. array의 경우 옆에 지정해준 숫자만큼의 크기가 만들어지고 listOf 의 경우 옆에 넣어준 숫자의 갯수를 표시해주는 것 같다. 실제로 안에 들어간 숫자를 순서대로가 아니고 임의로 다른 숫자로 바꾸어도 출력되는 값은 같았다.
또 풀이중에 값 범위를 깔끔하게 지정하신 분을 봤는데 참고가 될 것 같아 메모해둔다.
val a = numbers.all{0 <= it && it <= 1000}
val b = 1 <= numbers.size && numbers.size <= 100
if(a && b) answer = numbers.sum().toDouble()/numbers.size
all 은 컬렉션의 모든 원소가 조건을 만족하는지 확인 후 true false 로 답을 내주는 함수라고 한다. (컬렉션은 다수의 객체를 수집해놓은 객체를 뜻한다.) 그리고 여기에 나오는 it 은 array 에 자동 생성되는 인덱스 기능을 함.
나는 it 이 어디서 나온건지를 이해하지 못해서 따로 검색해보았다.
그러니까 첫째줄은 array로 만들어진 numbers를 all을 통해 {} 안에 it 은 0 보다 크거나 같고 1000보다 작거나 같다는 조건을 정해서 true false를 a 로 담아 조건을 지정해주는 것으로 이해했다. (이게 원소범위를 제한)
둘째줄은 앞에 찾아봤던 사이즈로 numbers 의 갯수를 찾아서 1부터 100까지 길이를 지정해 b에 담은 것 같다.
그렇게 마지막줄에 if 로 만약 a 와 b 가 같다면 numbers 에 담긴 값을 sum으로 모두 더해서 toDouble()로 소수점 표시를 해주고 members 갯수를 구해서 나누어 answer 로 답을 내라는 뜻인 것 같다.
짝수와 홀수
class Solution {
fun solution(num: Int) = if (num % 2 == 0) "Even" else "Odd"
}
이번에는 한줄로 정리하기를 시도해봤다. 제일 처음에 풀었던 문제를 응용했는데 식은 잘 적었으나 마지막에 Even 과 Odd가 문제였다. 나는 여기서 바로 "" 를 통해 문자를 쓸 수 있다는걸 지금 알았다.
혹시 싶어서 ""를 떼고도 넣어보았으나 값이 제대로 나오지 않았다.
정수를 2로 나누어서 0과 같으면 Even 다를시 Odd로 표현해서 소수점 이하값으로 판단하는 형식이다.
평균 구하기
class Solution {
fun solution(arr: IntArray) = arr.average()
}
사실상 풀이가 배열의 평균값과 같다. 심지어 제한사항 추가도 추가해둔것과 비슷하게 할 수 있을것같다.
그래서 이걸 쓰면서 다시 만들어봤다. if를 적용할때 조금 해맸지만 어쨌든 정답이 나왔다.
class Solution {
fun solution(arr: IntArray): Double {
var answer = 0.0
var a = arr.all{-10000 <= it && it <= 10000}
var b = 1 <= arr.size && arr.size <= 100
if (a && b) {
answer= arr.average()
}
return answer
}
}
오늘 처음 배운 개념을 잘 이해할 수 있었던 것 같아 기분이 좋다.
사실 처음에는 문제를 푸는데 해결능력을 기르기 위해서라면 답을 찾아보는건 안좋다고만 생각해서 억지로 쥐어짜내곤 했었다. 이번에는 하다가 안되어서 해답페이지를 아무리 넘겨도 이전까지처럼 푸는 방식은 보이지 않았다. 여기서 공부법을 바꿔야겠다고 생각하게 되었다.
어차피 나는 초보다. 아는게 없는데... 마른 스펀지를 짠다고 물이 안나오는거랑 같은 이치다.
그래서 공부법을 바꿔봤는데 훨씬 도움이 된 것 같다.
내일부터는 내가 아는걸로 풀수있는건 풀고 모르는건 공부한단 마음으로 찾아보고 정리해가며 풀어야겠다.
2. Kotlin 문법 기초 과제 - 계산기 (추가학습)
추가학습을 하려고 목표는 높게 잡았는데... 실제로 구현에도 성공을 했으나 Calculator 에는 너무 많은 내용을 담으면 좋지 않다고 컨펌을 받아 다시 메인으로 옮겼다. 문제는 이번에도 옮기는 과정에서 전부 오류가 났다...
게다가 try - catch 는 아직 정확하게 사용법을 숙지하지도 못했다.
공부하라는 답을 들었는데 솔직히 강의만 듣고서 뭘 어떻게 공부해야할지 감이 안잡힌다...
그것만 보고 이해하기가 쉽지 않다. 어느정도 개념에 대해 아는 사람들에게 복습차 훑어주고 가는것에 가까운 느낌이었다. 이론공부를 책을 사서라도 따로 하는편이 나을지도 모르겠다.
초반부터 기능에 욕심은 많았고 구현에 한번은 성공했으나 완성은 못한 비운의 코드를 여기 올려본다...ㅋㅋ
수정은 나중에 좀더 실력이 쌓이고 나면 그때 다시 만들든 고치든 해봐야겠다.
어쨌든 이것만 일주일 내내 붙들고 있었더니 지쳤다. 수정 전 / 수정 후 두가지 모두 깃에 백업했으니 놔줘야겠다.
Main
// LV4 1번
fun main(args: Array<String>) {
println("숫자를 입력해주세요.")
var num1 = readLine()!!.toDouble()
println("연산자를 넣어주세요(+, -, /, *)")
val operate = readLine()!!.toString()
println("숫자를 입력해주세요.")
var num2 = readLine()!!.toDouble()
val AbstractOperation : AbstractOperation = when (operate) {
"+" -> AddOperation()
"-" -> SubstractOperation()
"*" -> MultiplyOperation()
"/" -> DivideOperation()
else -> throw IllegalArgumentException("잘못된 입력입니다. 연산자만 넣어주세요.")
}
val calc = Calculator(AbstractOperation)
println("정답은 ${calc.operate(1,2)}입니다.")
}
// LV4 2번
fun main() {
val calc = Calculator()
try {
print("첫 번째 숫자를 입력하세요: ")
val num1 = readLine()!!.toDouble()
print("두 번째 숫자를 입력하세요: ")
val num2 = readLine()!!.toDouble()
val result = calc.operate(num1, num2)
println("정답은 ${result}입니다.")
} catch (e:NumberFormatException) {
println("숫자가 아닙니다. 다시 입력해주세요.")
}
}
Calculator
// LV 4 1번
class Calculator (
private val operation: AbstractOperation
) {
fun operate(num1: Int, num2: Int): Double {
return operation.operate(num1, num2)
}
}
//LV4 2번
class Calculator {
fun operate(num1: Double, num2: Double): Double {
while (true) {
println("연산자를 넣어주세요(+, -, *, /, %)")
val operate = readLine()!!.toString()
val operation: AbstractOperation? = when (operate) {
"+" -> AddOperation()
"-" -> SubstractOperation()
"*" -> MultiplyOperation()
"/" -> DivideOperation()
"%" -> RemainderOperation()
else -> null
}
if (operation != null) {
return operation.operate(num1, num2)
} else {
println("허용되지 않는 연산자입니다. 다시 입력해주세요.")
}
}
}
}
AbstractOperation
//LV4 1번
abstract class AbstractOperation {
abstract fun operate(num1: Int, num2: Int): Double
}
//LV4 2번
abstract class AbstractOperation {
abstract fun operate(num1: Double, num2: Double): Double
}
// 이하 코드는 이전에 올렸던것에서 변한게 거의 없어서 생략
3. Kotlin 문법 심화 과제 - 호텔 예약 프로그래밍
원래 try - catch 를 한번만 하고도 전체에 적용 가능하다고 하셔서 그걸 여쭤보러 갔는데 다른 튜터님이셔서 그런지 잘 모른다고 하셨다. 검색을 해봐도 나오는것도 없고... 계산기에 매달리느라 호텔쪽은 어제와 딱히 다른점이 없다.
지적받았던것도 어제 개선점에 적었던 내용 그대로라 그냥 진행하면 될 것 같다.
마무리
코드 짜는데 손이 좀 익긴 했지만 솔직히 체계적인 공부의 필요가 절실하게 느껴진다.
내일부터 기초 개념, 용어공부도 병행해야겠다.