<jupyter_start><jupyter_text>Part 1  Let's compute the power level.<jupyter_code>def hundred_digit(n):
    nstr = str(n)
    if len(nstr) > 2:
        return int(nstr[-3])
    else:
        raise NotImplementedError('Problem here.')
def compute_power_level(x, y, serial_number):
    rack_id = x + 10
    power_level = rack_id * y
    power_level = power_level + serial_number
    power_level *= rack_id
    power_level = hundred_digit(power_level)
    power_level -= 5
    return power_level<jupyter_output><empty_output><jupyter_text>Unit tests:<jupyter_code>serial_number = 8

(x, y) = 3, 5

compute_power_level(x, y, serial_number)
compute_power_level(122, 79, 57)
compute_power_level(217,196, 39)
compute_power_level(101,153,71)<jupyter_output><empty_output><jupyter_text>Let's also see if we get the two examples on matrices right:<jupyter_code>import numpy as np
mat = np.empty((5, 5))

for c in range(32, 37):
    for r in range(44, 49):
        x, y = c, r
        power_level = compute_power_level(x, y, 18)
        mat[r-44, c-32] = power_level

mat
mat = np.empty((5, 5))

for c in range(20, 25):
    for r in range(60, 65):
        x, y = c, r
        power_level = compute_power_level(x, y, 42)
        mat[r-60, c-20] = power_level

mat<jupyter_output><empty_output><jupyter_text>Let's build the 300 by 300 grid.<jupyter_code>mat = np.empty((300, 300))
for c in range(300):
    for r in range(300):
        x, y = c+1, r+1
        mat[r, c] = compute_power_level(x, y, 5791)
mat<jupyter_output><empty_output><jupyter_text>Let's find the largest 3x3 region.<jupyter_code>def compute_max_3x3(mat):
    rmax, cmax, max_total = None, None, 0
    for c in range(300-3):
        for r in range(300-3):
            region = mat[r:r+3, c:c+3]
            if np.sum(region) > max_total:
                max_total = np.sum(region)
                rmax, cmax = r, c

    return cmax+1, rmax+1
compute_max_3x3(mat)<jupyter_output><empty_output><jupyter_text>Part 2 We have to rewrite the sliding window code, for which we can also use Numba.<jupyter_code>from numba import njit
@njit
def compute_max_any_size(mat, size):
    rmax, cmax, max_total = -2, -2, 0
    for c in np.arange(300-size):
        for r in np.arange(300-size):
            region = mat[r:r+size, c:c+size]
            if np.sum(region) > max_total:
                max_total = np.sum(region)
                rmax, cmax = r, c
    return cmax+1, rmax+1, size, max_total
compute_max_any_size(mat, 3)
from tqdm import tqdm_notebook
scores = []
for size in tqdm_notebook(range(1, 301)):
    scores.append(compute_max_any_size(mat, size))
max(scores, key=lambda items: items[3])<jupyter_output><empty_output><jupyter_text>Using pythran<jupyter_code>%load_ext pythran.magic
%%pythran
import numpy as np
#pythran export compute_max_any_size_pythran(float[:, :], int)
def compute_max_any_size_pythran(mat, size):
    rmax, cmax, max_total = -2, -2, 0
    for c in np.arange(300-size):
        for r in np.arange(300-size):
            region = mat[r:r+size, c:c+size]
            if np.sum(region) > max_total:
                max_total = np.sum(region)
                rmax, cmax = r, c
    return cmax+1, rmax+1, size, max_total
compute_max_any_size_pythran(mat, 4)
scores = []
for size in tqdm_notebook(range(1, 301)):
    scores.append(compute_max_any_size_pythran(mat, size))<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup