File size: 4,149 Bytes
0f06ae9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def main():
    import numpy as np
    import re
    with open("/home/yassinealouini/Documents/code/advent_of_code/aoc/year_2021/data/5.txt") as f:
        tmp = f.read().rstrip().split("\n")

    # Using complex numbers as (x, y) representation
    starts, ends = [], []
    for row in tmp:
        x1, y1, x2, y2 = re.findall(r'\d+', row)
        starts.append(int(x1) + 1j * int(y1))
        ends.append(int(x2) + 1j * int(y2))
    # Dimensions of the grid
    d = max(map(abs, starts)) + 1

    def solve(part_2=False):
        a = np.zeros((int(d), int(d)))
        for start_point, end_point in zip(starts, ends):

            if part_2:
                # Compute cosine and sine to find if diagonal or anti-diagonal
                diff = start_point - end_point
                c = (diff.real) / abs(diff)
                s = (diff.imag) / abs(diff)
                start_x = min(int(start_point.real), int(end_point.real))
                end_x = max(int(start_point.real), int(end_point.real))
                start_y = min(int(start_point.imag), int(end_point.imag))
                end_y = max(int(start_point.imag), int(end_point.imag))
                sliced_a = a[start_x: end_x + 1, start_y: end_y + 1]
                if round(s * c, 1) == 0.5:
                    np.fill_diagonal(sliced_a, 
                                     sliced_a.diagonal() + 1)
                elif round(s * c, 1) == -0.5:
                    # Flip the sliced matrix to fill the diagonal
                    np.fill_diagonal(np.fliplr(sliced_a), 
                                     np.fliplr(sliced_a).diagonal() + 1)
            if start_point.real == end_point.real:
                start = min(int(start_point.imag), int(end_point.imag))
                end = max(int(start_point.imag), int(end_point.imag))
                a[int(start_point.real), start: end + 1] += 1
            elif start_point.imag == end_point.imag:
                start = min(int(start_point.real), int(end_point.real))
                end = max(int(start_point.real), int(end_point.real))
                a[start: end + 1, int(start_point.imag)] += 1
        return a
    
    print("Solution to part I: ", (solve()>= 2).sum())
    print("Solution to part II: ", (solve(part_2=True)>= 2).sum())


def streamlit_5(data_input):
    """ Day 5 solution (mainly using numpy)
    """
    import numpy as np
    import re
    import streamlit as st

    tmp = data_input.rstrip().split("\n")

    # Using complex numbers as (x, y) representation
    starts, ends = [], []
    for row in tmp:
        x1, y1, x2, y2 = re.findall(r'\d+', row)
        starts.append(int(x1) + 1j * int(y1))
        ends.append(int(x2) + 1j * int(y2))

    # Dimension of the grid
    d = max(map(abs, starts)) + 1

    def solve(part_2=False):
        a = np.zeros((int(d), int(d)))
        for start_point, end_point in zip(starts, ends):
            start_x = min(int(start_point.real), int(end_point.real))
            end_x = max(int(start_point.real), int(end_point.real))
            start_y = min(int(start_point.imag), int(end_point.imag))
            end_y = max(int(start_point.imag), int(end_point.imag))
            # Compute cosine and sine to find if diagonal or anti-diagonal
            diff = start_point - end_point
            c = (diff.real) / abs(diff)
            s = (diff.imag) / abs(diff)
            sliced_a = a[start_x: end_x + 1, start_y: end_y + 1]
            criterion = round(s * c, 1)
            if part_2:
                if criterion == 0.5:
                    np.fill_diagonal(sliced_a, sliced_a.diagonal() + 1)
                elif criterion == -0.5:
                    # Need to flip the sliced matrix to get the correct diagonal
                    np.fill_diagonal(np.fliplr(sliced_a), 
                                     np.fliplr(sliced_a).diagonal() + 1)
            # Either horizontal or vertical
            if criterion == 0:
                sliced_a += 1
        return a
    
    st.write("Solution to part I: ", (solve()>= 2).sum())
    st.write("Solution to part II: ", (solve(part_2=True)>= 2).sum())

if __name__ == "__main__":
    main()