Laboratorio 1

Exercise 6

Light intensity map with a 2-D numpy array

Problem restatement

Given the side length N of a square room and the coordinates of several light-spots, compute the illumination intensity on every floor-tile.

Each spot adds a fixed 5 x 5 pattern centered on its own tile.

r-offset -2 -1 0 +1 +2
-2 0.2 0.2 0.2 0.2 0.2
-1 0.2 0.5 0.5 0.5 0.2
0 0.2 0.5 1.0 0.5 0.2
+1 0.2 0.5 0.5 0.5 0.2
+2 0.2 0.2 0.2 0.2 0.2

Intensity values from different spots add up.

Edge tiles receive only the portion of the kernel that lies inside the room.

Methodological rationale

Step-by-step resolution

import numpy as np

def load_spot_file(path: str):
	"""Read N and a list of (row, col) integer pairs from text file."""
	with open(path, 'r') as f:
		# Read the first line separately to get N
		N = int(f.readline().strip())
		# Read the rest of the file for coordinates
		coords = np.loadtxt(f, dtype=int)
	return N, coords
	
# 5 x 5 kernel (centre at index [2,2])
KERNEL = np.array([[0.2, 0.2, 0.2, 0.2, 0.2],
				   [0.2, 0.5, 0.5, 0.5, 0.2],
				   [0.2, 0.5, 1.0, 0.5, 0.2],
				   [0.2, 0.5, 0.5, 0.5, 0.2],
				   [0.2, 0.2, 0.2, 0.2, 0.2]], dtype=float)
									 
def light_map(N, spots):
	room = np.zeros((N, N), dtype=float)
	
	for r, c in spots:
		# boundaries of the full 5x5 kernel centred at (r,c)
		r0, r1 = r - 2, r + 3 # Python slices are half-open
		c0, c1 = c - 2, c + 3
		
		# clip to room borders
		rs, re = max(r0, 0), min(r1, N)
		cs, ce = max(c0, 0), min(c1, N)
		
		# corresponding indices inside the kernel
		ks = rs - r0
		ke = re - r0
		ls = cs - c0
		le = ce - c0
		
		room[rs:re, cs:ce] += KERNEL[ks:ke, ls:le]
		
	return room
	
def print_map(M):
	"""Pretty-print with one decimal digit"""
	for row in M:
		print(" ".join(f"{v:0.1f}" for v in row))
		
# Example
N, coords = load_spot_file("spotlights.txt")
print_map(light_map(N, coords))

Explanation of key points

  1. Kernel super-position - the update room[slice] += KERNELE[subkernel] is a single vectorised operation; no Python loops over individual tiles.
  2. Edge-aware slicing - clipping indices ensures we never reference outside the array. The matching slice on the kernel is obtained by the same offsets.
  3. Complexity - Let S be the number of spotlights. Each update touches at most 25 elements, so the overall algorithm is O(S) and memory O(N²).

Result interpretation