## Rešitev

Imamo torej

    import re
    import numpy as np

    def anyrange(a, b):
        return np.arange(a, b + 1) if b >= a else np.arange(a, b - 1, -1)

    lines = np.array([[int(x) for x in re.findall(r"\d+", v)]
                      for v in open("example.txt")])

Kako veliko matriko si moramo pripraviti? Poiskati moramo največjo koordinato `x` in največjo koordinato `y`. `x`-i so v ničtem in drugem stolpcu, `y` prvem in tretjem.

    lines

    array([[0, 9, 5, 9],
           [8, 0, 0, 8],
           [9, 4, 3, 4],
           [2, 2, 2, 1],
           [7, 0, 7, 4],
           [6, 4, 2, 0],
           [0, 9, 2, 9],
           [3, 4, 1, 4],
           [0, 0, 8, 8],
           [5, 5, 8, 2]])

Potrebujemo maksimum ničtega in drugega skupaj ter maksimum prvega in tretjega. Seveda bi to lahko poračunali tako, da bi izračunali

    np.max(lines, axis=0)

    array([9, 9, 8, 9])

in to potem združevali (kar je glede na te konkretne številke sicer dolgočasno, vendar razmišljajmo o splošnem primeru). Vendar je, glede na to, da smo slučajno izvedeli za `reshape`, bolj zabavno združiti stolpca.

    lines.reshape((-1, 2))

    array([[0, 9],
           [5, 9],
           [8, 0],
           [0, 8],
           [9, 4],
           [3, 4],
           [2, 2],
           [2, 1],
           [7, 0],
           [7, 4],
           [6, 4],
           [2, 0],
           [0, 9],
           [2, 9],
           [3, 4],
           [1, 4],
           [0, 0],
           [8, 8],
           [5, 5],
           [8, 2]])

Naša maksimuma sta potem

    np.max(lines.reshape((-1, 2)), axis=0)

    array([9, 9])

Matrika, ki jo potrebujemo, mora biti za 1 večja, ker štejemo od 0.

    field = np.zeros(np.max(lines.reshape((-1, 2)) + 1, axis=0))

Prvi del naloge zahteva, da upoštevamo le črte, ki so navpične ali vodoravne. Za vsako povečamo ustrezne elemente tabele za 1. Indekse "ustreznih elementov" nam prijazno pove `anyrange`.

    for x1, y1, x2, y2 in lines:
        if x1 == x2 or y1 == y2:
            field[anyrange(x1, x2), anyrange(y1, y2)] += 1

Kako prešteti neničelne elemente? Takole.

    field > 1

    array([[False, False, False, False, False, False, False, False, False,
             True],
           [False, False, False, False, False, False, False, False, False,
             True],
           [False, False, False, False, False, False, False, False, False,
             True],
           [False, False, False, False,  True, False, False, False, False,
            False],
           [False, False, False, False, False, False, False, False, False,
            False],
           [False, False, False, False, False, False, False, False, False,
            False],
           [False, False, False, False, False, False, False, False, False,
            False],
           [False, False, False, False,  True, False, False, False, False,
            False],
           [False, False, False, False, False, False, False, False, False,
            False],
           [False, False, False, False, False, False, False, False, False,
            False]])

Le tole moramo sešteti.

    np.sum(field > 1)

    5

Za drugi del pa le izpustimo `if` in bomo dobili še diagonale.

Lahko pa rešimo oba dela hkrati. Celotna rešitev obeh delov je:

    import re
    import numpy as np

    def anyrange(a, b):
        return np.arange(a, b + 1) if b >= a else np.arange(a, b - 1, -1)

    lines = np.array([[int(x) for x in re.findall(r"\d+", v)]
                      for v in open("example.txt")])

    for part in (0, 1):
        field = np.zeros(np.max(lines.reshape((-1, 2)) + 1, axis=0))
        for x1, y1, x2, y2 in lines:
            if part == 1 or x1 == x2 or y1 == y2:
                field[anyrange(x1, x2), anyrange(y1, y2)] += 1
        print(np.sum(field > 1))

    5
    12