又來到一年一度的 Advent Of Code 的挑戰,去年只挑戰了8題,希望今年能夠挑戰多一點 XD
Day1 Calorie Counting
完整的題目可參考:Day1
Part I
根據題目,我們需要從輸入的列表計算出最大的卡路里,而在輸入值中,是以 ""
作為分段,所以我們要把 ""
當作分隔的條件,將每一段的數字加起來,找出最大的那個值。
一開始的思路,是想說要如何以 ""
作為分割條件,讓輸入的字串切割成新的 List<Int>
,然後從這裡面找出最大的那個數字。
首先遇到一個問題是,如果用 ""
作為切割的條件,那我們會需要先遍訪過整個 List,才能夠將輸入的值轉成我們希望的格式。如此一來,我們就至少需要作兩次 List 的遍訪。 如果不將輸入轉換成另外一個 List<Int>
,我們要如何在一次的遍訪中就能夠找出最大的值?
我的思路很簡單,直接遍訪所有的項目,將遇到的項目加起來,遇到 ""
的時候,我們將這個值與上一個最大值比,如果現在的值比較大,那麼我們就將最大值用現在計算的總和取代。如此一來,等到我們走到最後一個項目的時候,我們也找出最大的總和。
fun part1(input: List<String>): Int {
var sum = 0
var temp = 0
input.forEach {
if (it.isEmpty()) {
if (temp > sum) {
sum = temp
}
temp = 0
} else {
temp += it.toInt()
}
}
return sum
}
Part II
第二部分與第一部分類似,不過要找出的不是單一值,而是最大的三個值,所以我選擇使用了一個大小為 4 的 List,並在每次計算出總和的時候,將總和存進 List 的最後一個欄位:list[3],存完之後,排序 List,按照大小排列,所以 List 就會由大至小的排列下去。
最後我們就能直接使用 take(3) 取得前三個值,再使用 sum() 取得其加總。
fun part2(input: List<String>): Int {
var firstFourItems = MutableList(4){0}
val newInput = input + ""
var temp = 0
newInput.forEach {
if (it.isEmpty()) {
firstFourItems[3] = temp
firstFourItems = firstFourItems.sorted().reversed().toMutableList()
println(firstFourItems)
temp = 0
} else {
temp += it.toInt()
}
}
return firstFourItems.take(3).sum()
以上就是第一天的答案以及思路,如果有錯誤以及有更好的想法,歡迎與我分享,謝謝各位。
github: https://github.com/andyludeveloper/Kotlin-in-Advent-of-Code-2022