package main import ( "fmt" "os" "strconv" "strings" ) type Dimension struct { l, w, h int } func main() { input := readFile("../input.txt") fmt.Println(part1(input)) fmt.Println(part2(input)) } func part1(input string) int { list := strings.Split(input, "\r\n") total := 0 for _, p := range list { total += calculateWrapSize(parseDimensions(p)) } return total } func part2(input string) int { list := strings.Split(input, "\r\n") total := 0 for _, p := range list { total += calculateBowSize(parseDimensions(p)) } return total } func parseDimensions(input string) Dimension { splitValues := strings.Split(input, "x") l, _ := strconv.Atoi(splitValues[0]) w, _ := strconv.Atoi(splitValues[1]) h, _ := strconv.Atoi(splitValues[2]) return Dimension{ l: l, w: w, h: h, } } func calculateBowSize(dimensions Dimension) int { sorted := quickSort([]int{dimensions.l, dimensions.w, dimensions.h}) first := sorted[0] second := sorted[1] ribbonLength := first*2 + second*2 extra := dimensions.l * dimensions.w * dimensions.h return ribbonLength + extra } func calculateWrapSize(dimensions Dimension) int { lw := dimensions.l * dimensions.w wh := dimensions.w * dimensions.h hl := dimensions.h * dimensions.l smallest := min([]int{lw, wh, hl}) return 2*lw + 2*wh + 2*hl + smallest } func quickSort(arr []int) []int { if len(arr) < 2 { return arr } left, right := 0, len(arr)-1 // Choose the pivot (here, the last element) pivot := arr[right] // Partition: all elements less than pivot to the left for i := range arr { if arr[i] < pivot { arr[i], arr[left] = arr[left], arr[i] left++ } } // Place the pivot after the last smaller element arr[left], arr[right] = arr[right], arr[left] // Recursively sort left and right parts quickSort(arr[:left]) quickSort(arr[left+1:]) return arr } func min(list []int) int { min := list[0] for _, v := range list { if v < min { min = v } } return min } func readFile(filename string) string { content, err := os.ReadFile(filename) if err != nil { return "" } return string(content) }