AOC第1天 - 卡路里计数
#初学者 #编程 #go #adventofcode

我们都一直在等待的那一刻,第一次。年底即将到来,所以那些Advent of Code

对于那些不认识的人,AOC是一项年度编程比赛,我们试图帮助圣诞老人做一些时髦的sh **。
竞争本身是基于速度和时间的,您可以阅读更多有关它的信息。

卡路里计数

Question

第1部分

我们获得了一个数字列表,其中每个连续的数字代表精灵随身携带的卡路里。
例如

1000 - \
2000 -   -> an elf carrying 6000 calories 
3000 - /

4000

5000
6000

7000 - \
8000 -   ->  an elf carrying 24000 calories - the Maximum in our list
9000 - /

10000

这个问题似乎足够简单,我们需要在空线上拆分字符串,然后取每个块并总结其中的数字。
一旦获得了各种块(精灵卡路里),我们就可以搜索最大值,我们有答案。

解析

从名为“ input.txt”的文件中读取我们的输入

func parse() []string {
    data, _ := os.ReadFile("./input.txt")
    chunks := strings.Split(string(data), "\n\n")
    return chunks
}

 // example output
// ["1000\n2000\n3000", "4000", "5000\n6000", ....]

为什么我们要在“ \ n \ n”上拆分字符串?空线中唯一的炭是“ \ n”,在获得“ \ n \ n”

之前将其与线结合在一起

总结一下

添加一个新函数,该功能获取代表块的字符串,例如1000\n2000\n3000并返回这些数字的总和

func sumChunk(chunk string) int {
    sum := 0
    for _, num := range strings.Split(chunk, "\n") {
        v, _ := strconv.Atoi(num)
        sum += v
    }
    return sum
}
 // example output
// [6000, 4000, 11000, ....]

要将字符串转换为int,我们需要导入strconv软件包并使用atoi函数(ascii to int)。
现在,可能是一个很好的观点,即在Go中返回错误,在返回错误中,在_上方的函数中,从atoi返回的函数表示我们应该处理的可能的错误,但是由于AOC与速度有关通过将其命名为_

来忽略它。

将所有这些放在一起

package main

import (
    "fmt"
    "os"
    "sort"
    "strconv"
    "strings"
)

func main() {
    chunks := parse()
    //
    result := []int{}
    for _, chunk := range chunks {
        result = append(result, sumChunk(chunk))
    }

    sort.Ints(result)

    fmt.Println("Part 1")
    fmt.Println(result[len(result)-1])


}

再次为了速度,我们将仅存储所有结果,按顺序排序,使用go sort软件包并将最后一个位置用作我们的答案。

我知道,我知道我可以通过在for循环中进行比较来找到最大条目,但是您会发现这是值得的。

第2部分

在第2部分中,我们被要求返回带有最多卡路里的3个精灵的总和,即采用我们的排序阵列并将最后3个元素和总和
我们可以通过添加此行轻松调整答案以适应这些新要求

    fmt.Println("Part 2")
    fmt.Println(result[len(result)-1] + result[len(result)-2] + result[len(result)-3])

备择方案?

我使用排序来获取数组中最大的N元素,但是这里还有其他更多性能的方法,例如使用Max-Heap数据结构,但 aoc是要保持简单并获得有效的答案尽快,除非您知道自己遇到性能问题,最好通常使用更简单,更幼稚的解决方案。

您可以找到完整的代码here
感谢您的阅读!