summaryrefslogtreecommitdiffstats
path: root/2/sol.py
blob: 901f9fe80e680ed8671e679c80208de6feb5bed6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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))