from dataclasses import dataclass from typing import List @dataclass class Box: w: int h: int d: int @staticmethod def from_string(s: str) -> 'Box': w, h, d = map(int, s.split('x')) return Box(w, h, d) def surface_area(self) -> int: return 2 * self.w * self.h + 2 * self.h * self.d + 2 * self.d * self.w def smallest_side_area(self) -> int: return min(self.w * self.h, self.h * self.d, self.d * self.w) def wrapping_paper_area(self) -> int: return self.surface_area() + self.smallest_side_area() def smallest_perimeter(self) -> int: return 2 * (self.w + self.h + self.d - max(self.w, self.h, self.d)) def ribbon_length(self) -> int: """The ribbon required to wrap a present is the shortest distance around its sides, or the smallest perimeter of any one face. Each present also requires a bow made out of ribbon as well; the feet of ribbon required for the perfect bow is equal to the cubic feet of volume of the present.""" return self.smallest_perimeter() + self.w * self.h * self.d def part1(boxes: List[Box]) -> int: return sum(box.wrapping_paper_area() for box in boxes) def part2(boxes: List[Box]) -> int: return sum(box.ribbon_length() for box in boxes) if __name__ == '__main__': with open('2/input') as f: boxes = [Box.from_string(line.strip()) for line in f] print(part1(boxes)) print(part2(boxes))