0. 오늘은 무엇을 했는가
오늘은 한 게 많이 없습니다. 뭔가 하느라 바빴다기보다도,
코드 카타가 쉽게 안 풀렸고, 개인 과제도 코드가 마음에 안 들어서 한 번 엎었기 때문입니다...
그럼 바로 시작하겠습니다.
1. 코드 카타
[ 09:00 ~ 14:00 ]
오늘의 코드 카타는 조금 어려웠습니다.
우선 주제 자체는 저번에 풀어봤던 최소공배수를 푸는 내용인데,
대신 이번에는 n개의 최소 공배수를 구하는 문제였습니다.
저는 당연하게도 저번과 같은 알고리즘이 통할 거라 생각하고,
최대공약수를 구해서, 최소공배수를 구하는 알고리즘을 만들었고,
결과는
여기서부터 한참동안 어떻게 해야 해결할 수 있을지 고민했습니다.
11시 30분쯤이 되어서야 어느 정도 갈피를 잡았습니다.
최소공배수는 결국, 모든 수를 하나씩 나눠보면서 그 값들을 곱하면 되는 것이었습니다.
예를 들어보겠습니다.
3, 8, 9, 10, 12 의 최소공배수는 어떻게 구할까요?
2부터 시작해서 제일 큰 수까지, 또, 그 수로 안 나눠질 때까지 나눠보겠습니다.
모든 수를 2로 나누면, 3, 4, 9, 5, 6 이 나옵니다.
2로 나눌 수 있기에, 다시 2로 나누면 3, 2, 9, 5, 3이 나옵니다.
2로 나눌 수 있기에, 2로 나누면, 3, 1, 9, 5, 3이 나옵니다.
이렇게 해서 2의 3승만큼 나눴습니다.
그 후, 3으로 나누겠습니다. 1, 1, 3, 5, 1 가 됩니다.
다시 3으로 나누면 1, 1, 1, 5, 1이 됩니다.
현재까지 2의 3승과 3의 2승만큼 나눴습니다. 나머지 하나는 당연히 5입니다.
즉, 최소공배수는 2의 3승 X 3의 2승 X 5 = 360이 됩니다.
이런 방식으로 구하기 때문에 저는 이걸 이용해봤습니다.
class Solution {
fun solution(arr: IntArray): Int {
var answer = 1
var iarr = arr
var num = 2
var next = false
while(iarr.sum() != iarr.size) {
next = false
iarr = iarr.map {
if(it % num == 0) {
next = true
it / num
}
else it
}.toIntArray()
if (next == false) num++
else answer *= num
}
return answer
}
}
굉장히 복잡하고, 시간복잡도도 별로 좋지 않습니다.
그래서 다른 분의 풀이를 확인해봤습니다.
다른 분의 풀이입니다.
class Solution {
fun solution(arr: IntArray): Int {
var answer = 1
while(true) {
var x = 0
for(a in arr) x += answer%a
if(x==0) return answer
answer++
}
return answer
}
}
정말 간단하고, 시간복잡도 효율도 좋습니다.
돌아가는 방식은 arr의 요소들을 돌아가면서 answer로 나눠지는지 확인하고,
나머지 값을 x에 더하고, x가 0이 될 때까지, 즉, answer가 arr의 모든 요소들로 나눠질 때까지
answer를 1씩 증가시킵니다.
지금 보니까 이 방법을 왜 생각 못했는지 의문이 듭니다.
아무래도, 요즘 다양한 함수를 공부하면서, 그 함수들을 이용해보고 싶어서 그런 것 같습니다.
앞으로는 고정된 생각말고, 조금 다양한 생각을 해야겠습니다.
2. 개인 과제 - Lv. 1, Lv. 2
[ 14:00 ~ 20:00 ]
코드 카타를 한 이후에는 개인 과제를 진행했습니다.
이번 과제 주제는 키오스크였습니다. 저는 롯데리아가 가장 먼저 떠올라서 롯데리아를 선택했습니다.
당연히, 빠르게 끝내고, 코드 카타를 더 할 수 있을 것 같았지만,
생각보다 구상하는 과정에서 시간이 오래 걸렸고, 그걸 구현할 때, 코드가 많이 엉킨 모습이 보였습니다.
그래서, 이건 구상도 다시 하고, 코드도 다시 짜야겠다고 생각했습니다.
먼저 Lv. 1의 main입니다.
fun main() {
var nowMenu = 0
while (true) {
println("[ 롯데리아에 어서 오세요! ]")
repeat(menuNum) {
print("${it + 1}. ${menu[it]}")
print(" ".repeat(menuSpace[it]))
println("| ${menuDesc[it]}")
println("[ ${titles[nowMenu]} ]")
repeat(menu[nowMenu].size) {
print("${it + 1}. ${menu[nowMenu][it]}")
if(nowMenu != 0) print(" | ${price[nowMenu - 1][it]}")
println(" | ${menuDesc[nowMenu][it]}")
}
if(nowMenu == 0) println("0. 종료하기 | 프로그램 종료")
else println("0. 돌아가기 | 돌아가기")
println()
print("메뉴 선택 : ")
val selectMenu = readln()
if(readln().isDigitsOnly()) println("미구현")
val selectMenu = readln().toInt()
if(nowMenu == 0) {
if(selectMenu == 0) {
println("종료합니다.")
break
}
else nowMenu = selectMenu
}
else {
when{
selectMenu == 0 -> nowMenu = selectMenu
selectMenu in 1..menu[nowMenu].size -> println("${menu[nowMenu][selectMenu-1]} 메뉴를 선택했습니다.")
else -> println("잘못 선택했습니다")
}
}
println()
}
}
모든 기능, 변수들을 main에서 해결합니다. 여기에는 길이때문에 잘랐지만,
위에는 메뉴 내용이 적혀 있는, 문자열 배열이 존재합니다.
이 코드도 깔끔하진 않아서, 조금 더 손을 본 내용이 Lv. 2입니다.
fun main() {
var nowMenu = 0
while (true) {
// 타이틀
println("[ ${titles[nowMenu]} ]")
repeat(menu[nowMenu].size) {
print("${it + 1}. ${menu[nowMenu][it]}")
if(nowMenu != 0) print(" | ${price[nowMenu - 1][it]}")
println(" | ${menuDesc[nowMenu][it]}")
// 내용
when(nowMenu) {
0 -> mainMenuArr.forEachIndexed() { index, it ->
print("${index + 1}. ")
it.displayInfo()
}
1 -> burgerArr.forEachIndexed() { index, it ->
print("${index + 1}. ")
it.displayInfo()
}
2 -> dessertArr.forEachIndexed() { index, it ->
print("${index + 1}. ")
it.displayInfo()
}
3 -> drinkArr.forEachIndexed() { index, it ->
print("${index + 1}. ")
it.displayInfo()
}
4 -> iceCreamArr.forEachIndexed() { index, it ->
print("${index + 1}. ")
it.displayInfo()
}
}
// 종료, 돌아가기
if(nowMenu == 0) println("0. 종료하기 | 프로그램 종료")
else println("0. 돌아가기 | 돌아가기")
println()
// 메뉴 고르는 곳
print("메뉴 선택 : ")
val selectMenu = readln().toInt()
if(nowMenu == 0) {
if(selectMenu == 0) {
println("종료합니다.")
break
// 메뉴 고른 거에 따른 동작
lateinit var selectedName: String
if (selectMenu != 0) {
when(nowMenu) {
0 ->
{
selectedName = mainMenuArr[selectMenu-1].name
nowMenu = selectMenu
}
1 -> selectedName = burgerArr[selectMenu-1].name
2 -> selectedName = dessertArr[selectMenu-1].name
3 -> selectedName = drinkArr[selectMenu-1].name
4 -> selectedName = iceCreamArr[selectMenu-1].name
else -> selectedName = "존재하지 않는"
}
else nowMenu = selectMenu
}
else {
when{
selectMenu == 0 -> nowMenu = selectMenu
selectMenu in 1..menu[nowMenu].size -> println("${menu[nowMenu][selectMenu-1]} 메뉴를 선택했습니다.")
else -> println("잘못 선택했습니다")
if(nowMenu == 0) {
println("종료합니다.")
break
}
else {
selectedName = "돌아가기"
nowMenu = 0
}
}
println("$selectedName 메뉴를 고르셨습니다.")
println()
}
}
쓸데없이 길어지긴 했지만, 클래스를 추가했습니다.
출력 메소드를 따로 만들고도 싶었지만, 솔직히 Lv. 2는 정리가 안 된 상태라,
정리를 다하고 나서 넣을 생각입니다.
Lv. 3에서는 상속과 컬렉션을 다루기에, 더 깔끔하게 코드를 정리할 수 있을 것 같습니다.
3. 끝
오늘은 이렇게가 제가 한 전부입니다.
생각하는 데 시간의 절반은 쓴 것 같습니다.
오늘 날씨도 정말 더워서 쉽지 않았던 날이었습니다.
그래서 내일은 잠시동안 에어컨을 틀어볼 생각입니다.
끝.