# your code goes here
#0JLQsNGB0LjQu9C10L3QutC+INCQ0YDRgtC10Lwg
import random
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import matplotlib.patches as mpatches
N = 40
M = 40
TREE_CHANCE = 0.15
GARAGE_H = 4
GARAGE_W = 5
EMPTY = 0
TREE = 1
GARAGE = 2
def solve_garages_simple_plot():
grid = np.zeros((N, M), dtype=int)
for r in range(N):
for c in range(M):
if random.random() < TREE_CHANCE:
grid[r, c] = TREE
print(f"Поле {N}x{M}. Дерев: {TREE_CHANCE*100}%.")
print(f"Гараж: {GARAGE_H}x{GARAGE_W}")
garages_count = 0
for r in range(N):
for c in range(M):
if r + GARAGE_H > N or c + GARAGE_W > M:
continue
area = grid[r:r+GARAGE_H, c:c+GARAGE_W]
if np.any(area != EMPTY):
continue
grid[r:r+GARAGE_H, c:c+GARAGE_W] = GARAGE
garages_count += 1
print(f"Розміщено гаражів: {garages_count}")
colors = ['#f0f0f0', '#228B22', '#4169E1']
cmap = ListedColormap(colors)
fig, ax = plt.subplots(figsize=(12, 8))
ax.imshow(grid, cmap=cmap, vmin=0, vmax=2)
ax.set_xticks(np.arange(-0.5, M, 1), minor=True)
ax.set_yticks(np.arange(-0.5, N, 1), minor=True)
ax.grid(which='minor', color='white', linestyle='-', linewidth=0.5)
ax.tick_params(which="minor", bottom=False, left=False)
ax.set_title(f'План забудови: {garages_count} гаражів\n(Поле: {N}x{M}, Гараж: {GARAGE_H}x{GARAGE_W})', fontsize=14)
ax.set_xlabel('M')
ax.set_ylabel('N')
legend_patches = [
mpatches.Patch(color=colors[0], label='Вільна ділянка'),
mpatches.Patch(color=colors[1], label='Дерево'),
mpatches.Patch(color=colors[2], label='Гараж')
]
ax.legend(handles=legend_patches, bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0.)
plt.tight_layout()
plt.show()
if __name__ == "__main__":
solve_garages_simple_plot()
IyB5b3VyIGNvZGUgZ29lcyBoZXJlCiMwSkxRc05HQjBMalF1OUMxMEwzUXV0QytJTkNRMFlEUmd0QzEwTHdnCgppbXBvcnQgcmFuZG9tCmltcG9ydCBudW1weSBhcyBucAppbXBvcnQgbWF0cGxvdGxpYi5weXBsb3QgYXMgcGx0CmZyb20gbWF0cGxvdGxpYi5jb2xvcnMgaW1wb3J0IExpc3RlZENvbG9ybWFwCmltcG9ydCBtYXRwbG90bGliLnBhdGNoZXMgYXMgbXBhdGNoZXMKCk4gPSA0MApNID0gNDAKVFJFRV9DSEFOQ0UgPSAwLjE1CkdBUkFHRV9IID0gNApHQVJBR0VfVyA9IDUKCkVNUFRZID0gMApUUkVFID0gMQpHQVJBR0UgPSAyCgpkZWYgc29sdmVfZ2FyYWdlc19zaW1wbGVfcGxvdCgpOgogICAgZ3JpZCA9IG5wLnplcm9zKChOLCBNKSwgZHR5cGU9aW50KQogICAgCiAgICBmb3IgciBpbiByYW5nZShOKToKICAgICAgICBmb3IgYyBpbiByYW5nZShNKToKICAgICAgICAgICAgaWYgcmFuZG9tLnJhbmRvbSgpIDwgVFJFRV9DSEFOQ0U6CiAgICAgICAgICAgICAgICBncmlkW3IsIGNdID0gVFJFRQoKICAgIHByaW50KGYi0J/QvtC70LUge059eHtNfS4g0JTQtdGA0LXQsjoge1RSRUVfQ0hBTkNFKjEwMH0lLiIpCiAgICBwcmludChmItCT0LDRgNCw0LY6IHtHQVJBR0VfSH14e0dBUkFHRV9XfSIpCgogICAgZ2FyYWdlc19jb3VudCA9IDAKICAgIAogICAgZm9yIHIgaW4gcmFuZ2UoTik6CiAgICAgICAgZm9yIGMgaW4gcmFuZ2UoTSk6CiAgICAgICAgICAgIGlmIHIgKyBHQVJBR0VfSCA+IE4gb3IgYyArIEdBUkFHRV9XID4gTToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIAogICAgICAgICAgICBhcmVhID0gZ3JpZFtyOnIrR0FSQUdFX0gsIGM6YytHQVJBR0VfV10KICAgICAgICAgICAgaWYgbnAuYW55KGFyZWEgIT0gRU1QVFkpOgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgCiAgICAgICAgICAgIGdyaWRbcjpyK0dBUkFHRV9ILCBjOmMrR0FSQUdFX1ddID0gR0FSQUdFCiAgICAgICAgICAgIGdhcmFnZXNfY291bnQgKz0gMQoKICAgIHByaW50KGYi0KDQvtC30LzRltGJ0LXQvdC+INCz0LDRgNCw0LbRltCyOiB7Z2FyYWdlc19jb3VudH0iKQoKICAgIGNvbG9ycyA9IFsnI2YwZjBmMCcsICcjMjI4QjIyJywgJyM0MTY5RTEnXQogICAgY21hcCA9IExpc3RlZENvbG9ybWFwKGNvbG9ycykKCiAgICBmaWcsIGF4ID0gcGx0LnN1YnBsb3RzKGZpZ3NpemU9KDEyLCA4KSkKICAgIAogICAgYXguaW1zaG93KGdyaWQsIGNtYXA9Y21hcCwgdm1pbj0wLCB2bWF4PTIpCgogICAgYXguc2V0X3h0aWNrcyhucC5hcmFuZ2UoLTAuNSwgTSwgMSksIG1pbm9yPVRydWUpCiAgICBheC5zZXRfeXRpY2tzKG5wLmFyYW5nZSgtMC41LCBOLCAxKSwgbWlub3I9VHJ1ZSkKICAgIGF4LmdyaWQod2hpY2g9J21pbm9yJywgY29sb3I9J3doaXRlJywgbGluZXN0eWxlPSctJywgbGluZXdpZHRoPTAuNSkKICAgIGF4LnRpY2tfcGFyYW1zKHdoaWNoPSJtaW5vciIsIGJvdHRvbT1GYWxzZSwgbGVmdD1GYWxzZSkKICAgIAogICAgYXguc2V0X3RpdGxlKGYn0J/Qu9Cw0L0g0LfQsNCx0YPQtNC+0LLQuDoge2dhcmFnZXNfY291bnR9INCz0LDRgNCw0LbRltCyXG4o0J/QvtC70LU6IHtOfXh7TX0sINCT0LDRgNCw0LY6IHtHQVJBR0VfSH14e0dBUkFHRV9XfSknLCBmb250c2l6ZT0xNCkKICAgIGF4LnNldF94bGFiZWwoJ00nKQogICAgYXguc2V0X3lsYWJlbCgnTicpCgogICAgbGVnZW5kX3BhdGNoZXMgPSBbCiAgICAgICAgbXBhdGNoZXMuUGF0Y2goY29sb3I9Y29sb3JzWzBdLCBsYWJlbD0n0JLRltC70YzQvdCwINC00ZbQu9GP0L3QutCwJyksCiAgICAgICAgbXBhdGNoZXMuUGF0Y2goY29sb3I9Y29sb3JzWzFdLCBsYWJlbD0n0JTQtdGA0LXQstC+JyksCiAgICAgICAgbXBhdGNoZXMuUGF0Y2goY29sb3I9Y29sb3JzWzJdLCBsYWJlbD0n0JPQsNGA0LDQticpCiAgICBdCiAgICBheC5sZWdlbmQoaGFuZGxlcz1sZWdlbmRfcGF0Y2hlcywgYmJveF90b19hbmNob3I9KDEuMDIsIDEpLCBsb2M9J3VwcGVyIGxlZnQnLCBib3JkZXJheGVzcGFkPTAuKQoKICAgIHBsdC50aWdodF9sYXlvdXQoKQogICAgcGx0LnNob3coKQoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHNvbHZlX2dhcmFnZXNfc2ltcGxlX3Bsb3QoKQo=